6 |
6 |
7 text {* Strong Normalisation proof from the Proofs and Types book *} |
7 text {* Strong Normalisation proof from the Proofs and Types book *} |
8 |
8 |
9 section {* Beta Reduction *} |
9 section {* Beta Reduction *} |
10 |
10 |
11 lemma subst_rename[rule_format]: |
11 lemma subst_rename: |
12 shows "c\<sharp>t1 \<longrightarrow> (t1[a::=t2] = ([(c,a)]\<bullet>t1)[c::=t2])" |
12 assumes a: "c\<sharp>t1" |
13 apply(nominal_induct t1 avoiding: a c t2 rule: lam.induct) |
13 shows "t1[a::=t2] = ([(c,a)]\<bullet>t1)[c::=t2]" |
14 apply(auto simp add: calc_atm fresh_atm abs_fresh) |
14 using a |
15 done |
15 by (nominal_induct t1 avoiding: a c t2 rule: lam.induct) |
|
16 (auto simp add: calc_atm fresh_atm abs_fresh) |
16 |
17 |
17 lemma forget: |
18 lemma forget: |
18 assumes a: "a\<sharp>t1" |
19 assumes a: "a\<sharp>t1" |
19 shows "t1[a::=t2] = t1" |
20 shows "t1[a::=t2] = t1" |
20 using a |
21 using a |
21 apply (nominal_induct t1 avoiding: a t2 rule: lam.induct) |
22 by (nominal_induct t1 avoiding: a t2 rule: lam.induct) |
22 apply(auto simp add: abs_fresh fresh_atm) |
23 (auto simp add: abs_fresh fresh_atm) |
23 done |
|
24 |
24 |
25 lemma fresh_fact: |
25 lemma fresh_fact: |
26 fixes a::"name" |
26 fixes a::"name" |
27 assumes a: "a\<sharp>t1" |
27 assumes a: "a\<sharp>t1" |
28 and b: "a\<sharp>t2" |
28 and b: "a\<sharp>t2" |
29 shows "a\<sharp>(t1[b::=t2])" |
29 shows "a\<sharp>(t1[b::=t2])" |
30 using a b |
30 using a b |
31 apply(nominal_induct t1 avoiding: a b t2 rule: lam.induct) |
31 by (nominal_induct t1 avoiding: a b t2 rule: lam.induct) |
32 apply(auto simp add: abs_fresh fresh_atm) |
32 (auto simp add: abs_fresh fresh_atm) |
33 done |
|
34 |
33 |
35 lemma subst_lemma: |
34 lemma subst_lemma: |
36 assumes a: "x\<noteq>y" |
35 assumes a: "x\<noteq>y" |
37 and b: "x\<sharp>L" |
36 and b: "x\<sharp>L" |
38 shows "M[x::=N][y::=L] = M[y::=L][x::=N[y::=L]]" |
37 shows "M[x::=N][y::=L] = M[y::=L][x::=N[y::=L]]" |
39 using a b |
38 using a b |
40 by (nominal_induct M avoiding: x y N L rule: lam.induct) |
39 by (nominal_induct M avoiding: x y N L rule: lam.induct) |
41 (auto simp add: fresh_fact forget) |
40 (auto simp add: fresh_fact forget) |
42 |
41 |
43 lemma id_subs: "t[x::=Var x] = t" |
42 lemma id_subs: |
44 apply(nominal_induct t avoiding: x rule: lam.induct) |
43 shows "t[x::=Var x] = t" |
45 apply(simp_all add: fresh_atm) |
44 by (nominal_induct t avoiding: x rule: lam.induct) |
46 done |
45 (simp_all add: fresh_atm) |
|
46 |
|
47 lemma subst_eqvt[eqvt]: |
|
48 fixes pi::"name prm" |
|
49 and t::"lam" |
|
50 shows "pi\<bullet>(t[x::=t']) = (pi\<bullet>t)[(pi\<bullet>x)::=(pi\<bullet>t')]" |
|
51 by (nominal_induct t avoiding: x t' rule: lam.induct) |
|
52 (perm_simp add: fresh_bij)+ |
47 |
53 |
48 inductive2 Beta :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<longrightarrow>\<^isub>\<beta> _" [80,80] 80) |
54 inductive2 Beta :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<longrightarrow>\<^isub>\<beta> _" [80,80] 80) |
49 where |
55 where |
50 b1[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (App s1 t)\<longrightarrow>\<^isub>\<beta>(App s2 t)" |
56 b1[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (App s1 t)\<longrightarrow>\<^isub>\<beta>(App s2 t)" |
51 | b2[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (App t s1)\<longrightarrow>\<^isub>\<beta>(App t s2)" |
57 | b2[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (App t s1)\<longrightarrow>\<^isub>\<beta>(App t s2)" |
52 | b3[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (Lam [a].s1)\<longrightarrow>\<^isub>\<beta> (Lam [(a::name)].s2)" |
58 | b3[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (Lam [a].s1)\<longrightarrow>\<^isub>\<beta> (Lam [(a::name)].s2)" |
53 | b4[intro!]: "(App (Lam [(a::name)].s1) s2)\<longrightarrow>\<^isub>\<beta>(s1[a::=s2])" |
59 | b4[intro!]: "(App (Lam [(a::name)].s1) s2)\<longrightarrow>\<^isub>\<beta>(s1[a::=s2])" |
54 |
60 |
55 abbreviation "Beta_star" :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<longrightarrow>\<^isub>\<beta>\<^sup>* _" [80,80] 80) where |
61 abbreviation "Beta_star" :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<longrightarrow>\<^isub>\<beta>\<^sup>* _" [80,80] 80) where |
56 "t1 \<longrightarrow>\<^isub>\<beta>\<^sup>* t2 \<equiv> Beta\<^sup>*\<^sup>* t1 t2" |
62 "t1 \<longrightarrow>\<^isub>\<beta>\<^sup>* t2 \<equiv> Beta\<^sup>*\<^sup>* t1 t2" |
|
63 |
|
64 nominal_inductive Beta |
57 |
65 |
58 lemma eqvt_beta: |
|
59 fixes pi :: "name prm" |
|
60 and t :: "lam" |
|
61 and s :: "lam" |
|
62 assumes a: "t\<longrightarrow>\<^isub>\<beta>s" |
|
63 shows "(pi\<bullet>t)\<longrightarrow>\<^isub>\<beta>(pi\<bullet>s)" |
|
64 using a by (induct, auto) |
|
65 |
|
66 lemma beta_induct[consumes 1, case_names b1 b2 b3 b4]: |
66 lemma beta_induct[consumes 1, case_names b1 b2 b3 b4]: |
67 fixes P :: "'a::fs_name\<Rightarrow>lam \<Rightarrow> lam \<Rightarrow>bool" |
67 fixes P :: "'a::fs_name\<Rightarrow>lam \<Rightarrow> lam \<Rightarrow>bool" |
68 and t :: "lam" |
68 and t :: "lam" |
69 and s :: "lam" |
69 and s :: "lam" |
70 and x :: "'a::fs_name" |
70 and x :: "'a::fs_name" |
90 by (rule exists_fresh', simp add: fs_name1) |
90 by (rule exists_fresh', simp add: fs_name1) |
91 then obtain c::"name" |
91 then obtain c::"name" |
92 where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>x" and f3: "c\<sharp>(pi\<bullet>s1)" and f4: "c\<sharp>(pi\<bullet>s2)" |
92 where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>x" and f3: "c\<sharp>(pi\<bullet>s1)" and f4: "c\<sharp>(pi\<bullet>s2)" |
93 by (force simp add: fresh_prod fresh_atm) |
93 by (force simp add: fresh_prod fresh_atm) |
94 have x: "P x (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s1)) (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s2))" |
94 have x: "P x (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s1)) (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s2))" |
95 using a3 f2 j1 j2 by (simp, blast intro: eqvt_beta) |
95 using a3 f2 j1 j2 by (simp, blast intro: eqvt) |
96 have alpha1: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s1))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s1))" using f1 f3 |
96 have alpha1: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s1))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s1))" using f1 f3 |
97 by (simp add: lam.inject alpha) |
97 by (simp add: lam.inject alpha) |
98 have alpha2: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s2))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s2))" using f1 f3 |
98 have alpha2: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s2))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s2))" using f1 f3 |
99 by (simp add: lam.inject alpha) |
99 by (simp add: lam.inject alpha) |
100 show " P x (Lam [(pi\<bullet>a)].(pi\<bullet>s1)) (Lam [(pi\<bullet>a)].(pi\<bullet>s2))" |
100 show " P x (Lam [(pi\<bullet>a)].(pi\<bullet>s1)) (Lam [(pi\<bullet>a)].(pi\<bullet>s2))" |
108 by (rule exists_fresh', simp add: fs_name1) |
108 by (rule exists_fresh', simp add: fs_name1) |
109 then obtain c::"name" |
109 then obtain c::"name" |
110 where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>x" and f3: "c\<sharp>(pi\<bullet>s1)" and f4: "c\<sharp>(pi\<bullet>s2)" |
110 where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>x" and f3: "c\<sharp>(pi\<bullet>s1)" and f4: "c\<sharp>(pi\<bullet>s2)" |
111 by (force simp add: fresh_prod fresh_atm) |
111 by (force simp add: fresh_prod fresh_atm) |
112 have x: "P x (App (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s1)) (pi\<bullet>s2)) ((([(c,pi\<bullet>a)]@pi)\<bullet>s1)[c::=(pi\<bullet>s2)])" |
112 have x: "P x (App (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s1)) (pi\<bullet>s2)) ((([(c,pi\<bullet>a)]@pi)\<bullet>s1)[c::=(pi\<bullet>s2)])" |
113 using a4 f2 by (blast intro!: eqvt_beta) |
113 using a4 f2 by (blast intro!: eqvt) |
114 have alpha1: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s1))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s1))" using f1 f3 |
114 have alpha1: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s1))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s1))" using f1 f3 |
115 by (simp add: lam.inject alpha) |
115 by (simp add: lam.inject alpha) |
116 have alpha2: "(([(c,pi\<bullet>a)]@pi)\<bullet>s1)[c::=(pi\<bullet>s2)] = (pi\<bullet>s1)[(pi\<bullet>a)::=(pi\<bullet>s2)]" |
116 have alpha2: "(([(c,pi\<bullet>a)]@pi)\<bullet>s1)[c::=(pi\<bullet>s2)] = (pi\<bullet>s1)[(pi\<bullet>a)::=(pi\<bullet>s2)]" |
117 using f3 by (simp only: subst_rename[symmetric] pt_name2) |
117 using f3 by (simp only: subst_rename[symmetric] pt_name2) |
118 show "P x (App (Lam [(pi\<bullet>a)].(pi\<bullet>s1)) (pi\<bullet>s2)) ((pi\<bullet>s1)[(pi\<bullet>a)::=(pi\<bullet>s2)])" |
118 show "P x (App (Lam [(pi\<bullet>a)].(pi\<bullet>s1)) (pi\<bullet>s2)) ((pi\<bullet>s1)[(pi\<bullet>a)::=(pi\<bullet>s2)])" |
156 apply(auto simp add: fresh_atm subst_lemma) |
156 apply(auto simp add: fresh_atm subst_lemma) |
157 done |
157 done |
158 |
158 |
159 section {* types *} |
159 section {* types *} |
160 |
160 |
161 datatype ty = |
161 nominal_datatype ty = |
162 TVar "string" |
162 TVar "nat" |
163 | TArr "ty" "ty" (infix "\<rightarrow>" 200) |
163 | TArr "ty" "ty" (infix "\<rightarrow>" 200) |
164 |
|
165 primrec (unchecked) |
|
166 "pi\<bullet>(TVar s) = TVar s" |
|
167 "pi\<bullet>(\<tau> \<rightarrow> \<sigma>) = (\<tau> \<rightarrow> \<sigma>)" |
|
168 |
164 |
169 lemma perm_ty[simp]: |
165 lemma perm_ty[simp]: |
170 fixes pi ::"name prm" |
166 fixes pi ::"name prm" |
171 and \<tau> ::"ty" |
167 and \<tau> ::"ty" |
172 shows "pi\<bullet>\<tau> = \<tau>" |
168 shows "pi\<bullet>\<tau> = \<tau>" |
173 by (cases \<tau>, simp_all) |
169 by (nominal_induct \<tau> rule: ty.induct) |
|
170 (simp_all add: perm_nat_def) |
174 |
171 |
175 lemma fresh_ty: |
172 lemma fresh_ty: |
176 fixes a ::"name" |
173 fixes a ::"name" |
177 and \<tau> ::"ty" |
174 and \<tau> ::"ty" |
178 shows "a\<sharp>\<tau>" |
175 shows "a\<sharp>\<tau>" |
179 by (simp add: fresh_def supp_def) |
176 by (simp add: fresh_def supp_def) |
180 |
177 |
181 instance ty :: pt_name |
|
182 apply(intro_classes) |
|
183 apply(simp_all) |
|
184 done |
|
185 |
|
186 instance ty :: fs_name |
|
187 apply(intro_classes) |
|
188 apply(simp add: supp_def) |
|
189 done |
|
190 |
|
191 (* valid contexts *) |
178 (* valid contexts *) |
192 |
179 |
193 consts |
180 consts |
194 "dom_ty" :: "(name\<times>ty) list \<Rightarrow> (name list)" |
181 "dom_ty" :: "(name\<times>ty) list \<Rightarrow> (name list)" |
195 primrec |
182 primrec |
199 inductive2 valid :: "(name\<times>ty) list \<Rightarrow> bool" |
186 inductive2 valid :: "(name\<times>ty) list \<Rightarrow> bool" |
200 where |
187 where |
201 v1[intro]: "valid []" |
188 v1[intro]: "valid []" |
202 | v2[intro]: "\<lbrakk>valid \<Gamma>;a\<sharp>\<Gamma>\<rbrakk>\<Longrightarrow> valid ((a,\<sigma>)#\<Gamma>)" |
189 | v2[intro]: "\<lbrakk>valid \<Gamma>;a\<sharp>\<Gamma>\<rbrakk>\<Longrightarrow> valid ((a,\<sigma>)#\<Gamma>)" |
203 |
190 |
204 lemma valid_eqvt: |
191 nominal_inductive valid |
205 fixes pi:: "name prm" |
|
206 assumes a: "valid \<Gamma>" |
|
207 shows "valid (pi\<bullet>\<Gamma>)" |
|
208 using a |
|
209 apply(induct) |
|
210 apply(auto simp add: fresh_bij) |
|
211 done |
|
212 |
192 |
213 (* typing judgements *) |
193 (* typing judgements *) |
214 |
194 |
215 lemma fresh_context[rule_format]: |
195 lemma fresh_context: |
216 fixes \<Gamma> :: "(name\<times>ty)list" |
196 fixes \<Gamma> :: "(name\<times>ty)list" |
217 and a :: "name" |
197 and a :: "name" |
218 assumes a: "a\<sharp>\<Gamma>" |
198 assumes a: "a\<sharp>\<Gamma>" |
219 shows "\<not>(\<exists>\<tau>::ty. (a,\<tau>)\<in>set \<Gamma>)" |
199 shows "\<not>(\<exists>\<tau>::ty. (a,\<tau>)\<in>set \<Gamma>)" |
220 using a |
200 using a |
221 apply(induct \<Gamma>) |
201 apply(induct \<Gamma>) |
222 apply(auto simp add: fresh_prod fresh_list_cons fresh_atm) |
202 apply(auto simp add: fresh_prod fresh_list_cons fresh_atm) |
223 done |
203 done |
224 |
204 |
225 lemma valid_elim: |
205 inductive_cases2 valid_elim[elim]: "valid ((a,\<tau>)#\<Gamma>)" |
226 fixes \<Gamma> :: "(name\<times>ty)list" |
206 |
227 and pi:: "name prm" |
207 lemma valid_unicity: |
228 and a :: "name" |
|
229 and \<tau> :: "ty" |
|
230 shows "valid ((a,\<tau>)#\<Gamma>) \<Longrightarrow> valid \<Gamma> \<and> a\<sharp>\<Gamma>" |
|
231 apply(ind_cases2 "valid ((a,\<tau>)#\<Gamma>)", simp) |
|
232 done |
|
233 |
|
234 lemma valid_unicity[rule_format]: |
|
235 assumes a: "valid \<Gamma>" |
208 assumes a: "valid \<Gamma>" |
236 and b: "(c,\<sigma>)\<in>set \<Gamma>" |
209 and b: "(c,\<sigma>)\<in>set \<Gamma>" |
237 and c: "(c,\<tau>)\<in>set \<Gamma>" |
210 and c: "(c,\<tau>)\<in>set \<Gamma>" |
238 shows "\<sigma>=\<tau>" |
211 shows "\<sigma>=\<tau>" |
239 using a b c |
212 using a b c |
240 apply(induct \<Gamma>) |
213 by (induct \<Gamma>) (auto dest!: fresh_context) |
241 apply(auto dest!: valid_elim fresh_context) |
|
242 done |
|
243 |
214 |
244 inductive2 typing :: "(name\<times>ty) list\<Rightarrow>lam\<Rightarrow>ty\<Rightarrow>bool" (" _ \<turnstile> _ : _ " [80,80,80] 80) |
215 inductive2 typing :: "(name\<times>ty) list\<Rightarrow>lam\<Rightarrow>ty\<Rightarrow>bool" (" _ \<turnstile> _ : _ " [80,80,80] 80) |
245 where |
216 where |
246 t1[intro]: "\<lbrakk>valid \<Gamma>; (a,\<tau>)\<in>set \<Gamma>\<rbrakk>\<Longrightarrow> \<Gamma> \<turnstile> Var a : \<tau>" |
217 t1[intro]: "\<lbrakk>valid \<Gamma>; (a,\<tau>)\<in>set \<Gamma>\<rbrakk>\<Longrightarrow> \<Gamma> \<turnstile> Var a : \<tau>" |
247 | t2[intro]: "\<lbrakk>\<Gamma> \<turnstile> t1 : \<tau>\<rightarrow>\<sigma>; \<Gamma> \<turnstile> t2 : \<tau>\<rbrakk>\<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : \<sigma>" |
218 | t2[intro]: "\<lbrakk>\<Gamma> \<turnstile> t1 : \<tau>\<rightarrow>\<sigma>; \<Gamma> \<turnstile> t2 : \<tau>\<rbrakk>\<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : \<sigma>" |
259 case (t1 \<Gamma> a \<tau>) |
230 case (t1 \<Gamma> a \<tau>) |
260 have "valid (pi\<bullet>\<Gamma>)" by (rule valid_eqvt) |
231 have "valid (pi\<bullet>\<Gamma>)" by (rule valid_eqvt) |
261 moreover |
232 moreover |
262 have "(pi\<bullet>(a,\<tau>))\<in>((pi::name prm)\<bullet>set \<Gamma>)" by (rule pt_set_bij2[OF pt_name_inst, OF at_name_inst]) |
233 have "(pi\<bullet>(a,\<tau>))\<in>((pi::name prm)\<bullet>set \<Gamma>)" by (rule pt_set_bij2[OF pt_name_inst, OF at_name_inst]) |
263 ultimately show "(pi\<bullet>\<Gamma>) \<turnstile> ((pi::name prm)\<bullet>Var a) : \<tau>" |
234 ultimately show "(pi\<bullet>\<Gamma>) \<turnstile> ((pi::name prm)\<bullet>Var a) : \<tau>" |
264 using typing.t1 by (force simp add: pt_list_set_pi[OF pt_name_inst, symmetric]) |
235 using typing.t1 by (force simp add: set_eqvt[symmetric]) |
265 next |
236 next |
266 case (t3 a \<Gamma> \<tau> t \<sigma>) |
237 case (t3 a \<Gamma> \<tau> t \<sigma>) |
267 moreover have "(pi\<bullet>a)\<sharp>(pi\<bullet>\<Gamma>)" by (simp add: fresh_bij) |
238 moreover have "(pi\<bullet>a)\<sharp>(pi\<bullet>\<Gamma>)" by (simp add: fresh_bij) |
268 ultimately show "(pi\<bullet>\<Gamma>) \<turnstile> (pi\<bullet>Lam [a].t) :\<tau>\<rightarrow>\<sigma>" by force |
239 ultimately show "(pi\<bullet>\<Gamma>) \<turnstile> (pi\<bullet>Lam [a].t) :\<tau>\<rightarrow>\<sigma>" by force |
269 qed (auto) |
240 qed (auto) |
288 case (t1 \<Gamma> a \<tau>) |
259 case (t1 \<Gamma> a \<tau>) |
289 have j1: "valid \<Gamma>" by fact |
260 have j1: "valid \<Gamma>" by fact |
290 have j2: "(a,\<tau>)\<in>set \<Gamma>" by fact |
261 have j2: "(a,\<tau>)\<in>set \<Gamma>" by fact |
291 from j1 have j3: "valid (pi\<bullet>\<Gamma>)" by (rule valid_eqvt) |
262 from j1 have j3: "valid (pi\<bullet>\<Gamma>)" by (rule valid_eqvt) |
292 from j2 have "pi\<bullet>(a,\<tau>)\<in>pi\<bullet>(set \<Gamma>)" by (simp only: pt_set_bij[OF pt_name_inst, OF at_name_inst]) |
263 from j2 have "pi\<bullet>(a,\<tau>)\<in>pi\<bullet>(set \<Gamma>)" by (simp only: pt_set_bij[OF pt_name_inst, OF at_name_inst]) |
293 hence j4: "(pi\<bullet>a,\<tau>)\<in>set (pi\<bullet>\<Gamma>)" by (simp add: pt_list_set_pi[OF pt_name_inst]) |
264 hence j4: "(pi\<bullet>a,\<tau>)\<in>set (pi\<bullet>\<Gamma>)" by (simp add: eqvt) |
294 show "P x (pi\<bullet>\<Gamma>) (pi\<bullet>(Var a)) \<tau>" using a1 j3 j4 by simp |
265 show "P x (pi\<bullet>\<Gamma>) (pi\<bullet>(Var a)) \<tau>" using a1 j3 j4 by simp |
295 next |
266 next |
296 case (t2 \<Gamma> t1 \<tau> \<sigma> t2) |
267 case (t2 \<Gamma> t1 \<tau> \<sigma> t2) |
297 thus ?case using a2 by (simp, blast intro: eqvt_typing) |
268 thus ?case using a2 by (simp, blast intro: eqvt_typing) |
298 next |
269 next |
344 |
315 |
345 lemma in_ctxt: |
316 lemma in_ctxt: |
346 assumes a: "(a,\<tau>)\<in>set \<Gamma>" |
317 assumes a: "(a,\<tau>)\<in>set \<Gamma>" |
347 shows "a\<in>set(dom_ty \<Gamma>)" |
318 shows "a\<in>set(dom_ty \<Gamma>)" |
348 using a |
319 using a |
349 apply(induct \<Gamma>, auto) |
320 by (induct \<Gamma>) (auto) |
350 done |
|
351 |
321 |
352 lemma free_vars: |
322 lemma free_vars: |
353 assumes a: "\<Gamma> \<turnstile> t : \<tau>" |
323 assumes a: "\<Gamma> \<turnstile> t : \<tau>" |
354 shows " (supp t)\<subseteq>set(dom_ty \<Gamma>)" |
324 shows " (supp t)\<subseteq>set(dom_ty \<Gamma>)" |
355 using a |
325 using a |
356 apply(nominal_induct \<Gamma> t \<tau> rule: typing_induct) |
326 by (nominal_induct \<Gamma> t \<tau> rule: typing_induct) |
357 apply(auto simp add: lam.supp abs_supp supp_atm in_ctxt) |
327 (auto simp add: lam.supp abs_supp supp_atm in_ctxt) |
358 done |
|
359 |
328 |
360 lemma t1_elim: "\<Gamma> \<turnstile> Var a : \<tau> \<Longrightarrow> valid \<Gamma> \<and> (a,\<tau>) \<in> set \<Gamma>" |
329 lemma t1_elim: "\<Gamma> \<turnstile> Var a : \<tau> \<Longrightarrow> valid \<Gamma> \<and> (a,\<tau>) \<in> set \<Gamma>" |
361 apply(ind_cases2 "\<Gamma> \<turnstile> Var a : \<tau>") |
330 apply(ind_cases2 "\<Gamma> \<turnstile> Var a : \<tau>") |
362 apply(auto simp add: lam.inject lam.distinct) |
331 apply(auto simp add: lam.inject lam.distinct) |
363 done |
332 done |
432 have c1: "((c,\<sigma>)#\<Gamma>)\<turnstile>Lam [a].s : \<tau>" by fact |
401 have c1: "((c,\<sigma>)#\<Gamma>)\<turnstile>Lam [a].s : \<tau>" by fact |
433 hence "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" using f4 by (auto dest: t3_elim) |
402 hence "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" using f4 by (auto dest: t3_elim) |
434 then obtain \<tau>1 \<tau>2 where c11: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and c12: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" by force |
403 then obtain \<tau>1 \<tau>2 where c11: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and c12: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" by force |
435 from c12 have "valid ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>)" by (rule typing_valid) |
404 from c12 have "valid ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>)" by (rule typing_valid) |
436 hence ca: "valid \<Gamma>" and cb: "a\<sharp>\<Gamma>" and cc: "c\<sharp>\<Gamma>" |
405 hence ca: "valid \<Gamma>" and cb: "a\<sharp>\<Gamma>" and cc: "c\<sharp>\<Gamma>" |
437 by (auto dest: valid_elim simp add: fresh_list_cons) |
406 by (auto simp add: fresh_list_cons) |
438 from c12 have c14: "((c,\<sigma>)#(a,\<tau>1)#\<Gamma>) \<turnstile> s : \<tau>2" |
407 from c12 have c14: "((c,\<sigma>)#(a,\<tau>1)#\<Gamma>) \<turnstile> s : \<tau>2" |
439 proof - |
408 proof - |
440 have c2: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<lless> ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" by force |
409 have c2: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<lless> ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" by force |
441 have c3: "valid ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" |
410 have c3: "valid ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" |
442 by (rule v2, rule v2, auto simp add: fresh_list_cons fresh_prod ca cb cc f2' fresh_ty) |
411 by (rule v2, rule v2, auto simp add: fresh_list_cons fresh_prod ca cb cc f2' fresh_ty) |
484 case (b4 a s1 s2) --"Beta-redex" |
453 case (b4 a s1 s2) --"Beta-redex" |
485 have fr: "a\<sharp>\<Gamma>" by fact |
454 have fr: "a\<sharp>\<Gamma>" by fact |
486 have "\<Gamma> \<turnstile> App (Lam [a].s1) s2 : \<tau>" by fact |
455 have "\<Gamma> \<turnstile> App (Lam [a].s1) s2 : \<tau>" by fact |
487 hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s2 : \<sigma>)" by (simp add: t2_elim) |
456 hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s2 : \<sigma>)" by (simp add: t2_elim) |
488 then obtain \<sigma> where a1: "\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s2 : \<sigma>" by blast |
457 then obtain \<sigma> where a1: "\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s2 : \<sigma>" by blast |
489 from a1 have "((a,\<sigma>)#\<Gamma>) \<turnstile> s1 : \<tau>" using fr by (blast dest!: t3_elim) |
458 from a1 have "((a,\<sigma>)#\<Gamma>) \<turnstile> s1 : \<tau>" using fr by (auto dest!: t3_elim simp add: ty.inject) |
490 with a2 show "\<Gamma> \<turnstile> s1[a::=s2] : \<tau>" by (simp add: ty_subs) |
459 with a2 show "\<Gamma> \<turnstile> s1[a::=s2] : \<tau>" by (simp add: ty_subs) |
491 qed |
460 qed |
492 |
461 |
493 lemma subject_automatic: |
462 lemma subject_automatic: |
494 assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2" |
463 assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2" |
495 and b: "\<Gamma> \<turnstile> t1:\<tau>" |
464 and b: "\<Gamma> \<turnstile> t1:\<tau>" |
496 shows "\<Gamma> \<turnstile> t2:\<tau>" |
465 shows "\<Gamma> \<turnstile> t2:\<tau>" |
497 using a b |
466 using a b |
498 apply(nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct) |
467 apply(nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct) |
499 apply(auto dest!: t2_elim t3_elim intro: ty_subs) |
468 apply(auto dest!: t2_elim t3_elim intro: ty_subs simp add: ty.inject) |
500 done |
469 done |
501 |
470 |
502 subsection {* some facts about beta *} |
471 subsection {* some facts about beta *} |
503 |
472 |
504 constdefs |
473 constdefs |
531 apply(auto) |
500 apply(auto) |
532 done |
501 done |
533 |
502 |
534 section {* Candidates *} |
503 section {* Candidates *} |
535 |
504 |
536 consts |
505 lemma ty_cases: |
|
506 fixes x::ty |
|
507 shows "(\<exists>X. x= TVar X) \<or> (\<exists>T1 T2. x=T1\<rightarrow>T2)" |
|
508 by (induct x rule: ty.induct_weak) (auto) |
|
509 |
|
510 function |
537 RED :: "ty \<Rightarrow> lam set" |
511 RED :: "ty \<Rightarrow> lam set" |
538 primrec |
512 where |
539 "RED (TVar X) = {t. SN(t)}" |
513 "RED (TVar X) = {t. SN(t)}" |
540 "RED (\<tau>\<rightarrow>\<sigma>) = {t. \<forall>u. (u\<in>RED \<tau> \<longrightarrow> (App t u)\<in>RED \<sigma>)}" |
514 | "RED (\<tau>\<rightarrow>\<sigma>) = {t. \<forall>u. (u\<in>RED \<tau> \<longrightarrow> (App t u)\<in>RED \<sigma>)}" |
|
515 apply(auto simp add: ty.inject) |
|
516 apply(subgoal_tac "(\<exists>X. x= TVar X) \<or> (\<exists>T1 T2. x=T1\<rightarrow>T2)") |
|
517 apply(blast) |
|
518 apply(rule ty_cases) |
|
519 done |
|
520 |
|
521 instance ty :: size .. |
|
522 |
|
523 nominal_primrec |
|
524 "size (TVar X) = 1" |
|
525 "size (T\<^isub>1\<rightarrow>T\<^isub>2) = size T\<^isub>1 + size T\<^isub>2" |
|
526 by (rule TrueI)+ |
|
527 |
|
528 lemma ty_size_greater_zero[simp]: |
|
529 fixes T::"ty" |
|
530 shows "size T > 0" |
|
531 by (nominal_induct T rule: ty.induct) (simp_all) |
|
532 |
|
533 termination |
|
534 apply(relation "measure size") |
|
535 apply(auto) |
|
536 done |
541 |
537 |
542 constdefs |
538 constdefs |
543 NEUT :: "lam \<Rightarrow> bool" |
539 NEUT :: "lam \<Rightarrow> bool" |
544 "NEUT t \<equiv> (\<exists>a. t=Var a)\<or>(\<exists>t1 t2. t=App t1 t2)" |
540 "NEUT t \<equiv> (\<exists>a. t=Var a)\<or>(\<exists>t1 t2. t=App t1 t2)" |
545 |
541 |
546 (* a slight hack to get the first element of applications *) |
542 (* a slight hack to get the first element of applications *) |
547 inductive2 FST :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<guillemotright> _" [80,80] 80) |
543 inductive2 FST :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<guillemotright> _" [80,80] 80) |
548 where |
544 where |
549 fst[intro!]: "(App t s) \<guillemotright> t" |
545 fst[intro!]: "(App t s) \<guillemotright> t" |
550 |
546 |
551 lemma fst_elim[elim!]: |
547 lemma fst_elim[elim!]: |
552 shows "(App t s) \<guillemotright> t' \<Longrightarrow> t=t'" |
548 shows "(App t s) \<guillemotright> t' \<Longrightarrow> t=t'" |
553 apply(ind_cases2 "App t s \<guillemotright> t'") |
549 apply(ind_cases2 "App t s \<guillemotright> t'") |
554 apply(simp add: lam.inject) |
550 apply(simp add: lam.inject) |
815 using a b |
814 using a b |
816 apply(induct \<theta>) |
815 apply(induct \<theta>) |
817 apply(auto simp add: fresh_prod fresh_list_cons) |
816 apply(auto simp add: fresh_prod fresh_list_cons) |
818 done |
817 done |
819 |
818 |
820 lemma psubst_subst: |
819 lemma fresh_psubst: |
821 assumes a: "c\<sharp>\<theta>" |
820 fixes z::"name" |
|
821 and t::"lam" |
|
822 assumes "z\<sharp>t" "z\<sharp>\<theta>" |
|
823 shows "z\<sharp>(t[<\<theta>>])" |
|
824 using assms |
|
825 by (nominal_induct t avoiding: z \<theta> t rule: lam.induct) |
|
826 (auto simp add: abs_fresh lookup_fresh) |
|
827 |
|
828 lemma psubst_subst: |
|
829 assumes h:"c\<sharp>\<theta>" |
822 shows "(t[<\<theta>>])[c::=s] = t[<((c,s)#\<theta>)>]" |
830 shows "(t[<\<theta>>])[c::=s] = t[<((c,s)#\<theta>)>]" |
823 using a |
831 using h |
824 apply(nominal_induct t avoiding: \<theta> c s rule: lam.induct) |
832 by (nominal_induct t avoiding: \<theta> c s rule: lam.induct) |
825 apply(auto dest: fresh_domain) |
833 (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh' fresh_psubst) |
826 apply(drule fresh_at) |
834 |
827 apply(assumption) |
|
828 apply(rule forget) |
|
829 apply(assumption) |
|
830 apply(subgoal_tac "name\<sharp>((c,s)#\<theta>)")(*A*) |
|
831 apply(simp) |
|
832 (*A*) |
|
833 apply(simp add: fresh_list_cons fresh_prod) |
|
834 done |
|
835 |
835 |
836 lemma all_RED: |
836 lemma all_RED: |
837 assumes a: "\<Gamma>\<turnstile>t:\<tau>" |
837 assumes a: "\<Gamma>\<turnstile>t:\<tau>" |
838 and b: "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain \<theta>)\<and>\<theta><a>\<in>RED \<sigma>)" |
838 and b: "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain \<theta>)\<and>\<theta><a>\<in>RED \<sigma>)" |
839 shows "t[<\<theta>>]\<in>RED \<tau>" |
839 shows "t[<\<theta>>]\<in>RED \<tau>" |
840 using a b |
840 using a b |
|
841 sorry |
|
842 |
841 proof(nominal_induct t avoiding: \<Gamma> \<tau> \<theta> rule: lam.induct) |
843 proof(nominal_induct t avoiding: \<Gamma> \<tau> \<theta> rule: lam.induct) |
842 case (Lam a t) --"lambda case" |
844 case (Lam a t) --"lambda case" |
843 have ih: "\<And>\<Gamma> \<tau> \<theta>. \<Gamma> \<turnstile> t:\<tau> \<Longrightarrow> |
845 have ih: "\<And>\<Gamma> \<tau> \<theta>. \<Gamma> \<turnstile> t:\<tau> \<Longrightarrow> |
844 (\<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and> \<theta><c>\<in>RED \<sigma>) |
846 (\<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and> \<theta><c>\<in>RED \<sigma>) |
845 \<Longrightarrow> t[<\<theta>>]\<in>RED \<tau>" |
847 \<Longrightarrow> t[<\<theta>>]\<in>RED \<tau>" |
858 lemma all_RED: |
860 lemma all_RED: |
859 assumes a: "\<Gamma>\<turnstile>t:\<tau>" |
861 assumes a: "\<Gamma>\<turnstile>t:\<tau>" |
860 and b: "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain \<theta>)\<and>\<theta><a>\<in>RED \<sigma>)" |
862 and b: "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain \<theta>)\<and>\<theta><a>\<in>RED \<sigma>)" |
861 shows "t[<\<theta>>]\<in>RED \<tau>" |
863 shows "t[<\<theta>>]\<in>RED \<tau>" |
862 using a b |
864 using a b |
|
865 sorry |
|
866 |
863 proof(nominal_induct t avoiding: \<Gamma> \<tau> \<theta> rule: lam.induct) |
867 proof(nominal_induct t avoiding: \<Gamma> \<tau> \<theta> rule: lam.induct) |
864 case (Lam a t) --"lambda case" |
868 case (Lam a t) --"lambda case" |
865 have ih: "\<And>\<Gamma> \<tau> \<theta>. \<lbrakk>\<Gamma> \<turnstile> t:\<tau>; \<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and> \<theta><c>\<in>RED \<sigma>\<rbrakk> |
869 have ih: "\<And>\<Gamma> \<tau> \<theta>. \<lbrakk>\<Gamma> \<turnstile> t:\<tau>; \<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and> \<theta><c>\<in>RED \<sigma>\<rbrakk> |
866 \<Longrightarrow> t[<\<theta>>]\<in>RED \<tau>" |
870 \<Longrightarrow> t[<\<theta>>]\<in>RED \<tau>" |
867 and \<theta>_cond: "\<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and> \<theta><c>\<in>RED \<sigma>" |
871 and \<theta>_cond: "\<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and> \<theta><c>\<in>RED \<sigma>" |
872 from ih have "\<forall>s\<in>RED \<tau>1. t[<\<theta>>][a::=s] \<in> RED \<tau>2" using fresh typing \<theta>_cond |
876 from ih have "\<forall>s\<in>RED \<tau>1. t[<\<theta>>][a::=s] \<in> RED \<tau>2" using fresh typing \<theta>_cond |
873 by (force dest: fresh_context simp add: psubst_subst) |
877 by (force dest: fresh_context simp add: psubst_subst) |
874 hence "(Lam [a].(t[<\<theta>>])) \<in> RED (\<tau>1 \<rightarrow> \<tau>2)" by (simp only: abs_RED) |
878 hence "(Lam [a].(t[<\<theta>>])) \<in> RED (\<tau>1 \<rightarrow> \<tau>2)" by (simp only: abs_RED) |
875 thus "(Lam [a].t)[<\<theta>>] \<in> RED \<tau>" using fresh \<tau>_inst by simp |
879 thus "(Lam [a].t)[<\<theta>>] \<in> RED \<tau>" using fresh \<tau>_inst by simp |
876 qed (force dest!: t1_elim t2_elim)+ |
880 qed (force dest!: t1_elim t2_elim)+ |
|
881 *) |
877 |
882 |
878 (* identity substitution generated from a context \<Gamma> *) |
883 (* identity substitution generated from a context \<Gamma> *) |
|
884 (* |
879 consts |
885 consts |
880 "id" :: "(name\<times>ty) list \<Rightarrow> (name\<times>lam) list" |
886 "id" :: "(name\<times>ty) list \<Rightarrow> (name\<times>lam) list" |
881 primrec |
887 primrec |
882 "id [] = []" |
888 "id [] = []" |
883 "id (x#\<Gamma>) = ((fst x),Var (fst x))#(id \<Gamma>)" |
889 "id (x#\<Gamma>) = ((fst x),Var (fst x))#(id \<Gamma>)" |
918 shows "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain (id \<Gamma>))\<and>(id \<Gamma>)<a>\<in>RED \<sigma>)" |
927 shows "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain (id \<Gamma>))\<and>(id \<Gamma>)<a>\<in>RED \<sigma>)" |
919 apply(auto) |
928 apply(auto) |
920 apply(simp add: id_mem) |
929 apply(simp add: id_mem) |
921 apply(frule id_mem) |
930 apply(frule id_mem) |
922 apply(simp add: id_var) |
931 apply(simp add: id_var) |
923 apply(subgoal_tac "CR3 \<sigma>")(*A*) |
932 apply(subgoal_tac "CR3 \<sigma>") --"A" |
924 apply(drule CR3_CR4) |
933 apply(drule CR3_CR4) |
925 apply(simp add: CR4_def) |
934 apply(simp add: CR4_def) |
926 apply(drule_tac x="Var a" in spec) |
935 apply(drule_tac x="Var a" in spec) |
927 apply(force simp add: NEUT_def NORMAL_Var) |
936 apply(force simp add: NEUT_def NORMAL_Var) |
928 (*A*) |
937 --"A" |
929 apply(rule RED_props) |
938 apply(rule RED_props) |
930 done |
939 done |
931 |
940 |
932 lemma typing_implies_RED: |
941 lemma typing_implies_RED: |
933 assumes a: "\<Gamma>\<turnstile>t:\<tau>" |
942 assumes a: "\<Gamma>\<turnstile>t:\<tau>" |