Theory Weak_Early_Cong_Subst_Pres

(* 
   Title: The pi-calculus   
   Author/Maintainer: Jesper Bengtson (jebe.dk), 2012
*)
theory Weak_Early_Cong_Subst_Pres
  imports Weak_Early_Cong_Subst Weak_Early_Cong_Pres
begin

lemma weakCongStructCong:
  fixes P :: pi
  and   Q :: pi

  assumes "P s Q"

  shows "P s Q"
using assms
by(metis earlyCongStructCong strongEqWeakCong)


lemma tauPres:
  fixes P :: pi
  and   Q :: pi
  
  assumes "P s Q"

  shows "τ.(P) s τ.(Q)"
using assms
by(auto simp add: weakCongruenceSubst_def intro: Weak_Early_Cong_Pres.tauPres)

lemma inputPres:
  fixes P :: pi
  and   Q :: pi
  and   a :: name
  and   x :: name

  assumes PeqQ: "P s Q"

  shows "a<x>.P s a<x>.Q"
proof(auto simp add: weakCongruenceSubst_def)
  fix s::"(name × name) list"

  from congruenceWeakBisim have Input: "P Q a x s. P[<s>] s Q[<s>]; x  s  (a<x>.P)[<s>]  (a<x>.Q)[<s>]"
    apply(auto simp add: weakCongruenceSubst_def weakCongruence_def)
    apply(rule Weak_Early_Step_Sim_Pres.inputPres, auto)
    apply(erule_tac x="[(x, y)]" in allE, auto)
    apply(rule Weak_Early_Step_Sim_Pres.inputPres, auto)
    by(erule_tac x="[(x, y)]" in allE, auto)

  then obtain c::name where cFreshP: "c  P" and cFreshQ: "c  Q" and cFreshs: "c  s"
    by(force intro: name_exists_fresh[of "(P, Q, s)"])

  from PeqQ have "P[<([(x, c)]  s)>] s Q[<([(x, c)]  s)>]" by(rule partUnfold)
  hence "([(x, c)]  P[<([(x, c)]  s)>]) s  ([(x, c)]  Q[<([(x, c)]  s)>])" by(rule Weak_Early_Cong_Subst.eqvtI)
  hence "([(x, c)]  P)[<s>] s ([(x, c)]  Q)[<s>]" by simp
  hence "(a<c>.([(x, c)]  P))[<s>]  (a<c>.([(x, c)]  Q))[<s>]" using cFreshs by(rule Input)

  moreover from cFreshP cFreshQ have "a<x>.P = a<c>.([(x, c)]  P)" and "a<x>.Q = a<c>.([(x, c)]  Q)"
    by(simp add: Agent.alphaInput)+

  ultimately show "(a<x>.P)[<s>]  (a<x>.Q)[<s>]" by simp
qed

lemma outputPres:
  fixes P :: pi
  and   Q :: pi
  
  assumes "P s Q"

  shows "a{b}.P s a{b}.Q"
using assms
by(auto simp add: weakCongruenceSubst_def intro: Weak_Early_Cong_Pres.outputPres)

lemma matchPres:
  fixes P :: pi
  and   Q :: pi
  and   a :: name
  and   b :: name

  assumes "P s Q"

  shows "[ab]P s [ab]Q"
using assms
by(auto simp add: weakCongruenceSubst_def intro: Weak_Early_Cong_Pres.matchPres)

lemma mismatchPres:
  fixes P :: pi
  and   Q :: pi
  and   a :: name
  and   b :: name

  assumes "P s Q"

  shows "[ab]P s [ab]Q"
using assms
by(auto simp add: weakCongruenceSubst_def intro: Weak_Early_Cong_Pres.mismatchPres)

lemma sumPres:
  fixes P :: pi
  and   Q :: pi
  and   R :: pi

  assumes "P s Q"

  shows "P  R s Q  R"
using assms
by(auto simp add: weakCongruenceSubst_def intro: Weak_Early_Cong_Pres.sumPres)

lemma parPres:
  fixes P :: pi
  and   Q :: pi
  and   R :: pi

  assumes "P s Q"

  shows "P  R s Q  R"
using assms
by(auto simp add: weakCongruenceSubst_def intro: Weak_Early_Cong_Pres.parPres)

lemma resPres:
  fixes P :: pi
  and   Q :: pi
  and   x :: name

  assumes PeqQ: "P s Q"
  
  shows "x>P s x>Q"
proof(auto simp add: weakCongruenceSubst_def)
  fix s::"(name × name) list"

  have Goal: "P Q x s. P[<s>] ↝«weakBisim» Q[<s>]; x  s  (x>P)[<s>] ↝«weakBisim» (x>Q)[<s>]"
    by(force intro: Weak_Early_Step_Sim_Pres.resPres Weak_Early_Bisim_Pres.resPres Weak_Early_Bisim.eqvt)
  
  then obtain c::name where cFreshP: "c  P" and cFreshQ: "c  Q" and cFreshs: "c  s"
    by(force intro: name_exists_fresh[of "(P, Q, s)"])

  from PeqQ have "P[<([(x, c)]  s)>] ↝«weakBisim» Q[<([(x, c)]  s)>]" and 
                 "Q[<([(x, c)]  s)>] ↝«weakBisim» P[<([(x, c)]  s)>]"
    by(force simp add: weakCongruenceSubst_def weakCongruence_def)+

  hence "([(x, c)]  (P[<([(x, c)]  s)>])) ↝«weakBisim» ([(x, c)]  (Q[<([(x, c)]  s)>]))" and 
        "([(x, c)]  (Q[<([(x, c)]  s)>])) ↝«weakBisim» ([(x, c)]  (P[<([(x, c)]  s)>]))"
    by(blast intro: Weak_Early_Step_Sim.eqvtI Weak_Early_Bisim.eqvt)+

  hence "([(x, c)]  P)[<s>] ↝«weakBisim» ([(x, c)]  Q)[<s>]" and
        "([(x, c)]  Q)[<s>] ↝«weakBisim» ([(x, c)]  P)[<s>]" by simp+

  with cFreshs have "(c>([(x, c)]  P))[<s>] ↝«weakBisim» (c>([(x, c)]  Q))[<s>]" and
                    "(c>([(x, c)]  Q))[<s>] ↝«weakBisim» (c>([(x, c)]  P))[<s>]"
    by(blast intro: Goal)+

  moreover from cFreshP cFreshQ have "x>P = c>([(x, c)]  P)" and "x>Q = c>([(x, c)]  Q)"
    by(simp add: alphaRes)+

  ultimately show "(x>P)[<s>]  (x>Q)[<s>]"
    by(simp add: weakCongruence_def)
qed

lemma bangPres:
  fixes P :: pi
  and   Q :: pi
  
  assumes "P s Q"

  shows "!P s !Q"
using assms
by(auto simp add: weakCongruenceSubst_def intro: Weak_Early_Cong_Pres.bangPres)

end