Theory Subst_Term
theory Subst_Term
imports Chain
begin
locale substType =
fixes subst :: "'a::fs_name ⇒ name list ⇒ 'b::fs_name list ⇒ 'a" ("_[_::=_]" [80, 80 ,80] 130)
assumes eq[eqvt]: "⋀p::name prm. (p ∙ (M[xvec::=Tvec])) = ((p ∙ M)[(p ∙ xvec)::=(p ∙ Tvec)])"
and subst3: "⋀xvec Tvec T x. ⟦length xvec = length Tvec; distinct xvec; set(xvec) ⊆ supp(T); (x::name) ♯ T[xvec::=Tvec]⟧ ⟹ x ♯ Tvec"
and renaming: "⋀xvec Tvec p T. ⟦length xvec = length Tvec; (set p) ⊆ set xvec × set (p ∙ xvec);
distinctPerm p; (p ∙ xvec) ♯* T⟧ ⟹
T[xvec::=Tvec] = (p ∙ T)[(p ∙ xvec)::=Tvec]"
begin
lemma suppSubst:
fixes M :: 'a
and xvec :: "name list"
and Tvec :: "'b list"
shows "(supp(M[xvec::=Tvec])::name set) ⊆ ((supp M) ∪ (supp xvec) ∪ (supp Tvec))"
proof(auto simp add: eqvts supp_def)
fix x::name
let ?P = "λy. ([(x, y)] ∙ M)[([(x, y)] ∙ xvec)::=([(x, y)] ∙ Tvec)] ≠ M[xvec::=Tvec]"
let ?Q = "λy M. ([(x, y)] ∙ M) ≠ (M::'a)"
let ?R = "λy xvec. ([(x, y)] ∙ xvec) ≠ (xvec::name list)"
let ?S = "λy Tvec. ([(x, y)] ∙ Tvec) ≠ (Tvec::'b list)"
assume A: "finite {y. ?Q y M}" and B: "finite {y. ?R y xvec}" and C: "finite {y. ?S y Tvec}" and D: "infinite {y. ?P(y)}"
hence "infinite({y. ?P(y)} - {y. ?Q y M} - {y. ?R y xvec} - {y. ?S y Tvec})"
by(auto intro: Diff_infinite_finite)
hence "infinite({y. ?P(y) ∧ ¬(?Q y M) ∧ ¬ (?R y xvec) ∧ ¬ (?S y Tvec)})" by(simp add: set_diff_eq)
moreover have "{y. ?P(y) ∧ ¬(?Q y M) ∧ ¬ (?R y xvec) ∧ ¬ (?S y Tvec)} = {}" by auto
ultimately have "infinite {}" by(drule_tac Infinite_cong) auto
thus False by simp
qed
lemma subst2[intro]:
fixes x :: name
and M :: 'a
and xvec :: "name list"
and Tvec :: "'b list"
assumes "x ♯ M"
and "x ♯ xvec"
and "x ♯ Tvec"
shows "x ♯ M[xvec::=Tvec]"
using assms suppSubst
by(auto simp add: fresh_def)
lemma subst2Chain[intro]:
fixes yvec :: "name list"
and M :: 'a
and xvec :: "name list"
and Tvec :: "'b list"
assumes "yvec ♯* M"
and "yvec ♯* xvec"
and "yvec ♯* Tvec"
shows "yvec ♯* M[xvec::=Tvec]"
using assms
by(induct yvec) auto
lemma fs[simp]: "finite ((supp subst)::name set)"
by(simp add: supp_def perm_fun_def eqvts)
lemma subst3Chain:
fixes xvec :: "name list"
and Tvec :: "'b list"
and Xs :: "name set"
and T :: 'a
assumes "length xvec = length Tvec"
and "distinct xvec"
and "set xvec ⊆ supp T"
and "Xs ♯* T[xvec::=Tvec]"
shows "Xs ♯* Tvec"
using assms
by(auto intro: subst3 simp add: fresh_star_def)
lemma subst4Chain:
fixes xvec :: "name list"
and Tvec :: "'b list"
and T :: 'a
assumes "length xvec = length Tvec"
and "distinct xvec"
and "xvec ♯* Tvec"
shows "xvec ♯* T[xvec::=Tvec]"
proof -
obtain p where "((p::name prm) ∙ (xvec::name list)) ♯* T" and "(p ∙ xvec) ♯* xvec"
and S: "(set p) ⊆ set xvec × set (p ∙ xvec)"
and "distinctPerm p"
by(rule_tac xvec=xvec and c="(T, xvec)" in name_list_avoiding) auto
from ‹length xvec = length Tvec› have "length(p ∙ xvec) = length Tvec" by simp
moreover from ‹(p ∙ xvec) ♯* T› have "(p ∙ p ∙ xvec) ♯* (p ∙ T)"
by(simp add: pt_fresh_star_bij[OF pt_name_inst, OF at_name_inst])
with ‹distinctPerm p› have "xvec ♯* (p ∙ T)" by simp
ultimately have "(set xvec) ♯* (p ∙ T)[(p ∙ xvec)::=Tvec]" using ‹xvec ♯* Tvec› ‹(p ∙ xvec) ♯* xvec›
by auto
thus ?thesis using ‹length xvec = length Tvec› ‹distinct xvec› S ‹(p ∙ xvec) ♯* T› ‹distinctPerm p›
by(simp add: renaming)
qed
definition seqSubst :: "'a ⇒ (name list × 'b list) list ⇒ 'a" ("_[<_>]" [80, 80] 130)
where "M[<σ>] ≡ foldl (λN. λ(xvec, Tvec). N[xvec::=Tvec]) M σ"
lemma seqSubstNil[simp]:
"seqSubst M [] = M"
by(simp add: seqSubst_def)
lemma seqSubstCons[simp]:
shows "seqSubst M ((xvec, Tvec)#σ) = seqSubst(M[xvec::=Tvec]) σ"
by(simp add: seqSubst_def)
lemma seqSubstTermAppend[simp]:
shows "seqSubst M (σ@σ') = seqSubst (seqSubst M σ) σ'"
by(induct σ) (auto simp add: seqSubst_def)
definition wellFormedSubst :: "(('d::fs_name) list × ('e::fs_name) list) list ⇒ bool" where "wellFormedSubst σ = ((filter (λ(xvec, Tvec). ¬(length xvec = length Tvec ∧ distinct xvec)) σ) = [])"
lemma wellFormedSubstEqvt[eqvt]:
fixes σ :: "(('d::fs_name) list × ('e::fs_name) list) list"
and p :: "name prm"
shows "p ∙ (wellFormedSubst σ) = wellFormedSubst(p ∙ σ)"
by(induct σ arbitrary: p) (auto simp add: eqvts wellFormedSubst_def)
lemma wellFormedSimp[simp]:
fixes σ :: "(('d::fs_name) list × ('e::fs_name) list) list"
and p :: "name prm"
shows "wellFormedSubst(p ∙ σ) = wellFormedSubst σ"
by(induct σ) (auto simp add: eqvts wellFormedSubst_def)
lemma wellFormedNil[simp]:
"wellFormedSubst []"
by(simp add: wellFormedSubst_def)
lemma wellFormedCons[simp]:
shows "wellFormedSubst((xvec, Tvec)#σ) = (length xvec = length Tvec ∧ distinct xvec ∧ wellFormedSubst σ)"
by(simp add: wellFormedSubst_def) auto
lemma wellFormedAppend[simp]:
fixes σ :: "(('d::fs_name) list × ('e::fs_name) list) list"
and σ' :: "(('d::fs_name) list × ('e::fs_name) list) list"
shows "wellFormedSubst(σ@σ') = (wellFormedSubst σ ∧ wellFormedSubst σ')"
by(simp add: wellFormedSubst_def)
lemma seqSubst2[intro]:
fixes σ :: "(name list × 'b list) list"
and T :: 'a
and x :: name
assumes "x ♯ σ"
and "x ♯ T"
shows "x ♯ T[<σ>]"
using assms
by(induct σ arbitrary: T) (clarsimp | blast)+
lemma seqSubst2Chain[intro]:
fixes σ :: "(name list × 'b list) list"
and T :: 'a
and xvec :: "name list"
assumes "xvec ♯* σ"
and "xvec ♯* T"
shows "xvec ♯* T[<σ>]"
using assms
by(induct xvec) auto
end
end