Theory Strong_Late_Bisim_Subst_SC
theory Strong_Late_Bisim_Subst_SC
imports Strong_Late_Bisim_Subst_Pres Strong_Late_Bisim_SC
begin
lemma matchId:
fixes a :: name
and P :: pi
shows "[a⌢a]P ∼⇧s P"
by(auto simp add: substClosed_def intro: Strong_Late_Bisim_SC.matchId)
lemma mismatchNil:
fixes a :: name
and P :: pi
shows "[a≠a]P ∼⇧s 𝟬"
by(auto simp add: substClosed_def intro: Strong_Late_Bisim_SC.mismatchNil)
lemma scopeFresh:
fixes P :: pi
and x :: name
assumes xFreshP: "x ♯ P"
shows "<νx>P ∼⇧s P"
proof(auto simp add: substClosed_def)
fix s :: "(name × name) list"
have "∃c::name. c ♯ (P, s)" by(blast intro: name_exists_fresh)
then obtain c::name where cFreshP: "c ♯ P" and cFreshs: "c ♯ s" by(force simp add: fresh_prod)
have "<νx>P = <νc>P"
proof -
from cFreshP have "<νx>P = <νc>([(x, c)] ∙ P)" by(simp add: alphaRes)
with cFreshP xFreshP show ?thesis by(simp add: name_fresh_fresh)
qed
with cFreshP cFreshs show "(<νx>P)[<s>] ∼ P[<s>]"
by(force intro: Strong_Late_Bisim_SC.scopeFresh)
qed
lemma resComm:
fixes P :: pi
and x :: name
and y :: name
shows "<νx><νy>P ∼⇧s <νy><νx>P"
proof(cases "x=y")
assume xeqy: "x=y"
have "P ∼⇧s P" by(rule Strong_Late_Bisim_Subst.reflexive)
hence "<νx>P ∼⇧s <νx>P" by(rule resPres)
hence "<νx><νx>P ∼⇧s <νx><νx>P" by(rule resPres)
with xeqy show ?thesis by simp
next
assume xineqy: "x ≠ y"
show ?thesis
proof(auto simp add: substClosed_def)
fix s::"(name × name) list"
have "∃c::name. c ♯ (P, s, y)" by(blast intro: name_exists_fresh)
then obtain c::name where cFreshP: "c ♯ P" and cFreshs: "c ♯ s" and cineqy: "c ≠ y"
by(force simp add: fresh_prod)
have "∃d::name. d ♯ (P, s, c, x, y)" by (blast intro: name_exists_fresh)
then obtain d::name where dFreshP: "d ♯ P" and dFreshs: "d ♯ s" and dineqc: "d ≠ c"
and dineqx: "d ≠ x" and dineqy: "d ≠ y"
by(force simp add: fresh_prod)
have "<νx><νy>P = <νc><νd>([(x, c)] ∙ [(y, d)] ∙ P)"
proof -
from cineqy cFreshP have cFreshyP: "c ♯ <νy>P" by(simp add: name_fresh_abs)
from dFreshP have "<νy>P = <νd>([(y, d)] ∙ P)" by(rule alphaRes)
moreover from cFreshyP have "<νx><νy>P = <νc>([(x, c)] ∙ (<νy>P))" by(rule alphaRes)
ultimately show ?thesis using dineqc dineqx by(simp add: name_calc)
qed
moreover have "<νy><νx>P = <νd><νc>([(x, c)] ∙ [(y, d)] ∙ P)"
proof -
from dineqx dFreshP have dFreshxP: "d ♯ <νx>P" by(simp add: name_fresh_abs)
from cFreshP have "<νx>P = <νc>([(x, c)] ∙ P)" by(rule alphaRes)
moreover from dFreshxP have "<νy><νx>P = <νd>([(y, d)] ∙ (<νx>P))" by(rule alphaRes)
ultimately have "<νy><νx>P = <νd><νc>([(y, d)] ∙ [(x, c)] ∙ P)" using dineqc cineqy
by(simp add: name_calc)
thus ?thesis using dineqx dineqc cineqy xineqy
by(subst name_perm_compose, simp add: name_calc)
qed
ultimately show "(<νx><νy>P)[<s>] ∼ (<νy><νx>P)[<s>]" using cFreshs dFreshs
by(force intro: Strong_Late_Bisim_SC.resComm)
qed
qed
lemma sumZero:
fixes P :: pi
shows "P ⊕ 𝟬 ∼⇧s P"
by(force simp add: substClosed_def intro: Strong_Late_Bisim_SC.sumZero)
lemma sumSym:
fixes P :: pi
and Q :: pi
shows "P ⊕ Q ∼⇧s Q ⊕ P"
by(force simp add: substClosed_def intro: Strong_Late_Bisim_SC.sumSym)
lemma sumAssoc:
fixes P :: pi
and Q :: pi
and R :: pi
shows "(P ⊕ Q) ⊕ R ∼⇧s P ⊕ (Q ⊕ R)"
by(force simp add: substClosed_def intro: Strong_Late_Bisim_SC.sumAssoc)
lemma sumRes:
fixes P :: pi
and Q :: pi
and x :: name
shows "<νx>(P ⊕ Q) ∼⇧s <νx>P ⊕ <νx>Q"
proof(auto simp add: substClosed_def)
fix s :: "(name × name) list"
have "∃c::name. c ♯ (P, Q, s)" by(blast intro: name_exists_fresh)
then obtain c::name where cFreshP: "c ♯ P" and cFreshQ: "c ♯ Q" and cFreshs: "c ♯ s"
by(force simp add: fresh_prod)
have "<νx>(P ⊕ Q) = <νc>(([(x, c)] ∙ P) ⊕ ([(x, c)] ∙ Q))"
proof -
from cFreshP cFreshQ have "c ♯ P ⊕ Q" by simp
hence "<νx>(P ⊕ Q) = <νc>([(x, c)] ∙ (P ⊕ Q))" by(simp add: alphaRes)
thus ?thesis by(simp add: name_fresh_fresh)
qed
moreover from cFreshP have "<νx>P = <νc>([(x, c)] ∙ P)" by(simp add: alphaRes)
moreover from cFreshQ have "<νx>Q = <νc>([(x, c)] ∙ Q)" by(simp add: alphaRes)
ultimately show "(<νx>(P ⊕ Q))[<s>] ∼ (<νx>P)[<s>] ⊕ (<νx>Q)[<s>]" using cFreshs
by(force intro: Strong_Late_Bisim_SC.sumRes)
qed
lemma scopeExtSum:
fixes P :: pi
and Q :: pi
and x :: name
assumes xFreshP: "x ♯ P"
shows "<νx>(P ⊕ Q) ∼⇧s P ⊕ <νx>Q"
proof(auto simp add: substClosed_def)
fix s :: "(name × name) list"
have "∃c::name. c ♯ (P, Q, s)" by(blast intro: name_exists_fresh)
then obtain c::name where cFreshP: "c ♯ P" and cFreshQ: "c ♯ Q" and cFreshs: "c ♯ s"
by(force simp add: fresh_prod)
have "<νx>(P ⊕ Q) = <νc>(P ⊕ ([(x, c)] ∙ Q))"
proof -
from cFreshP cFreshQ have "c ♯ P ⊕ Q" by simp
hence "<νx>(P ⊕ Q) = <νc>([(x, c)] ∙ (P ⊕ Q))" by(simp add: alphaRes)
with xFreshP cFreshP show ?thesis by(simp add: name_fresh_fresh)
qed
moreover from cFreshQ have "<νx>Q = <νc>([(x, c)] ∙ Q)" by(simp add: alphaRes)
ultimately show "(<νx>(P ⊕ Q))[<s>] ∼ P[<s>] ⊕ (<νx>Q)[<s>]" using cFreshs cFreshP
by(force intro: Strong_Late_Bisim_SC.scopeExtSum)
qed
lemma parZero:
fixes P :: pi
shows "P ∥ 𝟬 ∼⇧s P"
by(force simp add: substClosed_def intro: Strong_Late_Bisim_SC.parZero)
lemma parSym:
fixes P :: pi
and Q :: pi
shows "P ∥ Q ∼⇧s Q ∥ P"
by(force simp add: substClosed_def intro: Strong_Late_Bisim_SC.parSym)
lemma parAssoc:
fixes P :: pi
and Q :: pi
and R :: pi
shows "(P ∥ Q) ∥ R ∼⇧s P ∥ (Q ∥ R)"
by(force simp add: substClosed_def intro: Strong_Late_Bisim_SC.parAssoc)
lemma scopeExtPar:
fixes P :: pi
and Q :: pi
and x :: name
assumes xFreshP: "x ♯ P"
shows "<νx>(P ∥ Q) ∼⇧s P ∥ <νx>Q"
proof(auto simp add: substClosed_def)
fix s :: "(name × name) list"
have "∃c::name. c ♯ (P, Q, s)" by(blast intro: name_exists_fresh)
then obtain c::name where cFreshP: "c ♯ P" and cFreshQ: "c ♯ Q" and cFreshs: "c ♯ s"
by(force simp add: fresh_prod)
have "<νx>(P ∥ Q) = <νc>(P ∥ ([(x, c)] ∙ Q))"
proof -
from cFreshP cFreshQ have "c ♯ P ∥ Q" by simp
hence "<νx>(P ∥ Q) = <νc>([(x, c)] ∙ (P ∥ Q))" by(simp add: alphaRes)
with xFreshP cFreshP show ?thesis by(simp add: name_fresh_fresh)
qed
moreover from cFreshQ have "<νx>Q = <νc>([(x, c)] ∙ Q)" by(simp add: alphaRes)
ultimately show "(<νx>(P ∥ Q))[<s>] ∼ P[<s>] ∥ (<νx>Q)[<s>]" using cFreshs cFreshP
by(force intro: Strong_Late_Bisim_SC.scopeExtPar)
qed
lemma scopeExtPar':
fixes P :: pi
and Q :: pi
and x :: name
assumes xFreshP: "x ♯ Q"
shows "<νx>(P ∥ Q) ∼⇧s (<νx>P) ∥ Q"
proof -
have "<νx>(P ∥ Q) ∼⇧s <νx>(Q ∥ P)" by(blast intro: parSym resPres)
moreover from xFreshP have "<νx>(Q ∥ P) ∼⇧s Q ∥ <νx>P" by(rule scopeExtPar)
moreover have "Q ∥ <νx>P ∼⇧s (<νx>P) ∥ Q" by(rule parSym)
ultimately show ?thesis by (blast intro: transitive)
qed
lemma bangSC:
fixes P :: pi
shows "!P ∼⇧s P ∥ !P"
by(auto simp add: substClosed_def intro: Strong_Late_Bisim_SC.bangSC)
lemma nilRes:
fixes x :: name
shows "<νx>𝟬 ∼⇧s 𝟬"
proof(auto simp add: substClosed_def)
fix σ::"(name × name) list"
obtain y::name where "y ♯ σ"
by(generate_fresh "name") auto
have "<νy>𝟬 ∼ 𝟬" by (rule Strong_Late_Bisim_SC.nilRes)
with ‹y ♯ σ› have "(<νy>𝟬)[<σ>] ∼ 𝟬" by simp
thus "(<νx>𝟬)[<σ>] ∼ 𝟬"
by(subst alphaRes[where c=y]) auto
qed
lemma resTau:
fixes x :: name
and P :: pi
shows "<νx>(τ.(P)) ∼⇧s τ.(<νx>P)"
proof(auto simp add: substClosed_def)
fix σ::"(name × name) list"
obtain y::name where "y ♯ P" and "y ♯ σ"
by(generate_fresh "name", auto)
have "<νy>(τ.(([(x, y)] ∙ P)[<σ>])) ∼ τ.(<νy>(([(x, y)] ∙ P)[<σ>]))"
by(rule resTau)
with ‹y ♯ σ› have "(<νy>(τ.([(x, y)] ∙ P)))[<σ>] ∼ (τ.(<νy>([(x, y)] ∙ P)))[<σ>]"
by simp
with ‹y ♯ P› show "(<νx>τ.(P))[<σ>] ∼ τ.((<νx>P)[<σ>])"
apply(subst alphaRes[where c=y])
apply simp
apply(subst alphaRes[where c=y and a=x])
by simp+
qed
lemma resOutput:
fixes x :: name
and a :: name
and b :: name
and P :: pi
assumes "x ≠ a"
and "x ≠ b"
shows "<νx>(a{b}.(P)) ∼⇧s a{b}.(<νx>P)"
proof(auto simp add: substClosed_def)
fix σ::"(name × name) list"
obtain y::name where "y ♯ P" and "y ♯ σ" and "y ≠ a" and "y ≠ b"
by(generate_fresh "name", auto)
have "<νy>((seq_subst_name a σ){seq_subst_name b σ}.(([(x, y)] ∙ P)[<σ>])) ∼ seq_subst_name a σ{seq_subst_name b σ}.(<νy>(([(x, y)] ∙ P)[<σ>]))"
using ‹y ≠ a› ‹y ≠ b› ‹y ♯ σ› freshSeqSubstName
by(rule_tac resOutput) auto
with ‹y ♯ σ› have "(<νy>(a{b}.([(x, y)] ∙ P)))[<σ>] ∼ (a{b}.(<νy>([(x, y)] ∙ P)))[<σ>]"
by simp
with ‹y ♯ P› ‹y ≠ a› ‹y ≠ b› ‹x ≠ a› ‹x ≠ b› show "(<νx>a{b}.(P))[<σ>] ∼ seq_subst_name a σ{seq_subst_name b σ}.((<νx>P)[<σ>])"
apply(subst alphaRes[where c=y])
apply simp
apply(subst alphaRes[where c=y and a=x])
by simp+
qed
lemma resInput:
fixes x :: name
and a :: name
and b :: name
and P :: pi
assumes "x ≠ a"
and "x ≠ y"
shows "<νx>(a<y>.(P)) ∼⇧s a<y>.(<νx>P)"
proof(auto simp add: substClosed_def)
fix σ::"(name × name) list"
obtain x'::name where "x' ♯ P" and "x' ♯ σ" and "x' ≠ a" and "x' ≠ x" and "x' ≠ y"
by(generate_fresh "name", auto)
obtain y'::name where "y' ♯ P" and "y' ♯ σ" and "y' ≠ a" and "y' ≠ x" and "y' ≠ y" and "x' ≠ y'"
by(generate_fresh "name", auto)
have "<νx'>((seq_subst_name a σ)<y'>.(([(y, y')] ∙ [(x, x')] ∙ P)[<σ>])) ∼ seq_subst_name a σ<y'>.(<νx'>(([(y, y')] ∙ [(x, x')] ∙ P)[<σ>]))"
using ‹x' ≠ a› ‹x' ≠ y'› ‹x' ♯ σ› ‹y' ♯ σ› freshSeqSubstName
by(rule_tac resInput) auto
with ‹x' ♯ σ› ‹y' ♯ σ› have "(<νx'>(a<y'>.([(y, y')] ∙ [(x, x')] ∙ P)))[<σ>] ∼ (a<y'>.(<νx'>([(y, y')] ∙ [(x, x')] ∙ P)))[<σ>]"
by simp
with ‹x' ♯ P› ‹y' ≠ x› ‹x' ≠ y› ‹y' ♯ P› ‹x' ≠ y'› ‹x' ≠ a› ‹y' ≠ a› ‹x ≠ a› ‹x ≠ y› show "(<νx>a<y>.(P))[<σ>] ∼ a<y>.(<νx>P)[<σ>]"
apply(subst alphaInput[where c=y'])
apply simp
apply(subst alphaRes[where c=x'])
apply(simp add: abs_fresh fresh_left calc_atm)
apply(simp add: eqvts calc_atm)
apply(subst alphaRes[where c=x' and a=x])
apply simp
apply(subst alphaInput[where c=y' and x=y])
apply(simp add: abs_fresh fresh_left calc_atm)
apply(simp add: eqvts calc_atm)
apply(subst perm_compose)
by(simp add: eqvts calc_atm)
qed
lemma bisimSubstStructCong:
fixes P :: pi
and Q :: pi
assumes "P ≡⇩s Q"
shows "P ∼⇧s Q"
using assms
apply(induct rule: structCong.induct)
by(auto intro: reflexive symmetric transitive sumSym sumAssoc sumZero parSym parAssoc parZero
nilRes resComm resInput resOutput resTau sumRes scopeExtPar bangSC matchId mismatchId)
end