| author | wenzelm | 
| Mon, 13 Dec 2021 22:13:22 +0100 | |
| changeset 74926 | 5cd2e6e17e6f | 
| parent 66453 | cc19f7ca2ed6 | 
| child 80146 | cf11a7f0a5f0 | 
| permissions | -rw-r--r-- | 
| 25867 | 1 | (* *) | 
| 2 | (* Formalisation of some typical SOS-proofs. *) | |
| 3 | (* *) | |
| 4 | (* This work was inspired by challenge suggested by Adam *) | |
| 5 | (* Chlipala on the POPLmark mailing list. *) | |
| 6 | (* *) | |
| 7 | (* We thank Nick Benton for helping us with the *) | |
| 8 | (* termination-proof for evaluation. *) | |
| 9 | (* *) | |
| 10 | (* The formalisation was done by Julien Narboux and *) | |
| 11 | (* Christian Urban. *) | |
| 22447 | 12 | |
| 13 | theory SOS | |
| 66453 
cc19f7ca2ed6
session-qualified theory imports: isabelle imports -U -i -d '~~/src/Benchmarks' -a;
 wenzelm parents: 
63167diff
changeset | 14 | imports "HOL-Nominal.Nominal" | 
| 22447 | 15 | begin | 
| 16 | ||
| 23158 
749b6870b1a1
introduced symmetric variants of the lemmas for alpha-equivalence
 urbanc parents: 
22730diff
changeset | 17 | atom_decl name | 
| 22447 | 18 | |
| 63167 | 19 | text \<open>types and terms\<close> | 
| 22447 | 20 | nominal_datatype ty = | 
| 25832 | 21 | TVar "nat" | 
| 22447 | 22 |   | Arrow "ty" "ty" ("_\<rightarrow>_" [100,100] 100)
 | 
| 23 | ||
| 24 | nominal_datatype trm = | |
| 25 | Var "name" | |
| 26 |   | Lam "\<guillemotleft>name\<guillemotright>trm" ("Lam [_]._" [100,100] 100)
 | |
| 27 | | App "trm" "trm" | |
| 28 | ||
| 25832 | 29 | lemma fresh_ty: | 
| 22447 | 30 | fixes x::"name" | 
| 31 | and T::"ty" | |
| 32 | shows "x\<sharp>T" | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 33 | by (induct T rule: ty.induct) | 
| 25832 | 34 | (auto simp add: fresh_nat) | 
| 22447 | 35 | |
| 63167 | 36 | text \<open>Parallel and single substitution.\<close> | 
| 22447 | 37 | fun | 
| 38 | lookup :: "(name\<times>trm) list \<Rightarrow> name \<Rightarrow> trm" | |
| 39 | where | |
| 40 | "lookup [] x = Var x" | |
| 22502 | 41 | | "lookup ((y,e)#\<theta>) x = (if x=y then e else lookup \<theta> x)" | 
| 22447 | 42 | |
| 25832 | 43 | lemma lookup_eqvt[eqvt]: | 
| 22447 | 44 | fixes pi::"name prm" | 
| 45 | shows "pi\<bullet>(lookup \<theta> X) = lookup (pi\<bullet>\<theta>) (pi\<bullet>X)" | |
| 25832 | 46 | by (induct \<theta>) (auto simp add: eqvts) | 
| 22447 | 47 | |
| 48 | lemma lookup_fresh: | |
| 49 | fixes z::"name" | |
| 25832 | 50 | assumes a: "z\<sharp>\<theta>" and b: "z\<sharp>x" | 
| 22447 | 51 | shows "z \<sharp>lookup \<theta> x" | 
| 25832 | 52 | using a b | 
| 22447 | 53 | by (induct rule: lookup.induct) (auto simp add: fresh_list_cons) | 
| 54 | ||
| 55 | lemma lookup_fresh': | |
| 56 | assumes "z\<sharp>\<theta>" | |
| 57 | shows "lookup \<theta> z = Var z" | |
| 58 | using assms | |
| 59 | by (induct rule: lookup.induct) | |
| 60 | (auto simp add: fresh_list_cons fresh_prod fresh_atm) | |
| 61 | ||
| 25832 | 62 | (* parallel substitution *) | 
| 28568 | 63 | |
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
28568diff
changeset | 64 | nominal_primrec | 
| 22447 | 65 |   psubst :: "(name\<times>trm) list \<Rightarrow> trm \<Rightarrow> trm"  ("_<_>" [95,95] 105)
 | 
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
28568diff
changeset | 66 | where | 
| 22447 | 67 | "\<theta><(Var x)> = (lookup \<theta> x)" | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 68 | | "\<theta><(App e\<^sub>1 e\<^sub>2)> = App (\<theta><e\<^sub>1>) (\<theta><e\<^sub>2>)" | 
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
28568diff
changeset | 69 | | "x\<sharp>\<theta> \<Longrightarrow> \<theta><(Lam [x].e)> = Lam [x].(\<theta><e>)" | 
| 25832 | 70 | apply(finite_guess)+ | 
| 22472 | 71 | apply(rule TrueI)+ | 
| 72 | apply(simp add: abs_fresh)+ | |
| 25832 | 73 | apply(fresh_guess)+ | 
| 22472 | 74 | done | 
| 22447 | 75 | |
| 76 | lemma psubst_eqvt[eqvt]: | |
| 77 | fixes pi::"name prm" | |
| 78 | and t::"trm" | |
| 79 | shows "pi\<bullet>(\<theta><t>) = (pi\<bullet>\<theta>)<(pi\<bullet>t)>" | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 80 | by (nominal_induct t avoiding: \<theta> rule: trm.strong_induct) | 
| 22472 | 81 | (perm_simp add: fresh_bij lookup_eqvt)+ | 
| 22447 | 82 | |
| 83 | lemma fresh_psubst: | |
| 84 | fixes z::"name" | |
| 85 | and t::"trm" | |
| 86 | assumes "z\<sharp>t" and "z\<sharp>\<theta>" | |
| 87 | shows "z\<sharp>(\<theta><t>)" | |
| 88 | using assms | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 89 | by (nominal_induct t avoiding: z \<theta> t rule: trm.strong_induct) | 
| 22447 | 90 | (auto simp add: abs_fresh lookup_fresh) | 
| 91 | ||
| 25832 | 92 | lemma psubst_empty[simp]: | 
| 93 | shows "[]<t> = t" | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 94 | by (nominal_induct t rule: trm.strong_induct) | 
| 25832 | 95 | (auto simp add: fresh_list_nil) | 
| 96 | ||
| 63167 | 97 | text \<open>Single substitution\<close> | 
| 22447 | 98 | abbreviation | 
| 25832 | 99 |   subst :: "trm \<Rightarrow> name \<Rightarrow> trm \<Rightarrow> trm" ("_[_::=_]" [100,100,100] 100)
 | 
| 100 | where | |
| 101 | "t[x::=t'] \<equiv> ([(x,t')])<t>" | |
| 22447 | 102 | |
| 103 | lemma subst[simp]: | |
| 104 | shows "(Var x)[y::=t'] = (if x=y then t' else (Var x))" | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 105 | and "(App t\<^sub>1 t\<^sub>2)[y::=t'] = App (t\<^sub>1[y::=t']) (t\<^sub>2[y::=t'])" | 
| 22447 | 106 | and "x\<sharp>(y,t') \<Longrightarrow> (Lam [x].t)[y::=t'] = Lam [x].(t[y::=t'])" | 
| 22472 | 107 | by (simp_all add: fresh_list_cons fresh_list_nil) | 
| 22447 | 108 | |
| 109 | lemma fresh_subst: | |
| 110 | fixes z::"name" | |
| 28568 | 111 | shows "\<lbrakk>z\<sharp>s; (z=y \<or> z\<sharp>t)\<rbrakk> \<Longrightarrow> z\<sharp>t[y::=s]" | 
| 112 | by (nominal_induct t avoiding: z y s rule: trm.strong_induct) | |
| 113 | (auto simp add: abs_fresh fresh_prod fresh_atm) | |
| 22447 | 114 | |
| 115 | lemma forget: | |
| 25867 | 116 | assumes a: "x\<sharp>e" | 
| 25832 | 117 | shows "e[x::=e'] = e" | 
| 25867 | 118 | using a | 
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 119 | by (nominal_induct e avoiding: x e' rule: trm.strong_induct) | 
| 25867 | 120 | (auto simp add: fresh_atm abs_fresh) | 
| 22447 | 121 | |
| 122 | lemma psubst_subst_psubst: | |
| 25867 | 123 | assumes h: "x\<sharp>\<theta>" | 
| 25832 | 124 | shows "\<theta><e>[x::=e'] = ((x,e')#\<theta>)<e>" | 
| 125 | using h | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 126 | by (nominal_induct e avoiding: \<theta> x e' rule: trm.strong_induct) | 
| 25867 | 127 | (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh') | 
| 22447 | 128 | |
| 63167 | 129 | text \<open>Typing Judgements\<close> | 
| 22447 | 130 | |
| 23760 | 131 | inductive | 
| 25832 | 132 | valid :: "(name\<times>ty) list \<Rightarrow> bool" | 
| 22447 | 133 | where | 
| 25832 | 134 | v_nil[intro]: "valid []" | 
| 135 | | v_cons[intro]: "\<lbrakk>valid \<Gamma>;x\<sharp>\<Gamma>\<rbrakk> \<Longrightarrow> valid ((x,T)#\<Gamma>)" | |
| 22447 | 136 | |
| 22534 | 137 | equivariance valid | 
| 22447 | 138 | |
| 25832 | 139 | inductive_cases | 
| 28568 | 140 | valid_elim[elim]: "valid ((x,T)#\<Gamma>)" | 
| 22447 | 141 | |
| 28568 | 142 | lemma valid_insert: | 
| 143 | assumes a: "valid (\<Delta>@[(x,T)]@\<Gamma>)" | |
| 144 | shows "valid (\<Delta> @ \<Gamma>)" | |
| 145 | using a | |
| 146 | by (induct \<Delta>) | |
| 147 | (auto simp add: fresh_list_append fresh_list_cons elim!: valid_elim) | |
| 22447 | 148 | |
| 28568 | 149 | lemma fresh_set: | 
| 150 | shows "y\<sharp>xs = (\<forall>x\<in>set xs. y\<sharp>x)" | |
| 151 | by (induct xs) (simp_all add: fresh_list_nil fresh_list_cons) | |
| 152 | ||
| 153 | lemma context_unique: | |
| 154 | assumes a1: "valid \<Gamma>" | |
| 155 | and a2: "(x,T) \<in> set \<Gamma>" | |
| 156 | and a3: "(x,U) \<in> set \<Gamma>" | |
| 157 | shows "T = U" | |
| 158 | using a1 a2 a3 | |
| 159 | by (induct) (auto simp add: fresh_set fresh_prod fresh_atm) | |
| 22447 | 160 | |
| 63167 | 161 | text \<open>Typing Relation\<close> | 
| 25867 | 162 | |
| 23760 | 163 | inductive | 
| 22447 | 164 |   typing :: "(name\<times>ty) list\<Rightarrow>trm\<Rightarrow>ty\<Rightarrow>bool" ("_ \<turnstile> _ : _" [60,60,60] 60) 
 | 
| 165 | where | |
| 25832 | 166 | t_Var[intro]: "\<lbrakk>valid \<Gamma>; (x,T)\<in>set \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Var x : T" | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 167 | | t_App[intro]: "\<lbrakk>\<Gamma> \<turnstile> e\<^sub>1 : T\<^sub>1\<rightarrow>T\<^sub>2; \<Gamma> \<turnstile> e\<^sub>2 : T\<^sub>1\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> App e\<^sub>1 e\<^sub>2 : T\<^sub>2" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 168 | | t_Lam[intro]: "\<lbrakk>x\<sharp>\<Gamma>; (x,T\<^sub>1)#\<Gamma> \<turnstile> e : T\<^sub>2\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Lam [x].e : T\<^sub>1\<rightarrow>T\<^sub>2" | 
| 22447 | 169 | |
| 22730 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 170 | equivariance typing | 
| 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 171 | |
| 22531 | 172 | nominal_inductive typing | 
| 25832 | 173 | by (simp_all add: abs_fresh fresh_ty) | 
| 22531 | 174 | |
| 22472 | 175 | lemma typing_implies_valid: | 
| 25832 | 176 | assumes a: "\<Gamma> \<turnstile> t : T" | 
| 22447 | 177 | shows "valid \<Gamma>" | 
| 28568 | 178 | using a by (induct) (auto) | 
| 179 | ||
| 180 | ||
| 181 | lemma t_App_elim: | |
| 182 | assumes a: "\<Gamma> \<turnstile> App t1 t2 : T" | |
| 183 | obtains T' where "\<Gamma> \<turnstile> t1 : T' \<rightarrow> T" and "\<Gamma> \<turnstile> t2 : T'" | |
| 184 | using a | |
| 185 | by (cases) (auto simp add: trm.inject) | |
| 22447 | 186 | |
| 25832 | 187 | lemma t_Lam_elim: | 
| 25867 | 188 | assumes a: "\<Gamma> \<turnstile> Lam [x].t : T" "x\<sharp>\<Gamma>" | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 189 | obtains T\<^sub>1 and T\<^sub>2 where "(x,T\<^sub>1)#\<Gamma> \<turnstile> t : T\<^sub>2" and "T=T\<^sub>1\<rightarrow>T\<^sub>2" | 
| 25867 | 190 | using a | 
| 25832 | 191 | by (cases rule: typing.strong_cases [where x="x"]) | 
| 192 | (auto simp add: abs_fresh fresh_ty alpha trm.inject) | |
| 22447 | 193 | |
| 25832 | 194 | abbreviation | 
| 195 |   "sub_context" :: "(name\<times>ty) list \<Rightarrow> (name\<times>ty) list \<Rightarrow> bool" ("_ \<subseteq> _" [55,55] 55)
 | |
| 196 | where | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 197 | "\<Gamma>\<^sub>1 \<subseteq> \<Gamma>\<^sub>2 \<equiv> \<forall>x T. (x,T)\<in>set \<Gamma>\<^sub>1 \<longrightarrow> (x,T)\<in>set \<Gamma>\<^sub>2" | 
| 22447 | 198 | |
| 199 | lemma weakening: | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 200 | fixes \<Gamma>\<^sub>1 \<Gamma>\<^sub>2::"(name\<times>ty) list" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 201 | assumes "\<Gamma>\<^sub>1 \<turnstile> e: T" and "valid \<Gamma>\<^sub>2" and "\<Gamma>\<^sub>1 \<subseteq> \<Gamma>\<^sub>2" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 202 | shows "\<Gamma>\<^sub>2 \<turnstile> e: T" | 
| 22447 | 203 | using assms | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 204 | proof(nominal_induct \<Gamma>\<^sub>1 e T avoiding: \<Gamma>\<^sub>2 rule: typing.strong_induct) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 205 | case (t_Lam x \<Gamma>\<^sub>1 T\<^sub>1 t T\<^sub>2 \<Gamma>\<^sub>2) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 206 | have vc: "x\<sharp>\<Gamma>\<^sub>2" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 207 | have ih: "\<lbrakk>valid ((x,T\<^sub>1)#\<Gamma>\<^sub>2); (x,T\<^sub>1)#\<Gamma>\<^sub>1 \<subseteq> (x,T\<^sub>1)#\<Gamma>\<^sub>2\<rbrakk> \<Longrightarrow> (x,T\<^sub>1)#\<Gamma>\<^sub>2 \<turnstile> t : T\<^sub>2" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 208 | have "valid \<Gamma>\<^sub>2" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 209 | then have "valid ((x,T\<^sub>1)#\<Gamma>\<^sub>2)" using vc by auto | 
| 25832 | 210 | moreover | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 211 | have "\<Gamma>\<^sub>1 \<subseteq> \<Gamma>\<^sub>2" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 212 | then have "(x,T\<^sub>1)#\<Gamma>\<^sub>1 \<subseteq> (x,T\<^sub>1)#\<Gamma>\<^sub>2" by simp | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 213 | ultimately have "(x,T\<^sub>1)#\<Gamma>\<^sub>2 \<turnstile> t : T\<^sub>2" using ih by simp | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 214 | with vc show "\<Gamma>\<^sub>2 \<turnstile> Lam [x].t : T\<^sub>1\<rightarrow>T\<^sub>2" by auto | 
| 22447 | 215 | qed (auto) | 
| 216 | ||
| 28568 | 217 | lemma type_substitutivity_aux: | 
| 218 | assumes a: "(\<Delta>@[(x,T')]@\<Gamma>) \<turnstile> e : T" | |
| 219 | and b: "\<Gamma> \<turnstile> e' : T'" | |
| 220 | shows "(\<Delta>@\<Gamma>) \<turnstile> e[x::=e'] : T" | |
| 221 | using a b | |
| 222 | proof (nominal_induct \<Gamma>\<equiv>"\<Delta>@[(x,T')]@\<Gamma>" e T avoiding: e' \<Delta> rule: typing.strong_induct) | |
| 34915 | 223 | case (t_Var y T e' \<Delta>) | 
| 28568 | 224 | then have a1: "valid (\<Delta>@[(x,T')]@\<Gamma>)" | 
| 225 | and a2: "(y,T) \<in> set (\<Delta>@[(x,T')]@\<Gamma>)" | |
| 34915 | 226 | and a3: "\<Gamma> \<turnstile> e' : T'" . | 
| 28568 | 227 | from a1 have a4: "valid (\<Delta>@\<Gamma>)" by (rule valid_insert) | 
| 228 |   { assume eq: "x=y"
 | |
| 229 | from a1 a2 have "T=T'" using eq by (auto intro: context_unique) | |
| 230 | with a3 have "\<Delta>@\<Gamma> \<turnstile> Var y[x::=e'] : T" using eq a4 by (auto intro: weakening) | |
| 231 | } | |
| 232 | moreover | |
| 233 |   { assume ineq: "x\<noteq>y"
 | |
| 234 | from a2 have "(y,T) \<in> set (\<Delta>@\<Gamma>)" using ineq by simp | |
| 235 | then have "\<Delta>@\<Gamma> \<turnstile> Var y[x::=e'] : T" using ineq a4 by auto | |
| 236 | } | |
| 237 | ultimately show "\<Delta>@\<Gamma> \<turnstile> Var y[x::=e'] : T" by blast | |
| 238 | qed (force simp add: fresh_list_append fresh_list_cons)+ | |
| 22447 | 239 | |
| 28568 | 240 | corollary type_substitutivity: | 
| 241 | assumes a: "(x,T')#\<Gamma> \<turnstile> e : T" | |
| 242 | and b: "\<Gamma> \<turnstile> e' : T'" | |
| 22447 | 243 | shows "\<Gamma> \<turnstile> e[x::=e'] : T" | 
| 28568 | 244 | using a b type_substitutivity_aux[where \<Delta>="[]"] | 
| 245 | by (auto) | |
| 25832 | 246 | |
| 63167 | 247 | text \<open>Values\<close> | 
| 25832 | 248 | inductive | 
| 249 | val :: "trm\<Rightarrow>bool" | |
| 250 | where | |
| 251 | v_Lam[intro]: "val (Lam [x].e)" | |
| 252 | ||
| 253 | equivariance val | |
| 254 | ||
| 255 | lemma not_val_App[simp]: | |
| 256 | shows | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 257 | "\<not> val (App e\<^sub>1 e\<^sub>2)" | 
| 25832 | 258 | "\<not> val (Var x)" | 
| 259 | by (auto elim: val.cases) | |
| 22447 | 260 | |
| 63167 | 261 | text \<open>Big-Step Evaluation\<close> | 
| 22447 | 262 | |
| 23760 | 263 | inductive | 
| 22447 | 264 |   big :: "trm\<Rightarrow>trm\<Rightarrow>bool" ("_ \<Down> _" [80,80] 80) 
 | 
| 265 | where | |
| 266 | b_Lam[intro]: "Lam [x].e \<Down> Lam [x].e" | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 267 | | b_App[intro]: "\<lbrakk>x\<sharp>(e\<^sub>1,e\<^sub>2,e'); e\<^sub>1\<Down>Lam [x].e; e\<^sub>2\<Down>e\<^sub>2'; e[x::=e\<^sub>2']\<Down>e'\<rbrakk> \<Longrightarrow> App e\<^sub>1 e\<^sub>2 \<Down> e'" | 
| 22447 | 268 | |
| 22730 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 269 | equivariance big | 
| 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 270 | |
| 22447 | 271 | nominal_inductive big | 
| 25832 | 272 | by (simp_all add: abs_fresh) | 
| 22447 | 273 | |
| 25832 | 274 | lemma big_preserves_fresh: | 
| 275 | fixes x::"name" | |
| 276 | assumes a: "e \<Down> e'" "x\<sharp>e" | |
| 277 | shows "x\<sharp>e'" | |
| 278 | using a by (induct) (auto simp add: abs_fresh fresh_subst) | |
| 22447 | 279 | |
| 25832 | 280 | lemma b_App_elim: | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 281 | assumes a: "App e\<^sub>1 e\<^sub>2 \<Down> e'" "x\<sharp>(e\<^sub>1,e\<^sub>2,e')" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 282 | obtains f\<^sub>1 and f\<^sub>2 where "e\<^sub>1 \<Down> Lam [x]. f\<^sub>1" "e\<^sub>2 \<Down> f\<^sub>2" "f\<^sub>1[x::=f\<^sub>2] \<Down> e'" | 
| 25832 | 283 | using a | 
| 284 | by (cases rule: big.strong_cases[where x="x" and xa="x"]) | |
| 285 | (auto simp add: trm.inject) | |
| 22447 | 286 | |
| 287 | lemma subject_reduction: | |
| 25832 | 288 | assumes a: "e \<Down> e'" and b: "\<Gamma> \<turnstile> e : T" | 
| 22447 | 289 | shows "\<Gamma> \<turnstile> e' : T" | 
| 22472 | 290 | using a b | 
| 22534 | 291 | proof (nominal_induct avoiding: \<Gamma> arbitrary: T rule: big.strong_induct) | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 292 | case (b_App x e\<^sub>1 e\<^sub>2 e' e e\<^sub>2' \<Gamma> T) | 
| 22447 | 293 | have vc: "x\<sharp>\<Gamma>" by fact | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 294 | have "\<Gamma> \<turnstile> App e\<^sub>1 e\<^sub>2 : T" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 295 | then obtain T' where a1: "\<Gamma> \<turnstile> e\<^sub>1 : T'\<rightarrow>T" and a2: "\<Gamma> \<turnstile> e\<^sub>2 : T'" | 
| 25832 | 296 | by (cases) (auto simp add: trm.inject) | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 297 | have ih1: "\<Gamma> \<turnstile> e\<^sub>1 : T' \<rightarrow> T \<Longrightarrow> \<Gamma> \<turnstile> Lam [x].e : T' \<rightarrow> T" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 298 | have ih2: "\<Gamma> \<turnstile> e\<^sub>2 : T' \<Longrightarrow> \<Gamma> \<turnstile> e\<^sub>2' : T'" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 299 | have ih3: "\<Gamma> \<turnstile> e[x::=e\<^sub>2'] : T \<Longrightarrow> \<Gamma> \<turnstile> e' : T" by fact | 
| 22447 | 300 | have "\<Gamma> \<turnstile> Lam [x].e : T'\<rightarrow>T" using ih1 a1 by simp | 
| 25832 | 301 | then have "((x,T')#\<Gamma>) \<turnstile> e : T" using vc | 
| 302 | by (auto elim: t_Lam_elim simp add: ty.inject) | |
| 22447 | 303 | moreover | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 304 | have "\<Gamma> \<turnstile> e\<^sub>2': T'" using ih2 a2 by simp | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 305 | ultimately have "\<Gamma> \<turnstile> e[x::=e\<^sub>2'] : T" by (simp add: type_substitutivity) | 
| 22447 | 306 | thus "\<Gamma> \<turnstile> e' : T" using ih3 by simp | 
| 28568 | 307 | qed (blast) | 
| 308 | ||
| 309 | lemma subject_reduction2: | |
| 310 | assumes a: "e \<Down> e'" and b: "\<Gamma> \<turnstile> e : T" | |
| 311 | shows "\<Gamma> \<turnstile> e' : T" | |
| 312 | using a b | |
| 313 | by (nominal_induct avoiding: \<Gamma> T rule: big.strong_induct) | |
| 314 | (force elim: t_App_elim t_Lam_elim simp add: ty.inject type_substitutivity)+ | |
| 22447 | 315 | |
| 22472 | 316 | lemma unicity_of_evaluation: | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 317 | assumes a: "e \<Down> e\<^sub>1" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 318 | and b: "e \<Down> e\<^sub>2" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 319 | shows "e\<^sub>1 = e\<^sub>2" | 
| 22472 | 320 | using a b | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 321 | proof (nominal_induct e e\<^sub>1 avoiding: e\<^sub>2 rule: big.strong_induct) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 322 | case (b_Lam x e t\<^sub>2) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 323 | have "Lam [x].e \<Down> t\<^sub>2" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 324 | thus "Lam [x].e = t\<^sub>2" by cases (simp_all add: trm.inject) | 
| 22447 | 325 | next | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 326 | case (b_App x e\<^sub>1 e\<^sub>2 e' e\<^sub>1' e\<^sub>2' t\<^sub>2) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 327 | have ih1: "\<And>t. e\<^sub>1 \<Down> t \<Longrightarrow> Lam [x].e\<^sub>1' = t" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 328 | have ih2:"\<And>t. e\<^sub>2 \<Down> t \<Longrightarrow> e\<^sub>2' = t" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 329 | have ih3: "\<And>t. e\<^sub>1'[x::=e\<^sub>2'] \<Down> t \<Longrightarrow> e' = t" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 330 | have app: "App e\<^sub>1 e\<^sub>2 \<Down> t\<^sub>2" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 331 | have vc: "x\<sharp>e\<^sub>1" "x\<sharp>e\<^sub>2" "x\<sharp>t\<^sub>2" by fact+ | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 332 | then have "x\<sharp>App e\<^sub>1 e\<^sub>2" by auto | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 333 | from app vc obtain f\<^sub>1 f\<^sub>2 where x1: "e\<^sub>1 \<Down> Lam [x]. f\<^sub>1" and x2: "e\<^sub>2 \<Down> f\<^sub>2" and x3: "f\<^sub>1[x::=f\<^sub>2] \<Down> t\<^sub>2" | 
| 28568 | 334 | by (auto elim!: b_App_elim) | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 335 | then have "Lam [x]. f\<^sub>1 = Lam [x]. e\<^sub>1'" using ih1 by simp | 
| 22472 | 336 | then | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 337 | have "f\<^sub>1 = e\<^sub>1'" by (auto simp add: trm.inject alpha) | 
| 22472 | 338 | moreover | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 339 | have "f\<^sub>2 = e\<^sub>2'" using x2 ih2 by simp | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 340 | ultimately have "e\<^sub>1'[x::=e\<^sub>2'] \<Down> t\<^sub>2" using x3 by simp | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 341 | thus "e' = t\<^sub>2" using ih3 by simp | 
| 25832 | 342 | qed | 
| 22447 | 343 | |
| 22472 | 344 | lemma reduces_evaluates_to_values: | 
| 28568 | 345 | assumes h: "t \<Down> t'" | 
| 22447 | 346 | shows "val t'" | 
| 28568 | 347 | using h by (induct) (auto) | 
| 22447 | 348 | |
| 25832 | 349 | (* Valuation *) | 
| 22447 | 350 | |
| 351 | nominal_primrec | |
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
28568diff
changeset | 352 | V :: "ty \<Rightarrow> trm set" | 
| 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
28568diff
changeset | 353 | where | 
| 25832 | 354 |   "V (TVar x) = {e. val e}"
 | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 355 | | "V (T\<^sub>1 \<rightarrow> T\<^sub>2) = {Lam [x].e | x e. \<forall> v \<in> (V T\<^sub>1). \<exists> v'. e[x::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2}"
 | 
| 25832 | 356 | by (rule TrueI)+ | 
| 22447 | 357 | |
| 22472 | 358 | lemma V_eqvt: | 
| 359 | fixes pi::"name prm" | |
| 360 | assumes a: "x\<in>V T" | |
| 361 | shows "(pi\<bullet>x)\<in>V T" | |
| 362 | using a | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 363 | apply(nominal_induct T arbitrary: pi x rule: ty.strong_induct) | 
| 26806 | 364 | apply(auto simp add: trm.inject) | 
| 25832 | 365 | apply(simp add: eqvts) | 
| 22472 | 366 | apply(rule_tac x="pi\<bullet>xa" in exI) | 
| 367 | apply(rule_tac x="pi\<bullet>e" in exI) | |
| 368 | apply(simp) | |
| 369 | apply(auto) | |
| 370 | apply(drule_tac x="(rev pi)\<bullet>v" in bspec) | |
| 371 | apply(force) | |
| 372 | apply(auto) | |
| 373 | apply(rule_tac x="pi\<bullet>v'" in exI) | |
| 374 | apply(auto) | |
| 22542 | 375 | apply(drule_tac pi="pi" in big.eqvt) | 
| 22541 
c33b542394f3
the name for the collection of equivariance lemmas is now eqvts (changed from eqvt) in order to avoid clashes with eqvt-lemmas generated in nominal_inductive
 urbanc parents: 
22534diff
changeset | 376 | apply(perm_simp add: eqvts) | 
| 22472 | 377 | done | 
| 378 | ||
| 25832 | 379 | lemma V_arrow_elim_weak: | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 380 | assumes h:"u \<in> V (T\<^sub>1 \<rightarrow> T\<^sub>2)" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 381 | obtains a t where "u = Lam [a].t" and "\<forall> v \<in> (V T\<^sub>1). \<exists> v'. t[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" | 
| 22447 | 382 | using h by (auto) | 
| 383 | ||
| 25832 | 384 | lemma V_arrow_elim_strong: | 
| 22447 | 385 | fixes c::"'a::fs_name" | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 386 | assumes h: "u \<in> V (T\<^sub>1 \<rightarrow> T\<^sub>2)" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 387 | obtains a t where "a\<sharp>c" "u = Lam [a].t" "\<forall>v \<in> (V T\<^sub>1). \<exists> v'. t[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" | 
| 22447 | 388 | using h | 
| 389 | apply - | |
| 390 | apply(erule V_arrow_elim_weak) | |
| 22472 | 391 | apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(a,t,c)") (*A*) | 
| 22447 | 392 | apply(erule exE) | 
| 393 | apply(drule_tac x="a'" in meta_spec) | |
| 22472 | 394 | apply(drule_tac x="[(a,a')]\<bullet>t" in meta_spec) | 
| 395 | apply(drule meta_mp) | |
| 22447 | 396 | apply(simp) | 
| 22472 | 397 | apply(drule meta_mp) | 
| 398 | apply(simp add: trm.inject alpha fresh_left fresh_prod calc_atm fresh_atm) | |
| 22447 | 399 | apply(perm_simp) | 
| 22472 | 400 | apply(force) | 
| 401 | apply(drule meta_mp) | |
| 402 | apply(rule ballI) | |
| 403 | apply(drule_tac x="[(a,a')]\<bullet>v" in bspec) | |
| 404 | apply(simp add: V_eqvt) | |
| 22447 | 405 | apply(auto) | 
| 22472 | 406 | apply(rule_tac x="[(a,a')]\<bullet>v'" in exI) | 
| 407 | apply(auto) | |
| 22542 | 408 | apply(drule_tac pi="[(a,a')]" in big.eqvt) | 
| 22541 
c33b542394f3
the name for the collection of equivariance lemmas is now eqvts (changed from eqvt) in order to avoid clashes with eqvt-lemmas generated in nominal_inductive
 urbanc parents: 
22534diff
changeset | 409 | apply(perm_simp add: eqvts calc_atm) | 
| 22472 | 410 | apply(simp add: V_eqvt) | 
| 411 | (*A*) | |
| 22447 | 412 | apply(rule exists_fresh') | 
| 22472 | 413 | apply(simp add: fin_supp) | 
| 22447 | 414 | done | 
| 415 | ||
| 25832 | 416 | lemma Vs_are_values: | 
| 417 | assumes a: "e \<in> V T" | |
| 22447 | 418 | shows "val e" | 
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 419 | using a by (nominal_induct T arbitrary: e rule: ty.strong_induct) (auto) | 
| 22447 | 420 | |
| 421 | lemma values_reduce_to_themselves: | |
| 25832 | 422 | assumes a: "val v" | 
| 22447 | 423 | shows "v \<Down> v" | 
| 25832 | 424 | using a by (induct) (auto) | 
| 22447 | 425 | |
| 25832 | 426 | lemma Vs_reduce_to_themselves: | 
| 427 | assumes a: "v \<in> V T" | |
| 428 | shows "v \<Down> v" | |
| 429 | using a by (simp add: values_reduce_to_themselves Vs_are_values) | |
| 22447 | 430 | |
| 63167 | 431 | text \<open>'\<theta> maps x to e' asserts that \<theta> substitutes x with e\<close> | 
| 22447 | 432 | abbreviation | 
| 25832 | 433 |   mapsto :: "(name\<times>trm) list \<Rightarrow> name \<Rightarrow> trm \<Rightarrow> bool" ("_ maps _ to _" [55,55,55] 55) 
 | 
| 22447 | 434 | where | 
| 25832 | 435 | "\<theta> maps x to e \<equiv> (lookup \<theta> x) = e" | 
| 22447 | 436 | |
| 437 | abbreviation | |
| 438 |   v_closes :: "(name\<times>trm) list \<Rightarrow> (name\<times>ty) list \<Rightarrow> bool" ("_ Vcloses _" [55,55] 55) 
 | |
| 439 | where | |
| 25832 | 440 | "\<theta> Vcloses \<Gamma> \<equiv> \<forall>x T. (x,T) \<in> set \<Gamma> \<longrightarrow> (\<exists>v. \<theta> maps x to v \<and> v \<in> V T)" | 
| 22447 | 441 | |
| 28568 | 442 | lemma case_distinction_on_context: | 
| 443 | fixes \<Gamma>::"(name\<times>ty) list" | |
| 444 | assumes asm1: "valid ((m,t)#\<Gamma>)" | |
| 445 | and asm2: "(n,U) \<in> set ((m,T)#\<Gamma>)" | |
| 446 | shows "(n,U) = (m,T) \<or> ((n,U) \<in> set \<Gamma> \<and> n \<noteq> m)" | |
| 447 | proof - | |
| 448 | from asm2 have "(n,U) \<in> set [(m,T)] \<or> (n,U) \<in> set \<Gamma>" by auto | |
| 449 | moreover | |
| 450 |   { assume eq: "m=n"
 | |
| 451 | assume "(n,U) \<in> set \<Gamma>" | |
| 452 | then have "\<not> n\<sharp>\<Gamma>" | |
| 453 | by (induct \<Gamma>) (auto simp add: fresh_list_cons fresh_prod fresh_atm) | |
| 454 | moreover have "m\<sharp>\<Gamma>" using asm1 by auto | |
| 455 | ultimately have False using eq by auto | |
| 456 | } | |
| 457 | ultimately show ?thesis by auto | |
| 458 | qed | |
| 459 | ||
| 22447 | 460 | lemma monotonicity: | 
| 461 | fixes m::"name" | |
| 462 | fixes \<theta>::"(name \<times> trm) list" | |
| 463 | assumes h1: "\<theta> Vcloses \<Gamma>" | |
| 464 | and h2: "e \<in> V T" | |
| 465 | and h3: "valid ((x,T)#\<Gamma>)" | |
| 466 | shows "(x,e)#\<theta> Vcloses (x,T)#\<Gamma>" | |
| 467 | proof(intro strip) | |
| 468 | fix x' T' | |
| 469 | assume "(x',T') \<in> set ((x,T)#\<Gamma>)" | |
| 470 | then have "((x',T')=(x,T)) \<or> ((x',T')\<in>set \<Gamma> \<and> x'\<noteq>x)" using h3 | |
| 471 | by (rule_tac case_distinction_on_context) | |
| 472 | moreover | |
| 473 |   { (* first case *)
 | |
| 474 | assume "(x',T') = (x,T)" | |
| 475 | then have "\<exists>e'. ((x,e)#\<theta>) maps x to e' \<and> e' \<in> V T'" using h2 by auto | |
| 476 | } | |
| 477 | moreover | |
| 478 |   { (* second case *)
 | |
| 479 | assume "(x',T') \<in> set \<Gamma>" and neq:"x' \<noteq> x" | |
| 480 | then have "\<exists>e'. \<theta> maps x' to e' \<and> e' \<in> V T'" using h1 by auto | |
| 481 | then have "\<exists>e'. ((x,e)#\<theta>) maps x' to e' \<and> e' \<in> V T'" using neq by auto | |
| 482 | } | |
| 483 | ultimately show "\<exists>e'. ((x,e)#\<theta>) maps x' to e' \<and> e' \<in> V T'" by blast | |
| 484 | qed | |
| 485 | ||
| 486 | lemma termination_aux: | |
| 487 | assumes h1: "\<Gamma> \<turnstile> e : T" | |
| 488 | and h2: "\<theta> Vcloses \<Gamma>" | |
| 489 | shows "\<exists>v. \<theta><e> \<Down> v \<and> v \<in> V T" | |
| 490 | using h2 h1 | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 491 | proof(nominal_induct e avoiding: \<Gamma> \<theta> arbitrary: T rule: trm.strong_induct) | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 492 | case (App e\<^sub>1 e\<^sub>2 \<Gamma> \<theta> T) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 493 | have ih\<^sub>1: "\<And>\<theta> \<Gamma> T. \<lbrakk>\<theta> Vcloses \<Gamma>; \<Gamma> \<turnstile> e\<^sub>1 : T\<rbrakk> \<Longrightarrow> \<exists>v. \<theta><e\<^sub>1> \<Down> v \<and> v \<in> V T" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 494 | have ih\<^sub>2: "\<And>\<theta> \<Gamma> T. \<lbrakk>\<theta> Vcloses \<Gamma>; \<Gamma> \<turnstile> e\<^sub>2 : T\<rbrakk> \<Longrightarrow> \<exists>v. \<theta><e\<^sub>2> \<Down> v \<and> v \<in> V T" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 495 | have as\<^sub>1: "\<theta> Vcloses \<Gamma>" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 496 | have as\<^sub>2: "\<Gamma> \<turnstile> App e\<^sub>1 e\<^sub>2 : T" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 497 | then obtain T' where "\<Gamma> \<turnstile> e\<^sub>1 : T' \<rightarrow> T" and "\<Gamma> \<turnstile> e\<^sub>2 : T'" by (auto elim: t_App_elim) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 498 | then obtain v\<^sub>1 v\<^sub>2 where "(i)": "\<theta><e\<^sub>1> \<Down> v\<^sub>1" "v\<^sub>1 \<in> V (T' \<rightarrow> T)" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 499 | and "(ii)": "\<theta><e\<^sub>2> \<Down> v\<^sub>2" "v\<^sub>2 \<in> V T'" using ih\<^sub>1 ih\<^sub>2 as\<^sub>1 by blast | 
| 22447 | 500 | from "(i)" obtain x e' | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 501 | where "v\<^sub>1 = Lam [x].e'" | 
| 22447 | 502 | and "(iii)": "(\<forall>v \<in> (V T').\<exists> v'. e'[x::=v] \<Down> v' \<and> v' \<in> V T)" | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 503 | and "(iv)": "\<theta><e\<^sub>1> \<Down> Lam [x].e'" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 504 | and fr: "x\<sharp>(\<theta>,e\<^sub>1,e\<^sub>2)" by (blast elim: V_arrow_elim_strong) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 505 | from fr have fr\<^sub>1: "x\<sharp>\<theta><e\<^sub>1>" and fr\<^sub>2: "x\<sharp>\<theta><e\<^sub>2>" by (simp_all add: fresh_psubst) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 506 | from "(ii)" "(iii)" obtain v\<^sub>3 where "(v)": "e'[x::=v\<^sub>2] \<Down> v\<^sub>3" "v\<^sub>3 \<in> V T" by auto | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 507 | from fr\<^sub>2 "(ii)" have "x\<sharp>v\<^sub>2" by (simp add: big_preserves_fresh) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 508 | then have "x\<sharp>e'[x::=v\<^sub>2]" by (simp add: fresh_subst) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 509 | then have fr\<^sub>3: "x\<sharp>v\<^sub>3" using "(v)" by (simp add: big_preserves_fresh) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 510 | from fr\<^sub>1 fr\<^sub>2 fr\<^sub>3 have "x\<sharp>(\<theta><e\<^sub>1>,\<theta><e\<^sub>2>,v\<^sub>3)" by simp | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 511 | with "(iv)" "(ii)" "(v)" have "App (\<theta><e\<^sub>1>) (\<theta><e\<^sub>2>) \<Down> v\<^sub>3" by auto | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 512 | then show "\<exists>v. \<theta><App e\<^sub>1 e\<^sub>2> \<Down> v \<and> v \<in> V T" using "(v)" by auto | 
| 22447 | 513 | next | 
| 514 | case (Lam x e \<Gamma> \<theta> T) | |
| 515 | have ih:"\<And>\<theta> \<Gamma> T. \<lbrakk>\<theta> Vcloses \<Gamma>; \<Gamma> \<turnstile> e : T\<rbrakk> \<Longrightarrow> \<exists>v. \<theta><e> \<Down> v \<and> v \<in> V T" by fact | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 516 | have as\<^sub>1: "\<theta> Vcloses \<Gamma>" by fact | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 517 | have as\<^sub>2: "\<Gamma> \<turnstile> Lam [x].e : T" by fact | 
| 29300 | 518 | have fs: "x\<sharp>\<Gamma>" "x\<sharp>\<theta>" by fact+ | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 519 | from as\<^sub>2 fs obtain T\<^sub>1 T\<^sub>2 | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 520 | where "(i)": "(x,T\<^sub>1)#\<Gamma> \<turnstile> e:T\<^sub>2" and "(ii)": "T = T\<^sub>1 \<rightarrow> T\<^sub>2" using fs | 
| 28568 | 521 | by (auto elim: t_Lam_elim) | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 522 | from "(i)" have "(iii)": "valid ((x,T\<^sub>1)#\<Gamma>)" by (simp add: typing_implies_valid) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 523 | have "\<forall>v \<in> (V T\<^sub>1). \<exists>v'. (\<theta><e>)[x::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" | 
| 22447 | 524 | proof | 
| 525 | fix v | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 526 | assume "v \<in> (V T\<^sub>1)" | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 527 | with "(iii)" as\<^sub>1 have "(x,v)#\<theta> Vcloses (x,T\<^sub>1)#\<Gamma>" using monotonicity by auto | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 528 | with ih "(i)" obtain v' where "((x,v)#\<theta>)<e> \<Down> v' \<and> v' \<in> V T\<^sub>2" by blast | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 529 | then have "\<theta><e>[x::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" using fs by (simp add: psubst_subst_psubst) | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 530 | then show "\<exists>v'. \<theta><e>[x::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" by auto | 
| 22447 | 531 | qed | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 532 | then have "Lam[x].\<theta><e> \<in> V (T\<^sub>1 \<rightarrow> T\<^sub>2)" by auto | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 533 | then have "\<theta><Lam [x].e> \<Down> Lam [x].\<theta><e> \<and> Lam [x].\<theta><e> \<in> V (T\<^sub>1\<rightarrow>T\<^sub>2)" using fs by auto | 
| 22447 | 534 | thus "\<exists>v. \<theta><Lam [x].e> \<Down> v \<and> v \<in> V T" using "(ii)" by auto | 
| 535 | next | |
| 25832 | 536 | case (Var x \<Gamma> \<theta> T) | 
| 537 | have "\<Gamma> \<turnstile> (Var x) : T" by fact | |
| 538 | then have "(x,T)\<in>set \<Gamma>" by (cases) (auto simp add: trm.inject) | |
| 41893 | 539 | with Var have "\<theta><Var x> \<Down> \<theta><Var x> \<and> \<theta><Var x>\<in> V T" | 
| 25832 | 540 | by (auto intro!: Vs_reduce_to_themselves) | 
| 541 | then show "\<exists>v. \<theta><Var x> \<Down> v \<and> v \<in> V T" by auto | |
| 542 | qed | |
| 22447 | 543 | |
| 544 | theorem termination_of_evaluation: | |
| 545 | assumes a: "[] \<turnstile> e : T" | |
| 546 | shows "\<exists>v. e \<Down> v \<and> val v" | |
| 547 | proof - | |
| 25832 | 548 | from a have "\<exists>v. []<e> \<Down> v \<and> v \<in> V T" by (rule termination_aux) (auto) | 
| 549 | thus "\<exists>v. e \<Down> v \<and> val v" using Vs_are_values by auto | |
| 22447 | 550 | qed | 
| 551 | ||
| 552 | end |