Theory SN
theory SN
imports Lam_Funs
begin
text ‹Strong Normalisation proof from the Proofs and Types book›
section ‹Beta Reduction›
lemma subst_rename:
assumes a: "c♯t1"
shows "t1[a::=t2] = ([(c,a)]∙t1)[c::=t2]"
using a
by (nominal_induct t1 avoiding: a c t2 rule: lam.strong_induct)
(auto simp add: calc_atm fresh_atm abs_fresh)
lemma forget:
assumes a: "a♯t1"
shows "t1[a::=t2] = t1"
using a
by (nominal_induct t1 avoiding: a t2 rule: lam.strong_induct)
(auto simp add: abs_fresh fresh_atm)
lemma fresh_fact:
fixes a::"name"
assumes a: "a♯t1" "a♯t2"
shows "a♯t1[b::=t2]"
using a
by (nominal_induct t1 avoiding: a b t2 rule: lam.strong_induct)
(auto simp add: abs_fresh fresh_atm)
lemma fresh_fact':
fixes a::"name"
assumes a: "a♯t2"
shows "a♯t1[a::=t2]"
using a
by (nominal_induct t1 avoiding: a t2 rule: lam.strong_induct)
(auto simp add: abs_fresh fresh_atm)
lemma subst_lemma:
assumes a: "x≠y"
and b: "x♯L"
shows "M[x::=N][y::=L] = M[y::=L][x::=N[y::=L]]"
using a b
by (nominal_induct M avoiding: x y N L rule: lam.strong_induct)
(auto simp add: fresh_fact forget)
lemma id_subs:
shows "t[x::=Var x] = t"
by (nominal_induct t avoiding: x rule: lam.strong_induct)
(simp_all add: fresh_atm)
lemma lookup_fresh:
fixes z::"name"
assumes "z♯θ" "z♯x"
shows "z♯ lookup θ x"
using assms
by (induct rule: lookup.induct) (auto simp add: fresh_list_cons)
lemma lookup_fresh':
assumes "z♯θ"
shows "lookup θ z = Var z"
using assms
by (induct rule: lookup.induct)
(auto simp add: fresh_list_cons fresh_prod fresh_atm)
lemma psubst_subst:
assumes h:"c♯θ"
shows "(θ<t>)[c::=s] = ((c,s)#θ)<t>"
using h
by (nominal_induct t avoiding: θ c s rule: lam.strong_induct)
(auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh')
inductive
Beta :: "lam⇒lam⇒bool" (" _ ⟶⇩β _" [80,80] 80)
where
b1[intro!]: "s1 ⟶⇩β s2 ⟹ App s1 t ⟶⇩β App s2 t"
| b2[intro!]: "s1⟶⇩βs2 ⟹ App t s1 ⟶⇩β App t s2"
| b3[intro!]: "s1⟶⇩βs2 ⟹ Lam [a].s1 ⟶⇩β Lam [a].s2"
| b4[intro!]: "a♯s2 ⟹ App (Lam [a].s1) s2⟶⇩β (s1[a::=s2])"
equivariance Beta
nominal_inductive Beta
by (simp_all add: abs_fresh fresh_fact')
lemma beta_preserves_fresh:
fixes a::"name"
assumes a: "t⟶⇩β s"
shows "a♯t ⟹ a♯s"
using a
apply(nominal_induct t s avoiding: a rule: Beta.strong_induct)
apply(auto simp add: abs_fresh fresh_fact fresh_atm)
done
lemma beta_abs:
assumes a: "Lam [a].t⟶⇩β t'"
shows "∃t''. t'=Lam [a].t'' ∧ t⟶⇩β t''"
proof -
have "a♯Lam [a].t" by (simp add: abs_fresh)
with a have "a♯t'" by (simp add: beta_preserves_fresh)
with a show ?thesis
by (cases rule: Beta.strong_cases[where a="a" and aa="a"])
(auto simp add: lam.inject abs_fresh alpha)
qed
lemma beta_subst:
assumes a: "M ⟶⇩β M'"
shows "M[x::=N]⟶⇩β M'[x::=N]"
using a
by (nominal_induct M M' avoiding: x N rule: Beta.strong_induct)
(auto simp add: fresh_atm subst_lemma fresh_fact)
section ‹types›