| author | wenzelm | 
| Mon, 20 Jul 2009 00:37:39 +0200 | |
| changeset 32062 | 457f5bcd3d76 | 
| parent 29097 | 68245155eb58 | 
| child 32960 | 69916a850301 | 
| permissions | -rw-r--r-- | 
| 19496 | 1 | theory SN | 
| 25867 | 2 | imports Lam_Funs | 
| 18106 | 3 | begin | 
| 4 | ||
| 18269 | 5 | text {* Strong Normalisation proof from the Proofs and Types book *}
 | 
| 18106 | 6 | |
| 7 | section {* Beta Reduction *}
 | |
| 8 | ||
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 9 | lemma subst_rename: | 
| 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 10 | assumes a: "c\<sharp>t1" | 
| 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 11 | shows "t1[a::=t2] = ([(c,a)]\<bullet>t1)[c::=t2]" | 
| 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 12 | using a | 
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 13 | by (nominal_induct t1 avoiding: a c t2 rule: lam.strong_induct) | 
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 14 | (auto simp add: calc_atm fresh_atm abs_fresh) | 
| 18106 | 15 | |
| 18313 | 16 | lemma forget: | 
| 17 | assumes a: "a\<sharp>t1" | |
| 18 | shows "t1[a::=t2] = t1" | |
| 19 | using a | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 20 | by (nominal_induct t1 avoiding: a t2 rule: lam.strong_induct) | 
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 21 | (auto simp add: abs_fresh fresh_atm) | 
| 18106 | 22 | |
| 18313 | 23 | lemma fresh_fact: | 
| 24 | fixes a::"name" | |
| 23970 | 25 | assumes a: "a\<sharp>t1" "a\<sharp>t2" | 
| 22540 | 26 | shows "a\<sharp>t1[b::=t2]" | 
| 23970 | 27 | using a | 
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 28 | by (nominal_induct t1 avoiding: a b t2 rule: lam.strong_induct) | 
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 29 | (auto simp add: abs_fresh fresh_atm) | 
| 18106 | 30 | |
| 22540 | 31 | lemma fresh_fact': | 
| 32 | fixes a::"name" | |
| 33 | assumes a: "a\<sharp>t2" | |
| 34 | shows "a\<sharp>t1[a::=t2]" | |
| 35 | using a | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 36 | by (nominal_induct t1 avoiding: a t2 rule: lam.strong_induct) | 
| 22540 | 37 | (auto simp add: abs_fresh fresh_atm) | 
| 38 | ||
| 18383 | 39 | lemma subst_lemma: | 
| 18313 | 40 | assumes a: "x\<noteq>y" | 
| 41 | and b: "x\<sharp>L" | |
| 42 | shows "M[x::=N][y::=L] = M[y::=L][x::=N[y::=L]]" | |
| 43 | using a b | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 44 | by (nominal_induct M avoiding: x y N L rule: lam.strong_induct) | 
| 18313 | 45 | (auto simp add: fresh_fact forget) | 
| 18106 | 46 | |
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 47 | lemma id_subs: | 
| 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 48 | shows "t[x::=Var x] = t" | 
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 49 | by (nominal_induct t avoiding: x rule: lam.strong_induct) | 
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 50 | (simp_all add: fresh_atm) | 
| 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 51 | |
| 26772 | 52 | lemma lookup_fresh: | 
| 53 | fixes z::"name" | |
| 54 | assumes "z\<sharp>\<theta>" "z\<sharp>x" | |
| 55 | shows "z\<sharp> lookup \<theta> x" | |
| 56 | using assms | |
| 57 | by (induct rule: lookup.induct) (auto simp add: fresh_list_cons) | |
| 58 | ||
| 59 | lemma lookup_fresh': | |
| 60 | assumes "z\<sharp>\<theta>" | |
| 61 | shows "lookup \<theta> z = Var z" | |
| 62 | using assms | |
| 63 | by (induct rule: lookup.induct) | |
| 64 | (auto simp add: fresh_list_cons fresh_prod fresh_atm) | |
| 65 | ||
| 23142 | 66 | lemma psubst_subst: | 
| 67 | assumes h:"c\<sharp>\<theta>" | |
| 68 | shows "(\<theta><t>)[c::=s] = ((c,s)#\<theta>)<t>" | |
| 69 | using h | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 70 | by (nominal_induct t avoiding: \<theta> c s rule: lam.strong_induct) | 
| 23142 | 71 | (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh') | 
| 72 | ||
| 23760 | 73 | inductive | 
| 23142 | 74 |   Beta :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<longrightarrow>\<^isub>\<beta> _" [80,80] 80)
 | 
| 22271 | 75 | where | 
| 23970 | 76 | b1[intro!]: "s1 \<longrightarrow>\<^isub>\<beta> s2 \<Longrightarrow> App s1 t \<longrightarrow>\<^isub>\<beta> App s2 t" | 
| 77 | | b2[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> App t s1 \<longrightarrow>\<^isub>\<beta> App t s2" | |
| 78 | | b3[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> Lam [a].s1 \<longrightarrow>\<^isub>\<beta> Lam [a].s2" | |
| 79 | | b4[intro!]: "a\<sharp>s2 \<Longrightarrow> App (Lam [a].s1) s2\<longrightarrow>\<^isub>\<beta> (s1[a::=s2])" | |
| 22538 
3ccb92dfb5e9
tuned proofs (taking full advantage of nominal_inductive)
 urbanc parents: 
22531diff
changeset | 80 | |
| 22730 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 81 | equivariance Beta | 
| 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 82 | |
| 22538 
3ccb92dfb5e9
tuned proofs (taking full advantage of nominal_inductive)
 urbanc parents: 
22531diff
changeset | 83 | nominal_inductive Beta | 
| 22540 | 84 | by (simp_all add: abs_fresh fresh_fact') | 
| 18106 | 85 | |
| 25831 | 86 | lemma beta_preserves_fresh: | 
| 87 | fixes a::"name" | |
| 18378 | 88 | assumes a: "t\<longrightarrow>\<^isub>\<beta> s" | 
| 25831 | 89 | shows "a\<sharp>t \<Longrightarrow> a\<sharp>s" | 
| 18378 | 90 | using a | 
| 25831 | 91 | apply(nominal_induct t s avoiding: a rule: Beta.strong_induct) | 
| 92 | apply(auto simp add: abs_fresh fresh_fact fresh_atm) | |
| 93 | done | |
| 18378 | 94 | |
| 23970 | 95 | lemma beta_abs: | 
| 25831 | 96 | assumes a: "Lam [a].t\<longrightarrow>\<^isub>\<beta> t'" | 
| 23970 | 97 | shows "\<exists>t''. t'=Lam [a].t'' \<and> t\<longrightarrow>\<^isub>\<beta> t''" | 
| 25831 | 98 | proof - | 
| 99 | have "a\<sharp>Lam [a].t" by (simp add: abs_fresh) | |
| 100 | with a have "a\<sharp>t'" by (simp add: beta_preserves_fresh) | |
| 101 | with a show ?thesis | |
| 102 | by (cases rule: Beta.strong_cases[where a="a" and aa="a"]) | |
| 103 | (auto simp add: lam.inject abs_fresh alpha) | |
| 104 | qed | |
| 18106 | 105 | |
| 18313 | 106 | lemma beta_subst: | 
| 18106 | 107 | assumes a: "M \<longrightarrow>\<^isub>\<beta> M'" | 
| 108 | shows "M[x::=N]\<longrightarrow>\<^isub>\<beta> M'[x::=N]" | |
| 109 | using a | |
| 23142 | 110 | by (nominal_induct M M' avoiding: x N rule: Beta.strong_induct) | 
| 111 | (auto simp add: fresh_atm subst_lemma fresh_fact) | |
| 18106 | 112 | |
| 18383 | 113 | section {* types *}
 | 
| 114 | ||
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 115 | nominal_datatype ty = | 
| 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 116 | TVar "nat" | 
| 18106 | 117 | | TArr "ty" "ty" (infix "\<rightarrow>" 200) | 
| 118 | ||
| 119 | lemma fresh_ty: | |
| 120 | fixes a ::"name" | |
| 121 | and \<tau> ::"ty" | |
| 122 | shows "a\<sharp>\<tau>" | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 123 | by (nominal_induct \<tau> rule: ty.strong_induct) | 
| 25867 | 124 | (auto simp add: fresh_nat) | 
| 18106 | 125 | |
| 126 | (* valid contexts *) | |
| 127 | ||
| 23760 | 128 | inductive | 
| 23142 | 129 | valid :: "(name\<times>ty) list \<Rightarrow> bool" | 
| 22271 | 130 | where | 
| 131 | v1[intro]: "valid []" | |
| 132 | | v2[intro]: "\<lbrakk>valid \<Gamma>;a\<sharp>\<Gamma>\<rbrakk>\<Longrightarrow> valid ((a,\<sigma>)#\<Gamma>)" | |
| 18106 | 133 | |
| 22538 
3ccb92dfb5e9
tuned proofs (taking full advantage of nominal_inductive)
 urbanc parents: 
22531diff
changeset | 134 | equivariance valid | 
| 18106 | 135 | |
| 136 | (* typing judgements *) | |
| 137 | ||
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 138 | lemma fresh_context: | 
| 18106 | 139 | fixes \<Gamma> :: "(name\<times>ty)list" | 
| 140 | and a :: "name" | |
| 18378 | 141 | assumes a: "a\<sharp>\<Gamma>" | 
| 142 | shows "\<not>(\<exists>\<tau>::ty. (a,\<tau>)\<in>set \<Gamma>)" | |
| 143 | using a | |
| 23970 | 144 | by (induct \<Gamma>) | 
| 145 | (auto simp add: fresh_prod fresh_list_cons fresh_atm) | |
| 18106 | 146 | |
| 23760 | 147 | inductive | 
| 23142 | 148 |   typing :: "(name\<times>ty) list\<Rightarrow>lam\<Rightarrow>ty\<Rightarrow>bool" ("_ \<turnstile> _ : _" [60,60,60] 60)
 | 
| 22271 | 149 | where | 
| 22650 
0c5b22076fb3
tuned the proof of lemma pt_list_set_fresh (as suggested by Randy Pollack) and tuned the syntax for sub_contexts
 urbanc parents: 
22542diff
changeset | 150 | t1[intro]: "\<lbrakk>valid \<Gamma>; (a,\<tau>)\<in>set \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Var a : \<tau>" | 
| 
0c5b22076fb3
tuned the proof of lemma pt_list_set_fresh (as suggested by Randy Pollack) and tuned the syntax for sub_contexts
 urbanc parents: 
22542diff
changeset | 151 | | t2[intro]: "\<lbrakk>\<Gamma> \<turnstile> t1 : \<tau>\<rightarrow>\<sigma>; \<Gamma> \<turnstile> t2 : \<tau>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : \<sigma>" | 
| 22271 | 152 | | t3[intro]: "\<lbrakk>a\<sharp>\<Gamma>;((a,\<tau>)#\<Gamma>) \<turnstile> t : \<sigma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Lam [a].t : \<tau>\<rightarrow>\<sigma>" | 
| 18106 | 153 | |
| 22730 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 154 | equivariance typing | 
| 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 155 | |
| 22538 
3ccb92dfb5e9
tuned proofs (taking full advantage of nominal_inductive)
 urbanc parents: 
22531diff
changeset | 156 | nominal_inductive typing | 
| 
3ccb92dfb5e9
tuned proofs (taking full advantage of nominal_inductive)
 urbanc parents: 
22531diff
changeset | 157 | by (simp_all add: abs_fresh fresh_ty) | 
| 18106 | 158 | |
| 25867 | 159 | subsection {* a fact about beta *}
 | 
| 18106 | 160 | |
| 161 | constdefs | |
| 162 | "NORMAL" :: "lam \<Rightarrow> bool" | |
| 163 | "NORMAL t \<equiv> \<not>(\<exists>t'. t\<longrightarrow>\<^isub>\<beta> t')" | |
| 164 | ||
| 18383 | 165 | lemma NORMAL_Var: | 
| 166 | shows "NORMAL (Var a)" | |
| 167 | proof - | |
| 168 |   { assume "\<exists>t'. (Var a) \<longrightarrow>\<^isub>\<beta> t'"
 | |
| 169 | then obtain t' where "(Var a) \<longrightarrow>\<^isub>\<beta> t'" by blast | |
| 25867 | 170 | hence False by (cases) (auto) | 
| 18383 | 171 | } | 
| 25867 | 172 | thus "NORMAL (Var a)" by (auto simp add: NORMAL_def) | 
| 18383 | 173 | qed | 
| 174 | ||
| 25867 | 175 | text {* Inductive version of Strong Normalisation *}
 | 
| 23970 | 176 | inductive | 
| 177 | SN :: "lam \<Rightarrow> bool" | |
| 178 | where | |
| 179 | SN_intro: "(\<And>t'. t \<longrightarrow>\<^isub>\<beta> t' \<Longrightarrow> SN t') \<Longrightarrow> SN t" | |
| 180 | ||
| 181 | lemma SN_preserved: | |
| 182 | assumes a: "SN t1" "t1\<longrightarrow>\<^isub>\<beta> t2" | |
| 183 | shows "SN t2" | |
| 184 | using a | |
| 185 | by (cases) (auto) | |
| 18106 | 186 | |
| 23970 | 187 | lemma double_SN_aux: | 
| 188 | assumes a: "SN a" | |
| 189 | and b: "SN b" | |
| 190 | and hyp: "\<And>x z. | |
| 24899 | 191 | \<lbrakk>\<And>y. x \<longrightarrow>\<^isub>\<beta> y \<Longrightarrow> SN y; \<And>y. x \<longrightarrow>\<^isub>\<beta> y \<Longrightarrow> P y z; | 
| 192 | \<And>u. z \<longrightarrow>\<^isub>\<beta> u \<Longrightarrow> SN u; \<And>u. z \<longrightarrow>\<^isub>\<beta> u \<Longrightarrow> P x u\<rbrakk> \<Longrightarrow> P x z" | |
| 23970 | 193 | shows "P a b" | 
| 194 | proof - | |
| 195 | from a | |
| 196 | have r: "\<And>b. SN b \<Longrightarrow> P a b" | |
| 197 | proof (induct a rule: SN.SN.induct) | |
| 198 | case (SN_intro x) | |
| 199 | note SNI' = SN_intro | |
| 200 | have "SN b" by fact | |
| 201 | thus ?case | |
| 202 | proof (induct b rule: SN.SN.induct) | |
| 203 | case (SN_intro y) | |
| 204 | show ?case | |
| 205 | apply (rule hyp) | |
| 206 | apply (erule SNI') | |
| 207 | apply (erule SNI') | |
| 208 | apply (rule SN.SN_intro) | |
| 209 | apply (erule SN_intro)+ | |
| 210 | done | |
| 211 | qed | |
| 212 | qed | |
| 213 | from b show ?thesis by (rule r) | |
| 214 | qed | |
| 18106 | 215 | |
| 23970 | 216 | lemma double_SN[consumes 2]: | 
| 217 | assumes a: "SN a" | |
| 218 | and b: "SN b" | |
| 219 | and c: "\<And>x z. \<lbrakk>\<And>y. x \<longrightarrow>\<^isub>\<beta> y \<Longrightarrow> P y z; \<And>u. z \<longrightarrow>\<^isub>\<beta> u \<Longrightarrow> P x u\<rbrakk> \<Longrightarrow> P x z" | |
| 220 | shows "P a b" | |
| 221 | using a b c | |
| 222 | apply(rule_tac double_SN_aux) | |
| 223 | apply(assumption)+ | |
| 224 | apply(blast) | |
| 18106 | 225 | done | 
| 226 | ||
| 227 | section {* Candidates *}
 | |
| 228 | ||
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
27272diff
changeset | 229 | nominal_primrec | 
| 18106 | 230 | RED :: "ty \<Rightarrow> lam set" | 
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
27272diff
changeset | 231 | where | 
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 232 |   "RED (TVar X) = {t. SN(t)}"
 | 
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
27272diff
changeset | 233 | | "RED (\<tau>\<rightarrow>\<sigma>) =   {t. \<forall>u. (u\<in>RED \<tau> \<longrightarrow> (App t u)\<in>RED \<sigma>)}"
 | 
| 23970 | 234 | by (rule TrueI)+ | 
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 235 | |
| 25867 | 236 | text {* neutral terms *}
 | 
| 18106 | 237 | constdefs | 
| 238 | NEUT :: "lam \<Rightarrow> bool" | |
| 23970 | 239 | "NEUT t \<equiv> (\<exists>a. t = Var a) \<or> (\<exists>t1 t2. t = App t1 t2)" | 
| 18106 | 240 | |
| 241 | (* a slight hack to get the first element of applications *) | |
| 23970 | 242 | (* this is needed to get (SN t) from SN (App t s) *) | 
| 23760 | 243 | inductive | 
| 23142 | 244 |   FST :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<guillemotright> _" [80,80] 80)
 | 
| 22271 | 245 | where | 
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 246 | fst[intro!]: "(App t s) \<guillemotright> t" | 
| 18106 | 247 | |
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
27272diff
changeset | 248 | nominal_primrec | 
| 24899 | 249 | fst_app_aux::"lam\<Rightarrow>lam option" | 
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
27272diff
changeset | 250 | where | 
| 24899 | 251 | "fst_app_aux (Var a) = None" | 
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
27272diff
changeset | 252 | | "fst_app_aux (App t1 t2) = Some t1" | 
| 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
27272diff
changeset | 253 | | "fst_app_aux (Lam [x].t) = None" | 
| 24899 | 254 | apply(finite_guess)+ | 
| 255 | apply(rule TrueI)+ | |
| 256 | apply(simp add: fresh_none) | |
| 257 | apply(fresh_guess)+ | |
| 258 | done | |
| 259 | ||
| 260 | definition | |
| 261 | fst_app_def[simp]: "fst_app t = the (fst_app_aux t)" | |
| 262 | ||
| 23970 | 263 | lemma SN_of_FST_of_App: | 
| 264 | assumes a: "SN (App t s)" | |
| 24899 | 265 | shows "SN (fst_app (App t s))" | 
| 23970 | 266 | using a | 
| 267 | proof - | |
| 268 | from a have "\<forall>z. (App t s \<guillemotright> z) \<longrightarrow> SN z" | |
| 269 | by (induct rule: SN.SN.induct) | |
| 270 | (blast elim: FST.cases intro: SN_intro) | |
| 24899 | 271 | then have "SN t" by blast | 
| 272 | then show "SN (fst_app (App t s))" by simp | |
| 23970 | 273 | qed | 
| 18106 | 274 | |
| 18383 | 275 | section {* Candidates *}
 | 
| 276 | ||
| 18106 | 277 | constdefs | 
| 18383 | 278 | "CR1" :: "ty \<Rightarrow> bool" | 
| 23970 | 279 | "CR1 \<tau> \<equiv> \<forall>t. (t\<in>RED \<tau> \<longrightarrow> SN t)" | 
| 18106 | 280 | |
| 18383 | 281 | "CR2" :: "ty \<Rightarrow> bool" | 
| 282 | "CR2 \<tau> \<equiv> \<forall>t t'. (t\<in>RED \<tau> \<and> t \<longrightarrow>\<^isub>\<beta> t') \<longrightarrow> t'\<in>RED \<tau>" | |
| 18106 | 283 | |
| 18383 | 284 | "CR3_RED" :: "lam \<Rightarrow> ty \<Rightarrow> bool" | 
| 285 | "CR3_RED t \<tau> \<equiv> \<forall>t'. t\<longrightarrow>\<^isub>\<beta> t' \<longrightarrow> t'\<in>RED \<tau>" | |
| 18106 | 286 | |
| 18383 | 287 | "CR3" :: "ty \<Rightarrow> bool" | 
| 288 | "CR3 \<tau> \<equiv> \<forall>t. (NEUT t \<and> CR3_RED t \<tau>) \<longrightarrow> t\<in>RED \<tau>" | |
| 18106 | 289 | |
| 18383 | 290 | "CR4" :: "ty \<Rightarrow> bool" | 
| 291 | "CR4 \<tau> \<equiv> \<forall>t. (NEUT t \<and> NORMAL t) \<longrightarrow>t\<in>RED \<tau>" | |
| 18106 | 292 | |
| 23970 | 293 | lemma CR3_implies_CR4: | 
| 294 | assumes a: "CR3 \<tau>" | |
| 295 | shows "CR4 \<tau>" | |
| 296 | using a by (auto simp add: CR3_def CR3_RED_def CR4_def NORMAL_def) | |
| 18106 | 297 | |
| 23970 | 298 | (* sub_induction in the arrow-type case for the next proof *) | 
| 299 | lemma sub_induction: | |
| 300 | assumes a: "SN(u)" | |
| 301 | and b: "u\<in>RED \<tau>" | |
| 302 | and c1: "NEUT t" | |
| 303 | and c2: "CR2 \<tau>" | |
| 304 | and c3: "CR3 \<sigma>" | |
| 305 | and c4: "CR3_RED t (\<tau>\<rightarrow>\<sigma>)" | |
| 306 | shows "(App t u)\<in>RED \<sigma>" | |
| 307 | using a b | |
| 308 | proof (induct) | |
| 309 | fix u | |
| 310 | assume as: "u\<in>RED \<tau>" | |
| 311 | assume ih: " \<And>u'. \<lbrakk>u \<longrightarrow>\<^isub>\<beta> u'; u' \<in> RED \<tau>\<rbrakk> \<Longrightarrow> App t u' \<in> RED \<sigma>" | |
| 312 | have "NEUT (App t u)" using c1 by (auto simp add: NEUT_def) | |
| 313 | moreover | |
| 314 | have "CR3_RED (App t u) \<sigma>" unfolding CR3_RED_def | |
| 315 | proof (intro strip) | |
| 316 | fix r | |
| 317 | assume red: "App t u \<longrightarrow>\<^isub>\<beta> r" | |
| 318 | moreover | |
| 319 |     { assume "\<exists>t'. t \<longrightarrow>\<^isub>\<beta> t' \<and> r = App t' u"
 | |
| 320 | then obtain t' where a1: "t \<longrightarrow>\<^isub>\<beta> t'" and a2: "r = App t' u" by blast | |
| 321 | have "t'\<in>RED (\<tau>\<rightarrow>\<sigma>)" using c4 a1 by (simp add: CR3_RED_def) | |
| 322 | then have "App t' u\<in>RED \<sigma>" using as by simp | |
| 323 | then have "r\<in>RED \<sigma>" using a2 by simp | |
| 324 | } | |
| 325 | moreover | |
| 326 |     { assume "\<exists>u'. u \<longrightarrow>\<^isub>\<beta> u' \<and> r = App t u'"
 | |
| 327 | then obtain u' where b1: "u \<longrightarrow>\<^isub>\<beta> u'" and b2: "r = App t u'" by blast | |
| 328 | have "u'\<in>RED \<tau>" using as b1 c2 by (auto simp add: CR2_def) | |
| 329 | with ih have "App t u' \<in> RED \<sigma>" using b1 by simp | |
| 330 | then have "r\<in>RED \<sigma>" using b2 by simp | |
| 331 | } | |
| 332 | moreover | |
| 333 |     { assume "\<exists>x t'. t = Lam [x].t'"
 | |
| 334 | then obtain x t' where "t = Lam [x].t'" by blast | |
| 335 | then have "NEUT (Lam [x].t')" using c1 by simp | |
| 336 | then have "False" by (simp add: NEUT_def) | |
| 337 | then have "r\<in>RED \<sigma>" by simp | |
| 338 | } | |
| 339 | ultimately show "r \<in> RED \<sigma>" by (cases) (auto simp add: lam.inject) | |
| 340 | qed | |
| 341 | ultimately show "App t u \<in> RED \<sigma>" using c3 by (simp add: CR3_def) | |
| 342 | qed | |
| 18106 | 343 | |
| 25867 | 344 | text {* properties of the candiadates *}
 | 
| 18383 | 345 | lemma RED_props: | 
| 346 | shows "CR1 \<tau>" and "CR2 \<tau>" and "CR3 \<tau>" | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 347 | proof (nominal_induct \<tau> rule: ty.strong_induct) | 
| 18611 | 348 | case (TVar a) | 
| 349 |   { case 1 show "CR1 (TVar a)" by (simp add: CR1_def)
 | |
| 350 | next | |
| 23970 | 351 | case 2 show "CR2 (TVar a)" by (auto intro: SN_preserved simp add: CR2_def) | 
| 18611 | 352 | next | 
| 23970 | 353 | case 3 show "CR3 (TVar a)" by (auto intro: SN_intro simp add: CR3_def CR3_RED_def) | 
| 18611 | 354 | } | 
| 18599 
e01112713fdc
changed PRO_RED proof to conform with the new induction rules
 urbanc parents: 
18383diff
changeset | 355 | next | 
| 18611 | 356 | case (TArr \<tau>1 \<tau>2) | 
| 357 |   { case 1
 | |
| 358 | have ih_CR3_\<tau>1: "CR3 \<tau>1" by fact | |
| 359 | have ih_CR1_\<tau>2: "CR1 \<tau>2" by fact | |
| 25867 | 360 | have "\<And>t. t \<in> RED (\<tau>1 \<rightarrow> \<tau>2) \<Longrightarrow> SN t" | 
| 361 | proof - | |
| 18611 | 362 | fix t | 
| 25867 | 363 | assume "t \<in> RED (\<tau>1 \<rightarrow> \<tau>2)" | 
| 364 | then have a: "\<forall>u. u \<in> RED \<tau>1 \<longrightarrow> App t u \<in> RED \<tau>2" by simp | |
| 23970 | 365 | from ih_CR3_\<tau>1 have "CR4 \<tau>1" by (simp add: CR3_implies_CR4) | 
| 18611 | 366 | moreover | 
| 26932 | 367 | fix a have "NEUT (Var a)" by (force simp add: NEUT_def) | 
| 18611 | 368 | moreover | 
| 369 | have "NORMAL (Var a)" by (rule NORMAL_Var) | |
| 370 | ultimately have "(Var a)\<in> RED \<tau>1" by (simp add: CR4_def) | |
| 371 | with a have "App t (Var a) \<in> RED \<tau>2" by simp | |
| 372 | hence "SN (App t (Var a))" using ih_CR1_\<tau>2 by (simp add: CR1_def) | |
| 25867 | 373 | thus "SN t" by (auto dest: SN_of_FST_of_App) | 
| 18611 | 374 | qed | 
| 25867 | 375 | then show "CR1 (\<tau>1 \<rightarrow> \<tau>2)" unfolding CR1_def by simp | 
| 18611 | 376 | next | 
| 377 | case 2 | |
| 378 | have ih_CR2_\<tau>2: "CR2 \<tau>2" by fact | |
| 25867 | 379 | then show "CR2 (\<tau>1 \<rightarrow> \<tau>2)" unfolding CR2_def by auto | 
| 18611 | 380 | next | 
| 381 | case 3 | |
| 382 | have ih_CR1_\<tau>1: "CR1 \<tau>1" by fact | |
| 383 | have ih_CR2_\<tau>1: "CR2 \<tau>1" by fact | |
| 384 | have ih_CR3_\<tau>2: "CR3 \<tau>2" by fact | |
| 23970 | 385 | show "CR3 (\<tau>1 \<rightarrow> \<tau>2)" unfolding CR3_def | 
| 386 | proof (simp, intro strip) | |
| 18611 | 387 | fix t u | 
| 388 | assume a1: "u \<in> RED \<tau>1" | |
| 389 | assume a2: "NEUT t \<and> CR3_RED t (\<tau>1 \<rightarrow> \<tau>2)" | |
| 23970 | 390 | have "SN(u)" using a1 ih_CR1_\<tau>1 by (simp add: CR1_def) | 
| 391 | then show "(App t u)\<in>RED \<tau>2" using ih_CR2_\<tau>1 ih_CR3_\<tau>2 a1 a2 by (blast intro: sub_induction) | |
| 18611 | 392 | qed | 
| 393 | } | |
| 18383 | 394 | qed | 
| 23970 | 395 | |
| 25867 | 396 | text {* 
 | 
| 397 | the next lemma not as simple as on paper, probably because of | |
| 398 | the stronger double_SN induction | |
| 399 | *} | |
| 23970 | 400 | lemma abs_RED: | 
| 401 | assumes asm: "\<forall>s\<in>RED \<tau>. t[x::=s]\<in>RED \<sigma>" | |
| 402 | shows "Lam [x].t\<in>RED (\<tau>\<rightarrow>\<sigma>)" | |
| 18106 | 403 | proof - | 
| 23970 | 404 | have b1: "SN t" | 
| 405 | proof - | |
| 406 | have "Var x\<in>RED \<tau>" | |
| 407 | proof - | |
| 408 | have "CR4 \<tau>" by (simp add: RED_props CR3_implies_CR4) | |
| 409 | moreover | |
| 410 | have "NEUT (Var x)" by (auto simp add: NEUT_def) | |
| 411 | moreover | |
| 412 | have "NORMAL (Var x)" by (auto elim: Beta.cases simp add: NORMAL_def) | |
| 413 | ultimately show "Var x\<in>RED \<tau>" by (simp add: CR4_def) | |
| 414 | qed | |
| 415 | then have "t[x::=Var x]\<in>RED \<sigma>" using asm by simp | |
| 416 | then have "t\<in>RED \<sigma>" by (simp add: id_subs) | |
| 417 | moreover | |
| 418 | have "CR1 \<sigma>" by (simp add: RED_props) | |
| 419 | ultimately show "SN t" by (simp add: CR1_def) | |
| 420 | qed | |
| 421 | show "Lam [x].t\<in>RED (\<tau>\<rightarrow>\<sigma>)" | |
| 422 | proof (simp, intro strip) | |
| 423 | fix u | |
| 424 | assume b2: "u\<in>RED \<tau>" | |
| 425 | then have b3: "SN u" using RED_props by (auto simp add: CR1_def) | |
| 426 | show "App (Lam [x].t) u \<in> RED \<sigma>" using b1 b3 b2 asm | |
| 427 | proof(induct t u rule: double_SN) | |
| 428 | fix t u | |
| 429 | assume ih1: "\<And>t'. \<lbrakk>t \<longrightarrow>\<^isub>\<beta> t'; u\<in>RED \<tau>; \<forall>s\<in>RED \<tau>. t'[x::=s]\<in>RED \<sigma>\<rbrakk> \<Longrightarrow> App (Lam [x].t') u \<in> RED \<sigma>" | |
| 430 | assume ih2: "\<And>u'. \<lbrakk>u \<longrightarrow>\<^isub>\<beta> u'; u'\<in>RED \<tau>; \<forall>s\<in>RED \<tau>. t[x::=s]\<in>RED \<sigma>\<rbrakk> \<Longrightarrow> App (Lam [x].t) u' \<in> RED \<sigma>" | |
| 431 | assume as1: "u \<in> RED \<tau>" | |
| 432 | assume as2: "\<forall>s\<in>RED \<tau>. t[x::=s]\<in>RED \<sigma>" | |
| 433 | have "CR3_RED (App (Lam [x].t) u) \<sigma>" unfolding CR3_RED_def | |
| 434 | proof(intro strip) | |
| 435 | fix r | |
| 436 | assume red: "App (Lam [x].t) u \<longrightarrow>\<^isub>\<beta> r" | |
| 437 | moreover | |
| 438 | 	{ assume "\<exists>t'. t \<longrightarrow>\<^isub>\<beta> t' \<and> r = App (Lam [x].t') u"
 | |
| 439 | then obtain t' where a1: "t \<longrightarrow>\<^isub>\<beta> t'" and a2: "r = App (Lam [x].t') u" by blast | |
| 440 | have "App (Lam [x].t') u\<in>RED \<sigma>" using ih1 a1 as1 as2 | |
| 441 | apply(auto) | |
| 442 | apply(drule_tac x="t'" in meta_spec) | |
| 443 | apply(simp) | |
| 444 | apply(drule meta_mp) | |
| 25867 | 445 | prefer 2 | 
| 446 | apply(auto)[1] | |
| 447 | apply(rule ballI) | |
| 23970 | 448 | apply(drule_tac x="s" in bspec) | 
| 449 | apply(simp) | |
| 25867 | 450 | apply(subgoal_tac "CR2 \<sigma>")(*A*) | 
| 23970 | 451 | apply(unfold CR2_def)[1] | 
| 452 | apply(drule_tac x="t[x::=s]" in spec) | |
| 453 | apply(drule_tac x="t'[x::=s]" in spec) | |
| 454 | apply(simp add: beta_subst) | |
| 25867 | 455 | (*A*) | 
| 23970 | 456 | apply(simp add: RED_props) | 
| 457 | done | |
| 458 | then have "r\<in>RED \<sigma>" using a2 by simp | |
| 459 | } | |
| 460 | moreover | |
| 461 | 	{ assume "\<exists>u'. u \<longrightarrow>\<^isub>\<beta> u' \<and> r = App (Lam [x].t) u'"
 | |
| 462 | then obtain u' where b1: "u \<longrightarrow>\<^isub>\<beta> u'" and b2: "r = App (Lam [x].t) u'" by blast | |
| 463 | have "App (Lam [x].t) u'\<in>RED \<sigma>" using ih2 b1 as1 as2 | |
| 464 | apply(auto) | |
| 465 | apply(drule_tac x="u'" in meta_spec) | |
| 466 | apply(simp) | |
| 467 | apply(drule meta_mp) | |
| 468 | apply(subgoal_tac "CR2 \<tau>") | |
| 469 | apply(unfold CR2_def)[1] | |
| 470 | apply(drule_tac x="u" in spec) | |
| 471 | apply(drule_tac x="u'" in spec) | |
| 472 | apply(simp) | |
| 473 | apply(simp add: RED_props) | |
| 474 | apply(simp) | |
| 475 | done | |
| 476 | then have "r\<in>RED \<sigma>" using b2 by simp | |
| 477 | } | |
| 478 | moreover | |
| 479 | 	{ assume "r = t[x::=u]"
 | |
| 480 | then have "r\<in>RED \<sigma>" using as1 as2 by auto | |
| 481 | } | |
| 482 | ultimately show "r \<in> RED \<sigma>" | |
| 25867 | 483 | (* one wants to use the strong elimination principle; for this one | 
| 484 | has to know that x\<sharp>u *) | |
| 23970 | 485 | apply(cases) | 
| 486 | apply(auto simp add: lam.inject) | |
| 487 | apply(drule beta_abs) | |
| 25867 | 488 | apply(auto)[1] | 
| 23970 | 489 | apply(auto simp add: alpha subst_rename) | 
| 18106 | 490 | done | 
| 491 | qed | |
| 23970 | 492 | moreover | 
| 493 | have "NEUT (App (Lam [x].t) u)" unfolding NEUT_def by (auto) | |
| 494 | ultimately show "App (Lam [x].t) u \<in> RED \<sigma>" using RED_props by (simp add: CR3_def) | |
| 18106 | 495 | qed | 
| 496 | qed | |
| 23970 | 497 | qed | 
| 18106 | 498 | |
| 22420 | 499 | abbreviation | 
| 500 |  mapsto :: "(name\<times>lam) list \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> bool" ("_ maps _ to _" [55,55,55] 55) 
 | |
| 501 | where | |
| 25867 | 502 | "\<theta> maps x to e \<equiv> (lookup \<theta> x) = e" | 
| 22420 | 503 | |
| 504 | abbreviation | |
| 505 |   closes :: "(name\<times>lam) list \<Rightarrow> (name\<times>ty) list \<Rightarrow> bool" ("_ closes _" [55,55] 55) 
 | |
| 506 | where | |
| 507 | "\<theta> closes \<Gamma> \<equiv> \<forall>x T. ((x,T) \<in> set \<Gamma> \<longrightarrow> (\<exists>t. \<theta> maps x to t \<and> t \<in> RED T))" | |
| 21107 
e69c0e82955a
new file for defining functions in the lambda-calculus
 urbanc parents: 
19972diff
changeset | 508 | |
| 18106 | 509 | lemma all_RED: | 
| 22420 | 510 | assumes a: "\<Gamma> \<turnstile> t : \<tau>" | 
| 511 | and b: "\<theta> closes \<Gamma>" | |
| 512 | shows "\<theta><t> \<in> RED \<tau>" | |
| 18345 | 513 | using a b | 
| 23142 | 514 | proof(nominal_induct avoiding: \<theta> rule: typing.strong_induct) | 
| 515 | case (t3 a \<Gamma> \<sigma> t \<tau> \<theta>) --"lambda case" | |
| 516 | have ih: "\<And>\<theta>. \<theta> closes ((a,\<sigma>)#\<Gamma>) \<Longrightarrow> \<theta><t> \<in> RED \<tau>" by fact | |
| 517 | have \<theta>_cond: "\<theta> closes \<Gamma>" by fact | |
| 23393 | 518 | have fresh: "a\<sharp>\<Gamma>" "a\<sharp>\<theta>" by fact+ | 
| 24899 | 519 | from ih have "\<forall>s\<in>RED \<sigma>. ((a,s)#\<theta>)<t> \<in> RED \<tau>" using fresh \<theta>_cond fresh_context by simp | 
| 520 | then have "\<forall>s\<in>RED \<sigma>. \<theta><t>[a::=s] \<in> RED \<tau>" using fresh by (simp add: psubst_subst) | |
| 23970 | 521 | then have "Lam [a].(\<theta><t>) \<in> RED (\<sigma> \<rightarrow> \<tau>)" by (simp only: abs_RED) | 
| 23142 | 522 | then show "\<theta><(Lam [a].t)> \<in> RED (\<sigma> \<rightarrow> \<tau>)" using fresh by simp | 
| 523 | qed auto | |
| 18345 | 524 | |
| 23142 | 525 | section {* identity substitution generated from a context \<Gamma> *}
 | 
| 526 | fun | |
| 18382 | 527 | "id" :: "(name\<times>ty) list \<Rightarrow> (name\<times>lam) list" | 
| 23142 | 528 | where | 
| 18382 | 529 | "id [] = []" | 
| 23142 | 530 | | "id ((x,\<tau>)#\<Gamma>) = (x,Var x)#(id \<Gamma>)" | 
| 18382 | 531 | |
| 23142 | 532 | lemma id_maps: | 
| 533 | shows "(id \<Gamma>) maps a to (Var a)" | |
| 534 | by (induct \<Gamma>) (auto) | |
| 18382 | 535 | |
| 536 | lemma id_fresh: | |
| 537 | fixes a::"name" | |
| 538 | assumes a: "a\<sharp>\<Gamma>" | |
| 539 | shows "a\<sharp>(id \<Gamma>)" | |
| 540 | using a | |
| 23142 | 541 | by (induct \<Gamma>) | 
| 542 | (auto simp add: fresh_list_nil fresh_list_cons) | |
| 18382 | 543 | |
| 544 | lemma id_apply: | |
| 22420 | 545 | shows "(id \<Gamma>)<t> = t" | 
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26932diff
changeset | 546 | by (nominal_induct t avoiding: \<Gamma> rule: lam.strong_induct) | 
| 23970 | 547 | (auto simp add: id_maps id_fresh) | 
| 18382 | 548 | |
| 23142 | 549 | lemma id_closes: | 
| 22420 | 550 | shows "(id \<Gamma>) closes \<Gamma>" | 
| 18383 | 551 | apply(auto) | 
| 23142 | 552 | apply(simp add: id_maps) | 
| 22420 | 553 | apply(subgoal_tac "CR3 T") --"A" | 
| 23970 | 554 | apply(drule CR3_implies_CR4) | 
| 18382 | 555 | apply(simp add: CR4_def) | 
| 22420 | 556 | apply(drule_tac x="Var x" in spec) | 
| 18383 | 557 | apply(force simp add: NEUT_def NORMAL_Var) | 
| 22418 
49e2d9744ae1
major update of the nominal package; there is now an infrastructure
 urbanc parents: 
22271diff
changeset | 558 | --"A" | 
| 18383 | 559 | apply(rule RED_props) | 
| 18382 | 560 | done | 
| 561 | ||
| 18383 | 562 | lemma typing_implies_RED: | 
| 23142 | 563 | assumes a: "\<Gamma> \<turnstile> t : \<tau>" | 
| 18383 | 564 | shows "t \<in> RED \<tau>" | 
| 565 | proof - | |
| 22420 | 566 | have "(id \<Gamma>)<t>\<in>RED \<tau>" | 
| 18383 | 567 | proof - | 
| 23142 | 568 | have "(id \<Gamma>) closes \<Gamma>" by (rule id_closes) | 
| 18383 | 569 | with a show ?thesis by (rule all_RED) | 
| 570 | qed | |
| 571 | thus"t \<in> RED \<tau>" by (simp add: id_apply) | |
| 572 | qed | |
| 573 | ||
| 574 | lemma typing_implies_SN: | |
| 23142 | 575 | assumes a: "\<Gamma> \<turnstile> t : \<tau>" | 
| 18383 | 576 | shows "SN(t)" | 
| 577 | proof - | |
| 578 | from a have "t \<in> RED \<tau>" by (rule typing_implies_RED) | |
| 579 | moreover | |
| 580 | have "CR1 \<tau>" by (rule RED_props) | |
| 581 | ultimately show "SN(t)" by (simp add: CR1_def) | |
| 582 | qed | |
| 18382 | 583 | |
| 584 | end |