theory Lambda imports "Nominal" beginatom_decl namesection {* Alpha-Equated Lambda-Terms *}nominal_datatype lam = Var "name"| App "lam" "lam" | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._")section {* Capture-Avoiding Substitution *}consts subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam" ("_[_::=_]")nominal_primrec "(Var x)[y::=s] = (if x=y then s else (Var x))" "(App t1 t2)[y::=s] = App (t1[y::=s]) (t2[y::=s])" "x\<sharp>(y,s) \<Longrightarrow> (Lam [x].t)[y::=s] = Lam [x].(t[y::=s])"apply(finite_guess)+apply(rule TrueI)+apply(simp add: abs_fresh)+apply(fresh_guess)+donelemma subst_eqvt[eqvt]: fixes pi::"name prm" shows "pi\<bullet>(t1[x::=t2]) = (pi\<bullet>t1)[(pi\<bullet>x)::=(pi\<bullet>t2)]"by (nominal_induct t1 avoiding: x t2 rule: lam.strong_induct) (auto simp add: perm_bij fresh_atm fresh_bij)lemma forget: assumes a: "x\<sharp>L" shows "L[x::=P] = L" using a by (nominal_induct L avoiding: x P rule: lam.strong_induct) (auto simp add: abs_fresh fresh_atm)lemma fresh_fact: fixes z::"name" shows "\<lbrakk>z\<sharp>s; (z=y \<or> z\<sharp>t)\<rbrakk> \<Longrightarrow> z\<sharp>t[y::=s]"by (nominal_induct t avoiding: z y s rule: lam.strong_induct) (auto simp add: abs_fresh fresh_prod fresh_atm)lemma subst_rename: assumes a: "y\<sharp>t" shows "t[x::=s] = ([(y,x)]\<bullet>t)[y::=s]"using a by (nominal_induct t avoiding: x y s rule: lam.strong_induct) (auto simp add: calc_atm fresh_atm abs_fresh)text {* The purpose of the two lemmas below is to work around some quirks in Isabelle's handling of meta_quantifiers and meta_implications. *} lemma meta_impCE: assumes major: "P ==> PROP Q" and 1: "~ P ==> R" and 2: "PROP Q ==> R" shows Rproof (cases P) assume P then have "PROP Q" by (rule major) then show R by (rule 2)next assume "~ P" then show R by (rule 1)qeddeclare meta_allE [elim] and meta_impCE [elim!]end