| author | wenzelm | 
| Thu, 29 Aug 2024 11:43:14 +0200 | |
| changeset 80788 | 66a8113ac23e | 
| parent 80146 | cf11a7f0a5f0 | 
| child 80914 | d97fdabd9e2b | 
| 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>)" | 
| 80146 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 70 | by (finite_guess | simp add: abs_fresh | fresh_guess)+ | 
| 22447 | 71 | |
| 72 | lemma psubst_eqvt[eqvt]: | |
| 73 | fixes pi::"name prm" | |
| 74 | and t::"trm" | |
| 75 | 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 | 76 | by (nominal_induct t avoiding: \<theta> rule: trm.strong_induct) | 
| 22472 | 77 | (perm_simp add: fresh_bij lookup_eqvt)+ | 
| 22447 | 78 | |
| 79 | lemma fresh_psubst: | |
| 80 | fixes z::"name" | |
| 81 | and t::"trm" | |
| 82 | assumes "z\<sharp>t" and "z\<sharp>\<theta>" | |
| 83 | shows "z\<sharp>(\<theta><t>)" | |
| 84 | using assms | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 85 | by (nominal_induct t avoiding: z \<theta> t rule: trm.strong_induct) | 
| 22447 | 86 | (auto simp add: abs_fresh lookup_fresh) | 
| 87 | ||
| 25832 | 88 | lemma psubst_empty[simp]: | 
| 89 | shows "[]<t> = t" | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 90 | by (nominal_induct t rule: trm.strong_induct) | 
| 25832 | 91 | (auto simp add: fresh_list_nil) | 
| 92 | ||
| 63167 | 93 | text \<open>Single substitution\<close> | 
| 22447 | 94 | abbreviation | 
| 25832 | 95 |   subst :: "trm \<Rightarrow> name \<Rightarrow> trm \<Rightarrow> trm" ("_[_::=_]" [100,100,100] 100)
 | 
| 96 | where | |
| 97 | "t[x::=t'] \<equiv> ([(x,t')])<t>" | |
| 22447 | 98 | |
| 99 | lemma subst[simp]: | |
| 100 | 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 | 101 | and "(App t\<^sub>1 t\<^sub>2)[y::=t'] = App (t\<^sub>1[y::=t']) (t\<^sub>2[y::=t'])" | 
| 22447 | 102 | and "x\<sharp>(y,t') \<Longrightarrow> (Lam [x].t)[y::=t'] = Lam [x].(t[y::=t'])" | 
| 22472 | 103 | by (simp_all add: fresh_list_cons fresh_list_nil) | 
| 22447 | 104 | |
| 105 | lemma fresh_subst: | |
| 106 | fixes z::"name" | |
| 28568 | 107 | shows "\<lbrakk>z\<sharp>s; (z=y \<or> z\<sharp>t)\<rbrakk> \<Longrightarrow> z\<sharp>t[y::=s]" | 
| 108 | by (nominal_induct t avoiding: z y s rule: trm.strong_induct) | |
| 109 | (auto simp add: abs_fresh fresh_prod fresh_atm) | |
| 22447 | 110 | |
| 111 | lemma forget: | |
| 25867 | 112 | assumes a: "x\<sharp>e" | 
| 25832 | 113 | shows "e[x::=e'] = e" | 
| 25867 | 114 | using a | 
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 115 | by (nominal_induct e avoiding: x e' rule: trm.strong_induct) | 
| 25867 | 116 | (auto simp add: fresh_atm abs_fresh) | 
| 22447 | 117 | |
| 118 | lemma psubst_subst_psubst: | |
| 25867 | 119 | assumes h: "x\<sharp>\<theta>" | 
| 25832 | 120 | shows "\<theta><e>[x::=e'] = ((x,e')#\<theta>)<e>" | 
| 121 | using h | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 122 | by (nominal_induct e avoiding: \<theta> x e' rule: trm.strong_induct) | 
| 25867 | 123 | (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh') | 
| 22447 | 124 | |
| 63167 | 125 | text \<open>Typing Judgements\<close> | 
| 22447 | 126 | |
| 23760 | 127 | inductive | 
| 25832 | 128 | valid :: "(name\<times>ty) list \<Rightarrow> bool" | 
| 22447 | 129 | where | 
| 25832 | 130 | v_nil[intro]: "valid []" | 
| 131 | | v_cons[intro]: "\<lbrakk>valid \<Gamma>;x\<sharp>\<Gamma>\<rbrakk> \<Longrightarrow> valid ((x,T)#\<Gamma>)" | |
| 22447 | 132 | |
| 22534 | 133 | equivariance valid | 
| 22447 | 134 | |
| 25832 | 135 | inductive_cases | 
| 28568 | 136 | valid_elim[elim]: "valid ((x,T)#\<Gamma>)" | 
| 22447 | 137 | |
| 28568 | 138 | lemma valid_insert: | 
| 139 | assumes a: "valid (\<Delta>@[(x,T)]@\<Gamma>)" | |
| 140 | shows "valid (\<Delta> @ \<Gamma>)" | |
| 141 | using a | |
| 142 | by (induct \<Delta>) | |
| 143 | (auto simp add: fresh_list_append fresh_list_cons elim!: valid_elim) | |
| 22447 | 144 | |
| 28568 | 145 | lemma fresh_set: | 
| 146 | shows "y\<sharp>xs = (\<forall>x\<in>set xs. y\<sharp>x)" | |
| 147 | by (induct xs) (simp_all add: fresh_list_nil fresh_list_cons) | |
| 148 | ||
| 149 | lemma context_unique: | |
| 150 | assumes a1: "valid \<Gamma>" | |
| 151 | and a2: "(x,T) \<in> set \<Gamma>" | |
| 152 | and a3: "(x,U) \<in> set \<Gamma>" | |
| 153 | shows "T = U" | |
| 154 | using a1 a2 a3 | |
| 155 | by (induct) (auto simp add: fresh_set fresh_prod fresh_atm) | |
| 22447 | 156 | |
| 63167 | 157 | text \<open>Typing Relation\<close> | 
| 25867 | 158 | |
| 23760 | 159 | inductive | 
| 22447 | 160 |   typing :: "(name\<times>ty) list\<Rightarrow>trm\<Rightarrow>ty\<Rightarrow>bool" ("_ \<turnstile> _ : _" [60,60,60] 60) 
 | 
| 161 | where | |
| 25832 | 162 | 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 | 163 | | 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 | 164 | | 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 | 165 | |
| 22730 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 166 | equivariance typing | 
| 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 167 | |
| 22531 | 168 | nominal_inductive typing | 
| 25832 | 169 | by (simp_all add: abs_fresh fresh_ty) | 
| 22531 | 170 | |
| 22472 | 171 | lemma typing_implies_valid: | 
| 25832 | 172 | assumes a: "\<Gamma> \<turnstile> t : T" | 
| 22447 | 173 | shows "valid \<Gamma>" | 
| 28568 | 174 | using a by (induct) (auto) | 
| 175 | ||
| 176 | ||
| 177 | lemma t_App_elim: | |
| 178 | assumes a: "\<Gamma> \<turnstile> App t1 t2 : T" | |
| 179 | obtains T' where "\<Gamma> \<turnstile> t1 : T' \<rightarrow> T" and "\<Gamma> \<turnstile> t2 : T'" | |
| 180 | using a | |
| 181 | by (cases) (auto simp add: trm.inject) | |
| 22447 | 182 | |
| 25832 | 183 | lemma t_Lam_elim: | 
| 25867 | 184 | 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 | 185 | 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 | 186 | using a | 
| 25832 | 187 | by (cases rule: typing.strong_cases [where x="x"]) | 
| 188 | (auto simp add: abs_fresh fresh_ty alpha trm.inject) | |
| 22447 | 189 | |
| 25832 | 190 | abbreviation | 
| 191 |   "sub_context" :: "(name\<times>ty) list \<Rightarrow> (name\<times>ty) list \<Rightarrow> bool" ("_ \<subseteq> _" [55,55] 55)
 | |
| 192 | where | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 193 | "\<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 | 194 | |
| 195 | lemma weakening: | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 196 | 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 | 197 | 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 | 198 | shows "\<Gamma>\<^sub>2 \<turnstile> e: T" | 
| 22447 | 199 | using assms | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 200 | 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 | 201 | 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 | 202 | 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 | 203 | 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 | 204 | 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 | 205 | then have "valid ((x,T\<^sub>1)#\<Gamma>\<^sub>2)" using vc by auto | 
| 25832 | 206 | moreover | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 207 | 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 | 208 | 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 | 209 | 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 | 210 | with vc show "\<Gamma>\<^sub>2 \<turnstile> Lam [x].t : T\<^sub>1\<rightarrow>T\<^sub>2" by auto | 
| 22447 | 211 | qed (auto) | 
| 212 | ||
| 28568 | 213 | lemma type_substitutivity_aux: | 
| 214 | assumes a: "(\<Delta>@[(x,T')]@\<Gamma>) \<turnstile> e : T" | |
| 215 | and b: "\<Gamma> \<turnstile> e' : T'" | |
| 216 | shows "(\<Delta>@\<Gamma>) \<turnstile> e[x::=e'] : T" | |
| 217 | using a b | |
| 218 | proof (nominal_induct \<Gamma>\<equiv>"\<Delta>@[(x,T')]@\<Gamma>" e T avoiding: e' \<Delta> rule: typing.strong_induct) | |
| 34915 | 219 | case (t_Var y T e' \<Delta>) | 
| 28568 | 220 | then have a1: "valid (\<Delta>@[(x,T')]@\<Gamma>)" | 
| 221 | and a2: "(y,T) \<in> set (\<Delta>@[(x,T')]@\<Gamma>)" | |
| 34915 | 222 | and a3: "\<Gamma> \<turnstile> e' : T'" . | 
| 28568 | 223 | from a1 have a4: "valid (\<Delta>@\<Gamma>)" by (rule valid_insert) | 
| 224 |   { assume eq: "x=y"
 | |
| 225 | from a1 a2 have "T=T'" using eq by (auto intro: context_unique) | |
| 226 | with a3 have "\<Delta>@\<Gamma> \<turnstile> Var y[x::=e'] : T" using eq a4 by (auto intro: weakening) | |
| 227 | } | |
| 228 | moreover | |
| 229 |   { assume ineq: "x\<noteq>y"
 | |
| 230 | from a2 have "(y,T) \<in> set (\<Delta>@\<Gamma>)" using ineq by simp | |
| 231 | then have "\<Delta>@\<Gamma> \<turnstile> Var y[x::=e'] : T" using ineq a4 by auto | |
| 232 | } | |
| 233 | ultimately show "\<Delta>@\<Gamma> \<turnstile> Var y[x::=e'] : T" by blast | |
| 234 | qed (force simp add: fresh_list_append fresh_list_cons)+ | |
| 22447 | 235 | |
| 28568 | 236 | corollary type_substitutivity: | 
| 237 | assumes a: "(x,T')#\<Gamma> \<turnstile> e : T" | |
| 238 | and b: "\<Gamma> \<turnstile> e' : T'" | |
| 22447 | 239 | shows "\<Gamma> \<turnstile> e[x::=e'] : T" | 
| 28568 | 240 | using a b type_substitutivity_aux[where \<Delta>="[]"] | 
| 241 | by (auto) | |
| 25832 | 242 | |
| 63167 | 243 | text \<open>Values\<close> | 
| 25832 | 244 | inductive | 
| 245 | val :: "trm\<Rightarrow>bool" | |
| 246 | where | |
| 247 | v_Lam[intro]: "val (Lam [x].e)" | |
| 248 | ||
| 249 | equivariance val | |
| 250 | ||
| 251 | lemma not_val_App[simp]: | |
| 252 | shows | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 253 | "\<not> val (App e\<^sub>1 e\<^sub>2)" | 
| 25832 | 254 | "\<not> val (Var x)" | 
| 255 | by (auto elim: val.cases) | |
| 22447 | 256 | |
| 63167 | 257 | text \<open>Big-Step Evaluation\<close> | 
| 22447 | 258 | |
| 23760 | 259 | inductive | 
| 22447 | 260 |   big :: "trm\<Rightarrow>trm\<Rightarrow>bool" ("_ \<Down> _" [80,80] 80) 
 | 
| 261 | where | |
| 262 | 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 | 263 | | 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 | 264 | |
| 22730 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 265 | equivariance big | 
| 
8bcc8809ed3b
nominal_inductive no longer proves equivariance.
 berghofe parents: 
22650diff
changeset | 266 | |
| 22447 | 267 | nominal_inductive big | 
| 25832 | 268 | by (simp_all add: abs_fresh) | 
| 22447 | 269 | |
| 25832 | 270 | lemma big_preserves_fresh: | 
| 271 | fixes x::"name" | |
| 272 | assumes a: "e \<Down> e'" "x\<sharp>e" | |
| 273 | shows "x\<sharp>e'" | |
| 274 | using a by (induct) (auto simp add: abs_fresh fresh_subst) | |
| 22447 | 275 | |
| 25832 | 276 | 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 | 277 | 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 | 278 | 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 | 279 | using a | 
| 280 | by (cases rule: big.strong_cases[where x="x" and xa="x"]) | |
| 281 | (auto simp add: trm.inject) | |
| 22447 | 282 | |
| 283 | lemma subject_reduction: | |
| 25832 | 284 | assumes a: "e \<Down> e'" and b: "\<Gamma> \<turnstile> e : T" | 
| 22447 | 285 | shows "\<Gamma> \<turnstile> e' : T" | 
| 22472 | 286 | using a b | 
| 22534 | 287 | 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 | 288 | case (b_App x e\<^sub>1 e\<^sub>2 e' e e\<^sub>2' \<Gamma> T) | 
| 22447 | 289 | 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 | 290 | 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 | 291 | then obtain T' where a1: "\<Gamma> \<turnstile> e\<^sub>1 : T'\<rightarrow>T" and a2: "\<Gamma> \<turnstile> e\<^sub>2 : T'" | 
| 25832 | 292 | 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 | 293 | 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 | 294 | 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 | 295 | have ih3: "\<Gamma> \<turnstile> e[x::=e\<^sub>2'] : T \<Longrightarrow> \<Gamma> \<turnstile> e' : T" by fact | 
| 22447 | 296 | have "\<Gamma> \<turnstile> Lam [x].e : T'\<rightarrow>T" using ih1 a1 by simp | 
| 25832 | 297 | then have "((x,T')#\<Gamma>) \<turnstile> e : T" using vc | 
| 298 | by (auto elim: t_Lam_elim simp add: ty.inject) | |
| 22447 | 299 | moreover | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 300 | 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 | 301 | ultimately have "\<Gamma> \<turnstile> e[x::=e\<^sub>2'] : T" by (simp add: type_substitutivity) | 
| 22447 | 302 | thus "\<Gamma> \<turnstile> e' : T" using ih3 by simp | 
| 28568 | 303 | qed (blast) | 
| 304 | ||
| 305 | lemma subject_reduction2: | |
| 306 | assumes a: "e \<Down> e'" and b: "\<Gamma> \<turnstile> e : T" | |
| 307 | shows "\<Gamma> \<turnstile> e' : T" | |
| 308 | using a b | |
| 309 | by (nominal_induct avoiding: \<Gamma> T rule: big.strong_induct) | |
| 310 | (force elim: t_App_elim t_Lam_elim simp add: ty.inject type_substitutivity)+ | |
| 22447 | 311 | |
| 22472 | 312 | 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 | 313 | 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 | 314 | 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 | 315 | shows "e\<^sub>1 = e\<^sub>2" | 
| 22472 | 316 | using a b | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 317 | 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 | 318 | 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 | 319 | 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 | 320 | thus "Lam [x].e = t\<^sub>2" by cases (simp_all add: trm.inject) | 
| 22447 | 321 | next | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 322 | 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 | 323 | 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 | 324 | 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 | 325 | 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 | 326 | 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 | 327 | 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 | 328 | 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 | 329 | 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 | 330 | 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 | 331 | then have "Lam [x]. f\<^sub>1 = Lam [x]. e\<^sub>1'" using ih1 by simp | 
| 22472 | 332 | then | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 333 | have "f\<^sub>1 = e\<^sub>1'" by (auto simp add: trm.inject alpha) | 
| 22472 | 334 | moreover | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 335 | 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 | 336 | 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 | 337 | thus "e' = t\<^sub>2" using ih3 by simp | 
| 25832 | 338 | qed | 
| 22447 | 339 | |
| 22472 | 340 | lemma reduces_evaluates_to_values: | 
| 28568 | 341 | assumes h: "t \<Down> t'" | 
| 22447 | 342 | shows "val t'" | 
| 28568 | 343 | using h by (induct) (auto) | 
| 22447 | 344 | |
| 25832 | 345 | (* Valuation *) | 
| 22447 | 346 | |
| 347 | nominal_primrec | |
| 29097 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
28568diff
changeset | 348 | V :: "ty \<Rightarrow> trm set" | 
| 
68245155eb58
Modified nominal_primrec to make it work with local theories, unified syntax
 berghofe parents: 
28568diff
changeset | 349 | where | 
| 25832 | 350 |   "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 | 351 | | "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 | 352 | by (rule TrueI)+ | 
| 22447 | 353 | |
| 22472 | 354 | lemma V_eqvt: | 
| 355 | fixes pi::"name prm" | |
| 80146 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 356 | assumes "x \<in> V T" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 357 | shows "(pi\<bullet>x) \<in> V T" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 358 | using assms | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 359 | proof (nominal_induct T arbitrary: pi x rule: ty.strong_induct) | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 360 | case (TVar nat) | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 361 | then show ?case | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 362 | by (simp add: val.eqvt) | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 363 | next | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 364 | case (Arrow T\<^sub>1 T\<^sub>2 pi x) | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 365 | obtain a e where ae: "x = Lam [a]. e" "\<forall>v\<in>V T\<^sub>1. \<exists>v'. e[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 366 | using Arrow.prems by auto | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 367 | have "\<exists>v'. (pi \<bullet> e)[(pi \<bullet> a)::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" if v: "v \<in> V T\<^sub>1" for v | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 368 | proof - | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 369 | have "rev pi \<bullet> v \<in> V T\<^sub>1" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 370 | by (simp add: Arrow.hyps(1) v) | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 371 | then obtain v' where "e[a::=(rev pi \<bullet> v)] \<Down> v'" "v' \<in> V T\<^sub>2" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 372 | using ae(2) by blast | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 373 | then have "(pi \<bullet> e)[(pi \<bullet> a)::=v] \<Down> pi \<bullet> v'" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 374 | by (metis (no_types, lifting) big.eqvt cons_eqvt nil_eqvt perm_pi_simp(1) perm_prod.simps psubst_eqvt) | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 375 | then show ?thesis | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 376 | using Arrow.hyps \<open>v' \<in> V T\<^sub>2\<close> by blast | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 377 | qed | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 378 | with ae show ?case by force | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 379 | qed | 
| 22472 | 380 | |
| 25832 | 381 | 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 | 382 | 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 | 383 | 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 | 384 | using h by (auto) | 
| 385 | ||
| 25832 | 386 | lemma V_arrow_elim_strong: | 
| 22447 | 387 | 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 | 388 | 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 | 389 | 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" | 
| 80146 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 390 | proof - | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 391 | obtain a t where "u = Lam [a].t" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 392 | and at: "\<And>v. v \<in> (V T\<^sub>1) \<Longrightarrow> \<exists> v'. t[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 393 | using V_arrow_elim_weak [OF assms] by metis | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 394 | obtain a'::name where a': "a'\<sharp>(a,t,c)" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 395 | by (meson exists_fresh fs_name_class.axioms) | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 396 | then have "u = Lam [a'].([(a, a')] \<bullet> t)" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 397 | unfolding \<open>u = Lam [a].t\<close> | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 398 | by (smt (verit) alpha fresh_atm fresh_prod perm_swap trm.inject(2)) | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 399 | moreover | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 400 | have "\<exists> v'. ([(a, a')] \<bullet> t)[a'::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" if "v \<in> (V T\<^sub>1)" for v | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 401 | proof - | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 402 | obtain v' where v': "t[a::=([(a, a')] \<bullet> v)] \<Down> v' \<and> v' \<in> V T\<^sub>2" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 403 | using V_eqvt \<open>v \<in> V T\<^sub>1\<close> at by blast | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 404 | then have "([(a, a')] \<bullet> t[a::=([(a, a')] \<bullet> v)]) \<Down> [(a, a')] \<bullet> v'" | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 405 | by (simp add: big.eqvt) | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 406 | then show ?thesis | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 407 | by (smt (verit) V_eqvt cons_eqvt nil_eqvt perm_prod.simps perm_swap(1) psubst_eqvt swap_simps(1) v') | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 408 | qed | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 409 | ultimately show thesis | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 410 | by (metis fresh_prod that a') | 
| 
cf11a7f0a5f0
Tidying up another Nominal example (SOS)
 paulson <lp15@cam.ac.uk> parents: 
66453diff
changeset | 411 | qed | 
| 22447 | 412 | |
| 25832 | 413 | lemma Vs_are_values: | 
| 414 | assumes a: "e \<in> V T" | |
| 22447 | 415 | shows "val e" | 
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 416 | using a by (nominal_induct T arbitrary: e rule: ty.strong_induct) (auto) | 
| 22447 | 417 | |
| 418 | lemma values_reduce_to_themselves: | |
| 25832 | 419 | assumes a: "val v" | 
| 22447 | 420 | shows "v \<Down> v" | 
| 25832 | 421 | using a by (induct) (auto) | 
| 22447 | 422 | |
| 25832 | 423 | lemma Vs_reduce_to_themselves: | 
| 424 | assumes a: "v \<in> V T" | |
| 425 | shows "v \<Down> v" | |
| 426 | using a by (simp add: values_reduce_to_themselves Vs_are_values) | |
| 22447 | 427 | |
| 63167 | 428 | text \<open>'\<theta> maps x to e' asserts that \<theta> substitutes x with e\<close> | 
| 22447 | 429 | abbreviation | 
| 25832 | 430 |   mapsto :: "(name\<times>trm) list \<Rightarrow> name \<Rightarrow> trm \<Rightarrow> bool" ("_ maps _ to _" [55,55,55] 55) 
 | 
| 22447 | 431 | where | 
| 25832 | 432 | "\<theta> maps x to e \<equiv> (lookup \<theta> x) = e" | 
| 22447 | 433 | |
| 434 | abbreviation | |
| 435 |   v_closes :: "(name\<times>trm) list \<Rightarrow> (name\<times>ty) list \<Rightarrow> bool" ("_ Vcloses _" [55,55] 55) 
 | |
| 436 | where | |
| 25832 | 437 | "\<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 | 438 | |
| 28568 | 439 | lemma case_distinction_on_context: | 
| 440 | fixes \<Gamma>::"(name\<times>ty) list" | |
| 441 | assumes asm1: "valid ((m,t)#\<Gamma>)" | |
| 442 | and asm2: "(n,U) \<in> set ((m,T)#\<Gamma>)" | |
| 443 | shows "(n,U) = (m,T) \<or> ((n,U) \<in> set \<Gamma> \<and> n \<noteq> m)" | |
| 444 | proof - | |
| 445 | from asm2 have "(n,U) \<in> set [(m,T)] \<or> (n,U) \<in> set \<Gamma>" by auto | |
| 446 | moreover | |
| 447 |   { assume eq: "m=n"
 | |
| 448 | assume "(n,U) \<in> set \<Gamma>" | |
| 449 | then have "\<not> n\<sharp>\<Gamma>" | |
| 450 | by (induct \<Gamma>) (auto simp add: fresh_list_cons fresh_prod fresh_atm) | |
| 451 | moreover have "m\<sharp>\<Gamma>" using asm1 by auto | |
| 452 | ultimately have False using eq by auto | |
| 453 | } | |
| 454 | ultimately show ?thesis by auto | |
| 455 | qed | |
| 456 | ||
| 22447 | 457 | lemma monotonicity: | 
| 458 | fixes m::"name" | |
| 459 | fixes \<theta>::"(name \<times> trm) list" | |
| 460 | assumes h1: "\<theta> Vcloses \<Gamma>" | |
| 461 | and h2: "e \<in> V T" | |
| 462 | and h3: "valid ((x,T)#\<Gamma>)" | |
| 463 | shows "(x,e)#\<theta> Vcloses (x,T)#\<Gamma>" | |
| 464 | proof(intro strip) | |
| 465 | fix x' T' | |
| 466 | assume "(x',T') \<in> set ((x,T)#\<Gamma>)" | |
| 467 | then have "((x',T')=(x,T)) \<or> ((x',T')\<in>set \<Gamma> \<and> x'\<noteq>x)" using h3 | |
| 468 | by (rule_tac case_distinction_on_context) | |
| 469 | moreover | |
| 470 |   { (* first case *)
 | |
| 471 | assume "(x',T') = (x,T)" | |
| 472 | then have "\<exists>e'. ((x,e)#\<theta>) maps x to e' \<and> e' \<in> V T'" using h2 by auto | |
| 473 | } | |
| 474 | moreover | |
| 475 |   { (* second case *)
 | |
| 476 | assume "(x',T') \<in> set \<Gamma>" and neq:"x' \<noteq> x" | |
| 477 | then have "\<exists>e'. \<theta> maps x' to e' \<and> e' \<in> V T'" using h1 by auto | |
| 478 | then have "\<exists>e'. ((x,e)#\<theta>) maps x' to e' \<and> e' \<in> V T'" using neq by auto | |
| 479 | } | |
| 480 | ultimately show "\<exists>e'. ((x,e)#\<theta>) maps x' to e' \<and> e' \<in> V T'" by blast | |
| 481 | qed | |
| 482 | ||
| 483 | lemma termination_aux: | |
| 484 | assumes h1: "\<Gamma> \<turnstile> e : T" | |
| 485 | and h2: "\<theta> Vcloses \<Gamma>" | |
| 486 | shows "\<exists>v. \<theta><e> \<Down> v \<and> v \<in> V T" | |
| 487 | using h2 h1 | |
| 26966 
071f40487734
made the naming of the induction principles consistent: weak_induct is
 urbanc parents: 
26806diff
changeset | 488 | 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 | 489 | 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 | 490 | 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 | 491 | 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 | 492 | 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 | 493 | 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 | 494 | 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 | 495 | 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 | 496 | 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 | 497 | 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 | 498 | where "v\<^sub>1 = Lam [x].e'" | 
| 22447 | 499 | 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 | 500 | 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 | 501 | 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 | 502 | 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 | 503 | 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 | 504 | 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 | 505 | 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 | 506 | 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 | 507 | 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 | 508 | 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 | 509 | then show "\<exists>v. \<theta><App e\<^sub>1 e\<^sub>2> \<Down> v \<and> v \<in> V T" using "(v)" by auto | 
| 22447 | 510 | next | 
| 511 | case (Lam x e \<Gamma> \<theta> T) | |
| 512 | 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 | 513 | 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 | 514 | have as\<^sub>2: "\<Gamma> \<turnstile> Lam [x].e : T" by fact | 
| 29300 | 515 | 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 | 516 | 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 | 517 | 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 | 518 | 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 | 519 | 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 | 520 | have "\<forall>v \<in> (V T\<^sub>1). \<exists>v'. (\<theta><e>)[x::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" | 
| 22447 | 521 | proof | 
| 522 | fix v | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 523 | 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 | 524 | 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 | 525 | 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 | 526 | 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 | 527 | then show "\<exists>v'. \<theta><e>[x::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" by auto | 
| 22447 | 528 | qed | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
49171diff
changeset | 529 | 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 | 530 | 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 | 531 | thus "\<exists>v. \<theta><Lam [x].e> \<Down> v \<and> v \<in> V T" using "(ii)" by auto | 
| 532 | next | |
| 25832 | 533 | case (Var x \<Gamma> \<theta> T) | 
| 534 | have "\<Gamma> \<turnstile> (Var x) : T" by fact | |
| 535 | then have "(x,T)\<in>set \<Gamma>" by (cases) (auto simp add: trm.inject) | |
| 41893 | 536 | with Var have "\<theta><Var x> \<Down> \<theta><Var x> \<and> \<theta><Var x>\<in> V T" | 
| 25832 | 537 | by (auto intro!: Vs_reduce_to_themselves) | 
| 538 | then show "\<exists>v. \<theta><Var x> \<Down> v \<and> v \<in> V T" by auto | |
| 539 | qed | |
| 22447 | 540 | |
| 541 | theorem termination_of_evaluation: | |
| 542 | assumes a: "[] \<turnstile> e : T" | |
| 543 | shows "\<exists>v. e \<Down> v \<and> val v" | |
| 544 | proof - | |
| 25832 | 545 | from a have "\<exists>v. []<e> \<Down> v \<and> v \<in> V T" by (rule termination_aux) (auto) | 
| 546 | thus "\<exists>v. e \<Down> v \<and> val v" using Vs_are_values by auto | |
| 22447 | 547 | qed | 
| 548 | ||
| 549 | end |