122 done |
153 done |
123 |
154 |
124 termination (eqvt) |
155 termination (eqvt) |
125 by (lexicographic_order) |
156 by (lexicographic_order) |
126 |
157 |
127 text {* Some Tests about Alpha-Equality *} |
158 |
128 |
159 subsection {* Generalisation of types and type-schemes*} |
129 lemma |
160 |
130 shows "All [{|a, b|}].((Var a) \<rightarrow> (Var b)) = All [{|b, a|}]. ((Var a) \<rightarrow> (Var b))" |
161 fun |
131 apply(simp add: Abs_eq_iff) |
162 subst_dom_pi :: "Subst \<Rightarrow> perm \<Rightarrow> Subst" ("_|_") |
132 apply(rule_tac x="0::perm" in exI) |
163 where |
133 apply(simp add: alphas fresh_star_def ty.supp supp_at_base) |
164 "[]|p = []" |
134 done |
165 | "((X,T)#\<theta>)|p = (p \<bullet> X, T)#(\<theta>|p)" |
135 |
|
136 lemma |
|
137 shows "All [{|a, b|}].((Var a) \<rightarrow> (Var b)) = All [{|a, b|}].((Var b) \<rightarrow> (Var a))" |
|
138 apply(simp add: Abs_eq_iff) |
|
139 apply(rule_tac x="(atom a \<rightleftharpoons> atom b)" in exI) |
|
140 apply(simp add: alphas fresh_star_def supp_at_base ty.supp) |
|
141 done |
|
142 |
|
143 lemma |
|
144 shows "All [{|a, b, c|}].((Var a) \<rightarrow> (Var b)) = All [{|a, b|}].((Var a) \<rightarrow> (Var b))" |
|
145 apply(simp add: Abs_eq_iff) |
|
146 apply(rule_tac x="0::perm" in exI) |
|
147 apply(simp add: alphas fresh_star_def ty.supp supp_at_base) |
|
148 done |
|
149 |
|
150 lemma |
|
151 assumes a: "a \<noteq> b" |
|
152 shows "\<not>(All [{|a, b|}].((Var a) \<rightarrow> (Var b)) = All [{|c|}].((Var c) \<rightarrow> (Var c)))" |
|
153 using a |
|
154 apply(simp add: Abs_eq_iff) |
|
155 apply(clarify) |
|
156 apply(simp add: alphas fresh_star_def ty.supp supp_at_base) |
|
157 apply auto |
|
158 done |
|
159 |
|
160 |
|
161 text {* HERE *} |
|
162 |
|
163 fun |
|
164 compose::"Subst \<Rightarrow> Subst \<Rightarrow> Subst" ("_ \<circ> _" [100,100] 100) |
|
165 where |
|
166 "\<theta>\<^isub>1 \<circ> [] = \<theta>\<^isub>1" |
|
167 | "\<theta>\<^isub>1 \<circ> ((X,T)#\<theta>\<^isub>2) = (X,\<theta>\<^isub>1<T>)#(\<theta>\<^isub>1 \<circ> \<theta>\<^isub>2)" |
|
168 |
|
169 lemma compose_eqvt: |
|
170 fixes \<theta>1 \<theta>2::"Subst" |
|
171 shows "(p \<bullet> (\<theta>1 \<circ> \<theta>2)) = ((p \<bullet> \<theta>1) \<circ> (p \<bullet> \<theta>2))" |
|
172 apply(induct \<theta>2) |
|
173 apply(auto simp add: subst.eqvt) |
|
174 done |
|
175 |
|
176 lemma compose_ty: |
|
177 fixes \<theta>1 :: "Subst" |
|
178 and \<theta>2 :: "Subst" |
|
179 and T :: "ty" |
|
180 shows "\<theta>1<\<theta>2<T>> = (\<theta>1\<circ>\<theta>2)<T>" |
|
181 proof (induct T rule: ty.induct) |
|
182 case (Var X) |
|
183 have "\<theta>1<lookup \<theta>2 X> = lookup (\<theta>1\<circ>\<theta>2) X" |
|
184 by (induct \<theta>2) (auto) |
|
185 then show ?case by simp |
|
186 next |
|
187 case (Fun T1 T2) |
|
188 then show ?case by simp |
|
189 qed |
|
190 |
166 |
191 fun |
167 fun |
192 subst_subst :: "Subst \<Rightarrow> Subst \<Rightarrow> Subst" ("_<_>" [100,60] 120) |
168 subst_subst :: "Subst \<Rightarrow> Subst \<Rightarrow> Subst" ("_<_>" [100,60] 120) |
193 where |
169 where |
194 "\<theta><[]> = []" |
170 "\<theta><[]> = []" |
195 | "\<theta> <((X,T)#\<theta>')> = (X,\<theta><T>)#(\<theta><\<theta>'>)" |
171 | "\<theta> <((X,T)#\<theta>')> = (X,\<theta><T>)#(\<theta><\<theta>'>)" |
196 |
172 |
197 lemma redundant1: |
|
198 fixes \<theta>1::"Subst" |
|
199 and \<theta>2::"Subst" |
|
200 shows "\<theta>1 \<circ> \<theta>2 = (\<theta>1<\<theta>2>)@\<theta>1" |
|
201 by (induct \<theta>2) (auto) |
|
202 |
|
203 fun |
173 fun |
204 dom :: "Subst \<Rightarrow> name fset" |
174 dom :: "Subst \<Rightarrow> name fset" |
205 where |
175 where |
206 "dom [] = {||}" |
176 "dom [] = {||}" |
207 | "dom ((X,T)#\<theta>) = {|X|} |\<union>| dom \<theta>" |
177 | "dom ((X,T)#\<theta>) = {|X|} |\<union>| dom \<theta>" |
208 |
178 |
209 lemma dom_eqvt[eqvt]: |
179 lemma dom_eqvt[eqvt]: |
210 shows "(p \<bullet> dom \<theta>) = dom (p \<bullet> \<theta>)" |
180 shows "p \<bullet> (dom \<theta>) = dom (p \<bullet> \<theta>)" |
211 apply(induct \<theta> rule: dom.induct) |
181 by (induct \<theta>) (auto) |
212 apply(simp_all) |
182 |
213 done |
183 lemma dom_subst: |
214 |
184 fixes \<theta>1 \<theta>2::"Subst" |
215 lemma dom_compose: |
|
216 shows "dom (\<theta>1 \<circ> \<theta>2) = dom \<theta>1 |\<union>| dom \<theta>2" |
|
217 apply(induct rule: dom.induct) |
|
218 apply(simp) |
|
219 apply(simp) |
|
220 by (metis sup_commute union_insert_fset) |
|
221 |
|
222 lemma redundant3: |
|
223 fixes \<theta>1::"Subst" |
|
224 and \<theta>2::"Subst" |
|
225 shows "dom (\<theta>2<\<theta>1>) = (dom \<theta>1)" |
185 shows "dom (\<theta>2<\<theta>1>) = (dom \<theta>1)" |
226 by (induct \<theta>1) (auto) |
186 by (induct \<theta>1) (auto) |
227 |
187 |
228 lemma dom_pi: |
188 lemma dom_pi: |
229 shows "(p \<bullet> (dom \<theta>)) = dom (map (\<lambda>(X, T). (p \<bullet> X, T)) \<theta>)" |
189 shows "dom (\<theta>|p) = dom (p \<bullet> \<theta>)" |
230 apply(induct \<theta>) |
190 by (induct \<theta>) (auto) |
231 apply(auto) |
|
232 done |
|
233 |
191 |
234 lemma dom_fresh_lookup: |
192 lemma dom_fresh_lookup: |
235 fixes \<theta>::"Subst" |
193 fixes \<theta>::"Subst" |
236 assumes "\<forall>X \<in> fset (dom \<theta>). atom X \<sharp> name" |
194 assumes "\<forall>Y \<in> fset (dom \<theta>). atom Y \<sharp> X" |
237 shows "lookup \<theta> name = Var name" |
195 shows "lookup \<theta> X = Var X" |
238 using assms |
196 using assms |
239 apply(induct \<theta>) |
197 by (induct \<theta>) (auto simp add: fresh_at_base) |
240 apply(auto simp add: fresh_at_base) |
|
241 done |
|
242 |
198 |
243 lemma dom_fresh_ty: |
199 lemma dom_fresh_ty: |
244 fixes \<theta>::"Subst" |
200 fixes \<theta>::"Subst" |
245 and T::"ty" |
201 and T::"ty" |
246 assumes "\<forall>X \<in> fset (dom \<theta>). atom X \<sharp> T" |
202 assumes "\<forall>X \<in> fset (dom \<theta>). atom X \<sharp> T" |
247 shows "\<theta><T> = T" |
203 shows "\<theta><T> = T" |
248 using assms |
204 using assms |
249 apply(induct T rule: ty.induct) |
205 by (induct T rule: ty.induct) (auto simp add: ty.fresh dom_fresh_lookup) |
250 apply(auto simp add: ty.fresh dom_fresh_lookup) |
|
251 done |
|
252 |
206 |
253 lemma dom_fresh_subst: |
207 lemma dom_fresh_subst: |
254 fixes \<theta> \<theta>'::"Subst" |
208 fixes \<theta> \<theta>'::"Subst" |
255 assumes "\<forall>X \<in> fset (dom \<theta>). atom X \<sharp> \<theta>'" |
209 assumes "\<forall>X \<in> fset (dom \<theta>). atom X \<sharp> \<theta>'" |
256 shows "\<theta><\<theta>'> = \<theta>'" |
210 shows "\<theta><\<theta>'> = \<theta>'" |
257 using assms |
211 using assms |
258 apply(induct \<theta>') |
212 by (induct \<theta>') (auto simp add: fresh_Pair fresh_Cons dom_fresh_ty) |
259 apply(auto simp add: fresh_Pair fresh_Cons dom_fresh_ty) |
|
260 done |
|
261 |
|
262 |
|
263 abbreviation |
|
264 "sub_list" :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" ("_ \<subseteq> _" [60,60] 60) |
|
265 where |
|
266 "xs\<^isub>1 \<subseteq> xs\<^isub>2 \<equiv> \<forall>x. x \<in> set xs\<^isub>1 \<longrightarrow> x \<in> set xs\<^isub>2" |
|
267 |
213 |
268 |
214 |
269 definition |
215 definition |
270 generalises3 :: "ty \<Rightarrow> tys \<Rightarrow> bool" ("_ \<prec>\<prec>\<prec>\<prec> _") |
216 generalises :: "ty \<Rightarrow> tys \<Rightarrow> bool" ("_ \<prec>\<prec> _") |
271 where |
217 where |
272 " T \<prec>\<prec>\<prec>\<prec> S \<longleftrightarrow> (\<exists>\<theta> Xs T'. S = All [Xs].T'\<and> T = \<theta><T'> \<and> dom \<theta> = Xs)" |
218 "T \<prec>\<prec> S \<longleftrightarrow> (\<exists>\<theta> Xs T'. S = All [Xs].T'\<and> T = \<theta><T'> \<and> dom \<theta> = Xs)" |
273 |
219 |
274 |
220 |
275 lemma lookup_fresh: |
221 lemma lookup_fresh: |
276 fixes X::"name" |
222 fixes X::"name" |
277 assumes a: "atom X \<sharp> \<theta>" |
223 assumes a: "atom X \<sharp> \<theta>" |
278 shows "lookup \<theta> X = Var X" |
224 shows "lookup \<theta> X = Var X" |
279 using a |
225 using a |
280 apply (induct \<theta>) |
226 by (induct \<theta>) (auto simp add: fresh_Cons fresh_Pair fresh_at_base) |
281 apply (auto simp add: fresh_Cons fresh_Pair fresh_at_base) |
|
282 done |
|
283 |
227 |
284 lemma lookup_dom: |
228 lemma lookup_dom: |
285 fixes X::"name" |
229 fixes X::"name" |
286 assumes a: "X |\<notin>| dom \<theta>" |
230 assumes "X |\<notin>| dom \<theta>" |
287 shows "lookup \<theta> X = Var X" |
231 shows "lookup \<theta> X = Var X" |
288 using a |
232 using assms |
289 apply (induct \<theta>) |
233 by (induct \<theta>) (auto) |
290 apply(auto) |
|
291 done |
|
292 |
234 |
293 lemma w1: |
235 lemma w1: |
294 "\<theta><map (\<lambda>(X, y). (p \<bullet> X, y)) \<theta>'> = map (\<lambda>(X, y). (p \<bullet> X, y)) (\<theta><\<theta>'>)" |
236 shows "\<theta><\<theta>'|p> = (\<theta><\<theta>'>)|p" |
295 apply(induct \<theta>') |
237 by (induct \<theta>')(auto) |
296 apply(auto) |
|
297 done |
|
298 |
238 |
299 lemma w2: |
239 lemma w2: |
300 assumes "name |\<in>| dom \<theta>'" |
240 assumes "name |\<in>| dom \<theta>'" |
301 shows "\<theta><lookup \<theta>' name> = lookup (\<theta><\<theta>'>) name" |
241 shows "\<theta><lookup \<theta>' name> = lookup (\<theta><\<theta>'>) name" |
302 using assms |
242 using assms |
303 apply(induct \<theta>') |
243 apply(induct \<theta>') |
304 apply(auto) |
244 apply(auto simp add: notin_empty_fset) |
305 by (metis notin_empty_fset) |
245 done |
306 |
246 |
307 lemma w3: |
247 lemma w3: |
308 assumes "name |\<in>| dom \<theta>" |
248 assumes "name |\<in>| dom \<theta>" |
309 shows "lookup \<theta> name = lookup (map (\<lambda>(X, y). (p \<bullet> X, y)) \<theta>) (p \<bullet> name)" |
249 shows "lookup \<theta> name = lookup (\<theta>|p) (p \<bullet> name)" |
310 using assms |
250 using assms |
311 apply(induct \<theta>) |
251 apply(induct \<theta>) |
312 apply(auto) |
252 apply(auto simp add: notin_empty_fset) |
313 by (metis notin_empty_fset) |
253 done |
314 |
254 |
315 lemma fresh_lookup: |
255 lemma fresh_lookup: |
316 fixes X Y::"name" |
256 fixes X Y::"name" |
317 and \<theta>::"Subst" |
257 and \<theta>::"Subst" |
318 assumes asms: "atom X \<sharp> Y" "atom X \<sharp> \<theta>" |
258 assumes asms: "atom X \<sharp> Y" "atom X \<sharp> \<theta>" |
319 shows "atom X \<sharp> (lookup \<theta> Y)" |
259 shows "atom X \<sharp> (lookup \<theta> Y)" |
320 using assms |
260 using assms |
321 apply (induct \<theta>) |
261 apply (induct \<theta>) |
322 apply (auto simp add: fresh_Cons fresh_Pair fresh_at_base ty.fresh) |
262 apply (auto simp add: fresh_Cons fresh_Pair fresh_at_base ty.fresh) |
323 done |
263 done |
324 |
264 |
325 lemma test: |
265 lemma test: |
326 fixes \<theta> \<theta>'::"Subst" |
266 fixes \<theta> \<theta>'::"Subst" |
327 and T::"ty" |
267 and T::"ty" |
328 assumes "(p \<bullet> atom ` fset (dom \<theta>')) \<sharp>* \<theta>" "supp All [dom \<theta>'].T \<sharp>* p" |
268 assumes "(p \<bullet> atom ` fset (dom \<theta>')) \<sharp>* \<theta>" "supp All [dom \<theta>'].T \<sharp>* p" |
329 shows "\<theta><\<theta>'<T>> = \<theta><map (\<lambda>(X, y). (p \<bullet> X, y)) \<theta>'><\<theta><p \<bullet> T>>" |
269 shows "\<theta><\<theta>'<T>> = \<theta><\<theta>'|p><\<theta><p \<bullet> T>>" |
330 using assms |
270 using assms |
331 apply(induct T rule: ty.induct) |
271 apply(induct T rule: ty.induct) |
332 defer |
272 defer |
333 apply(auto simp add: tys.supp ty.supp fresh_star_def)[1] |
273 apply(auto simp add: tys.supp ty.supp fresh_star_def)[1] |
334 apply(auto simp add: tys.supp ty.supp fresh_star_def supp_at_base)[1] |
274 apply(auto simp add: tys.supp ty.supp fresh_star_def supp_at_base)[1] |