Theory Weak_Relations


subsection ‹Weak Simulation›

theory Weak_Relations
imports
  Weak_Transition_Systems
  Strong_Relations
begin

context lts_tau
begin

definition weak_simulation :: 
  ('s  's  bool)  bool
where
  weak_simulation R   p q. R p q  
    ( p' a. p a p'  ( q'. R p' q'
       (q ⇒^a q')))

text ‹Note: Isabelle won't finish the proofs needed for the introduction of the following
  coinductive predicate if it unfolds the abbreviation of @{text ‹⇒^›}. Therefore we use
  @{text ‹⇒^^›} as a barrier. There is no mathematical purpose in this.›

definition weak_step_tau2 :: 's  'a  's  bool
    (‹_ ⇒^^ _  _› [70, 70, 70] 80)
where [simp]:
  (p ⇒^^ a q)  p ⇒^a q

coinductive greatest_weak_simulation :: 
  's  's  bool
where
  ( p' a. p a p'  ( q'. greatest_weak_simulation p' q'  (q ⇒^^ a q')))
   greatest_weak_simulation p q
  
lemma weak_sim_ruleformat:
assumes weak_simulation R
  and R p q
shows
  p a p'  ¬tau a  ( q'. R p' q'  (q a q'))
  p a p'   tau a  ( q'. R p' q'  (q ⟼* tau q'))
  using assms unfolding weak_simulation_def by (blast+)

abbreviation weakly_simulated_by :: 's  's  bool (‹_ ⊑ws  _› [60, 60] 65)
  where weakly_simulated_by p q   R . weak_simulation R  R p q

lemma weaksim_greatest:
  shows weak_simulation (λ p q . p ⊑ws q)
  unfolding weak_simulation_def
  by (metis (no_types, lifting))


lemma gws_is_weak_simulation:
  shows weak_simulation greatest_weak_simulation
  unfolding weak_simulation_def
proof safe
  fix p q p' a
  assume ih:
    greatest_weak_simulation p q
    p a  p'
  hence (x xa. p x xa  (q'. q ⇒^^ x  q'  greatest_weak_simulation xa q'))
    by (meson greatest_weak_simulation.simps)
  then obtain q' where q ⇒^^ a  q'  greatest_weak_simulation p' q' using ih by blast
  thus q'. greatest_weak_simulation p' q'  q ⇒^a  q'
    unfolding weak_step_tau2_def by blast
qed

lemma weakly_sim_by_implies_gws:
  assumes p ⊑ws q
  shows greatest_weak_simulation p q
  using assms
proof coinduct
  case (greatest_weak_simulation p q)
  then obtain R where weak_simulation R R p q
    unfolding weak_simulation_def by blast
  with weak_sim_ruleformat[OF this] show ?case
    unfolding weak_step_tau2_def
    by metis
qed

lemma gws_eq_weakly_sim_by:
  shows p ⊑ws q = greatest_weak_simulation p q
  using weakly_sim_by_implies_gws gws_is_weak_simulation by blast

lemma steps_retain_weak_sim:
assumes 
  weak_simulation R
  R p q
  p ⟼*A  p'
   a . tau a  A a
shows q'. R p' q'  q ⟼*A  q'
  using assms(3,2,4) proof (induct)
  case (refl p' A)
  hence R p' q   q ⟼* A  q using assms(2) by (simp add: steps.refl)
  then show ?case by blast
next
  case (step p A p' a p'')
  then obtain q' where q': R p' q' q ⟼* A  q' by blast
  obtain q'' where q'':
    R p'' q'' (¬ tau a  q' a  q'')  (tau a  q' ⟼* tau  q'')
    using `weak_simulation R` q'(1) step(3) unfolding weak_simulation_def by blast
  have q' ⟼* A  q''
    using q''(2) steps_spec[of q'] step(4) step(6) weak_steps[of q' a q''] by blast
  hence q ⟼* A  q'' using steps_concat[OF _ q'(2)] by blast
  thus ?case using q''(1) by blast
qed

lemma weak_sim_weak_premise:
  weak_simulation R =
    ( p q . R p q  
      ( p' a. p ⇒^a p'  ( q'. R p' q'  q ⇒^a q')))
proof 
  assume  p q . R p q  (p' a. p ⇒^a  p'  (q'. R p' q'  q ⇒^a  q'))
  thus weak_simulation R
    unfolding weak_simulation_def using step_weak_step_tau by simp
next
  assume ws: weak_simulation R
  show p q. R p q  (p' a. p ⇒^a  p'  (q'. R p' q'  q ⇒^a  q'))
  proof safe
    fix p q p' a pq1 pq2
    assume case_assms:
      R p q
      p ⟼* tau  pq1
      pq1 a  pq2
      pq2 ⟼* tau  p'
    then obtain q' where q'_def: q ⟼* tau  q' R pq1 q'
      using steps_retain_weak_sim[OF ws] by blast
    then moreover obtain q'' where q''_def: R pq2 q'' q' ⇒^a  q''
      using ws case_assms(3) unfolding weak_simulation_def by blast
    then moreover obtain q''' where q''_def: R p' q''' q'' ⟼* tau  q'''
      using case_assms(4) steps_retain_weak_sim[OF ws] by blast
    ultimately show  q'''. R p' q'''  q ⇒^a  q''' using weak_step_extend by blast
  next
    fix p q p' a
    assume
      R p q
      p ⟼* tau  p'
      q'. R p' q'  q ⇒^a  q'
      tau a
    thus False
      using steps_retain_weak_sim[OF ws] by blast
  next
    ―‹case identical to first case›
    fix p q p' a pq1 pq2
    assume case_assms:
      R p q
      p ⟼* tau  pq1
      pq1 a  pq2
      pq2 ⟼* tau  p'
    then obtain q' where q'_def: q ⟼* tau  q' R pq1 q'
      using steps_retain_weak_sim[OF ws] by blast
    then moreover obtain q'' where q''_def: R pq2 q'' q' ⇒^a  q''
      using ws case_assms(3) unfolding weak_simulation_def by blast
    then moreover obtain q''' where q''_def: R p' q''' q'' ⟼* tau  q'''
      using case_assms(4) steps_retain_weak_sim[OF ws] by blast
    ultimately show  q'''. R p' q'''  q ⇒^a  q''' using weak_step_extend by blast
  qed
qed

lemma weak_sim_enabled_subs:
  assumes
    p ⊑ws q
    weak_enabled p a
    ¬ tau a
  shows weak_enabled q a
proof -
  obtain p' where p'_spec: p a p'
    using weak_enabled p a weak_enabled_step by blast
  obtain R where R p q weak_simulation R using assms(1) by blast
  then obtain q' where q ⇒^a q'
    unfolding weak_sim_weak_premise using weak_step_impl_weak_tau[OF p'_spec] by blast
  thus ?thesis using weak_enabled_step assms(3) by blast
qed

lemma weak_sim_union_cl:
  assumes
    weak_simulation RA
    weak_simulation RB
  shows
    weak_simulation (λ p q. RA p q  RB p q)
  using assms unfolding weak_simulation_def by blast

lemma weak_sim_remove_dead_state:
  assumes
    weak_simulation R
     a p . ¬ d a p  ¬ p a d
  shows
    weak_simulation (λ p q . R p q  q  d)
  unfolding weak_simulation_def
proof safe
  fix p q p' a
  assume
    R p q
    q  d
    p a  p'
  then obtain q' where R p' q' q ⇒^a  q'
    using assms(1) unfolding weak_simulation_def by blast
  moreover hence q'  d
    using assms(2) `q  d`
    by (metis steps.simps)
  ultimately show q'. (R p' q'  q'  d)  q ⇒^a  q' by blast
qed

lemma weak_sim_tau_step:
  weak_simulation (λ p1 q1 . q1 ⟼* tau p1)
  unfolding weak_simulation_def
  using lts.steps.simps by metis

lemma weak_sim_trans_constructive:
  fixes R1 R2
  defines
    R  λ p q .  pq . (R1 p pq  R2 pq q)  (R2 p pq  R1 pq q)
  assumes
    R1_def: weak_simulation R1 R1 p pq and
    R2_def: weak_simulation R2 R2 pq q
  shows
    R p q weak_simulation R
proof-
  show R p q unfolding R_def using R1_def(2) R2_def(2) by blast
next
  show weak_simulation R
    unfolding weak_sim_weak_premise R_def
  proof (safe)
    fix p q pq p' a pq1 pq2
    assume
      R1 p pq
      R2 pq q
      ¬ tau a
      p ⟼* tau  pq1
      pq1 a  pq2
      pq2 ⟼* tau  p'
    thus q'. (pq. R1 p' pq  R2 pq q'  R2 p' pq  R1 pq q')  q ⇒^a  q'
      using R1_def(1) R2_def(1) unfolding weak_sim_weak_premise by blast
  next
    fix p q pq p' a
    assume
      R1 p pq
      R2 pq q
      p ⟼* tau  p'
      q'.(pq. R1 p' pq  R2 pq q'  R2 p' pq  R1 pq q') q ⇒^a  q'
      tau a
    thus False
      using R1_def(1) R2_def(1) unfolding weak_sim_weak_premise by blast
  next
    fix p q pq p' a pq1 pq2
    assume 
      R1 p pq
      R2 pq q
      p ⟼* tau  p'
      p ⟼* tau  pq1
      pq1 a  pq2
      pq2 ⟼* tau  p'
    then obtain pq' q' where R1 p' pq' pq ⇒^a  pq' R2 pq' q' q ⇒^a  q'
      using R1_def(1) R2_def(1) assms(3) unfolding weak_sim_weak_premise by blast
    thus q'. (pq. R1 p' pq  R2 pq q'  R2 p' pq  R1 pq q')  q ⇒^a  q'
      by blast
  next
    fix p q pq p' a pq1 pq2
    assume sa:
      R2 p pq
      R1 pq q
      ¬ tau a
      p ⟼* tau  pq1
      pq1 a  pq2
      pq2 ⟼* tau  p'
    then obtain pq' q'  where R2 p' pq' pq ⇒^a  pq' R1 pq' q' q ⇒^a  q'
      using R2_def(1) R1_def(1) unfolding weak_sim_weak_premise by blast
    thus q'. (pq. R1 p' pq  R2 pq q'  R2 p' pq  R1 pq q')  q ⇒^a  q'
      by blast
  next
    fix p q pq p' a
    assume
      R2 p pq
      R1 pq q
      p ⟼* tau  p'
      q'.(pq. R1 p' pq  R2 pq q'  R2 p' pq  R1 pq q') q ⇒^a  q'
      tau a
    thus False
      using R1_def(1) R2_def(1) weak_step_tau_tau[OF `p ⟼* tau  p'` tau_tau]
      unfolding weak_sim_weak_premise by (metis (no_types, lifting))
  next
    fix p q pq p' a pq1 pq2
    assume sa:
      R2 p pq
      R1 pq q
      p ⟼* tau  p'
      p ⟼* tau  pq1
      pq1 a  pq2
      pq2 ⟼* tau  p'
    then obtain pq'  where R2 p' pq' pq ⇒^a  pq'
      using R1_def(1) R2_def(1) weak_step_impl_weak_tau[of p a p']
      unfolding weak_sim_weak_premise by blast
    moreover then obtain q' where R1 pq' q' q ⇒^a  q' 
      using R1_def(1) sa(2) unfolding weak_sim_weak_premise by blast
    ultimately show q'. (pq. R1 p' pq  R2 pq q'  R2 p' pq  R1 pq q')  q ⇒^a  q'
      by blast
  qed
qed

lemma weak_sim_trans:
  assumes
    p ⊑ws pq
    pq ⊑ws q
  shows
    p ⊑ws q
  using assms(1,2)
proof -
  obtain R1 R2  where  weak_simulation R1 R1 p pq weak_simulation R2 R2 pq q
    using assms(1,2) by blast
  thus ?thesis
    using weak_sim_trans_constructive tau_tau
    by blast
qed

lemma weak_sim_word_impl:
  fixes
    p q p' A
  assumes
    weak_simulation R R p q p ⇒$ A  p'
  shows
    q'. R p' q'  q ⇒$ A  q'
using assms(2,3) proof (induct A arbitrary: p q)
  case Nil
  then show ?case
    using assms(1) steps_retain_weak_sim by auto
next
  case (Cons a A)
  then obtain p'' where p''_spec: p ⇒^a p'' p'' ⇒$ A p' by auto
  with Cons(2) assms(1) obtain q'' where q''_spec: q ⇒^a q'' R p'' q''
    unfolding weak_sim_weak_premise by blast
  then show ?case using Cons(1) p''_spec(2)
    using weak_step_seq.simps(2) by blast
qed

lemma weak_sim_word_impl_contra:
  assumes
     p q . R p q 
      ( p' A. p ⇒$A p'  ( q'. R p' q'  q ⇒$A q'))
  shows
    weak_simulation R
proof -
  from assms have
     p q p' A . R p q  p ⇒$A p'  ( q'. R p' q'  q ⇒$A q') by blast
  hence  p q p' a . R p q  p ⇒$[a] p'  ( q'. R p' q'  q ⇒$[a] q') by blast
  thus ?thesis unfolding weak_single_step weak_sim_weak_premise by blast
qed

lemma weak_sim_word:
  weak_simulation R =
    ( p q . R p q 
      ( p' A. p ⇒$A p'  ( q'. R p' q'  q ⇒$A q')))
  using weak_sim_word_impl weak_sim_word_impl_contra by blast

subsection ‹Weak Bisimulation›

definition weak_bisimulation :: 
  ('s  's  bool)  bool
where
  weak_bisimulation R   p q. R p q  
    ( p' a. p a p'  ( q'. R p' q'
       (q ⇒^a q'))) 
    ( q' a. q a q'  ( p'. R p' q'
       ( p ⇒^a p')))
  
lemma weak_bisim_ruleformat:
assumes weak_bisimulation R
  and R p q
shows
  p a p'  ¬tau a  ( q'. R p' q'  (q a q'))
  p a p'   tau a  ( q'. R p' q'  (q ⟼* tau q'))
  q a q'  ¬tau a  ( p'. R p' q'  (p a p'))
  q a q'   tau a  ( p'. R p' q'  (p ⟼* tau p'))
  using assms unfolding weak_bisimulation_def by (blast+)
  
definition tau_weak_bisimulation :: 
  ('s  's   bool)   bool
where
  tau_weak_bisimulation R   p q. R p q  
    ( p' a. p a p'  
      ( q'. R p' q'  (q a q'))) 
    ( q' a. q a q'  
      ( p'. R p' q'  (p a p')))

lemma weak_bisim_implies_tau_weak_bisim:
  assumes
    tau_weak_bisimulation R
  shows
    weak_bisimulation R
unfolding weak_bisimulation_def proof (safe)
  fix p q p' a
  assume R p q p a  p'
  thus q'. R p' q'  (q ⇒^a  q')
    using assms weak_steps[of q a _ tau] unfolding tau_weak_bisimulation_def by blast
next
  fix p q q' a
  assume R p q q a  q'
  thus p'. R p' q'  (p ⇒^a  p')
    using assms weak_steps[of p a _ tau] unfolding tau_weak_bisimulation_def by blast
qed

lemma weak_bisim_invert:
  assumes
    weak_bisimulation R
  shows
    weak_bisimulation (λ p q. R q p)
using assms unfolding weak_bisimulation_def by auto

lemma bisim_weak_bisim:
  assumes bisimulation R
  shows weak_bisimulation R
  unfolding weak_bisimulation_def
proof (clarify, rule)
  fix p q
  assume R: R p q
  show p' a. p a  p'  (q'. R p' q'  (q ⇒^a  q'))
  proof (clarify)
    fix p' a
    assume p'a: p a  p'
    have
      ¬ tau a  (q'. R p' q'  q a  q')
      (tau a  (q'. R p' q'  q ⟼* tau  q')) 
      using bisim_ruleformat(1)[OF assms R p'a] step_weak_step step_weak_step_tau by auto
    thus q'. R p' q'  (q ⇒^a  q') by blast
  qed
next 
  fix p q
  assume R: R p q
  have q' a. q a  q'  (¬ tau a  (p'. R p' q'  p a  p'))
      (tau a  (p'. R p' q'  p ⟼* tau  p'))
  proof (clarify)
    fix q' a
    assume q'a: q a  q'
    show
      (¬ tau a  (p'. R p' q'  p a  p')) 
      (tau a  (p'. R p' q'  p ⟼* tau  p')) 
      using bisim_ruleformat(2)[OF assms R q'a] step_weak_step
        step_weak_step_tau steps_one_step by auto
  qed
  thus q' a. q a  q'  (p'. R p' q'  (p ⇒^a  p')) by blast
qed
  
lemma weak_bisim_weak_sim:
  shows weak_bisimulation R = (weak_simulation R  weak_simulation (λ p q . R q p))
unfolding weak_bisimulation_def weak_simulation_def by auto

lemma steps_retain_weak_bisim:
  assumes 
    weak_bisimulation R
    R p q
    p ⟼*A  p'
     a . tau a  A a
  shows q'. R p' q'  q ⟼*A  q'
    using assms weak_bisim_weak_sim steps_retain_weak_sim
    by auto
  
lemma weak_bisim_union:
  assumes
    weak_bisimulation R1
    weak_bisimulation R2
  shows
    weak_bisimulation (λ p q . R1 p q  R2 p q)
  using assms unfolding weak_bisimulation_def by blast

lemma weak_bisim_taufree_strong:
  assumes
    weak_bisimulation R
     p q a. p  a q  ¬ tau a
  shows
    bisimulation R
  using assms strong_weak_transition_system
  unfolding weak_bisimulation_def bisimulation_def
  by auto

subsection ‹Trace Inclusion›

definition trace_inclusion ::
  ('s  's  bool)  bool
where
  trace_inclusion R    p q p' A . ( a  set(A). a  τ) 
   R p q  p ⇒$ A p'  ( q'. q ⇒$ A q')

abbreviation weakly_trace_included_by :: 's  's  bool (‹_ ⊑T  _› [60, 60] 65)
  where weakly_trace_included_by p q   R . trace_inclusion R  R p q

lemma weak_trace_inlcusion_greatest:
  shows trace_inclusion (λ p q . p ⊑T q)
  unfolding trace_inclusion_def
  by blast

subsection ‹Delay Simulation›

definition delay_simulation :: 
  ('s  's  bool)  bool
where
  delay_simulation R   p q. R p q  
    ( p' a. p a p'  
      (tau a  R p' q) 
      (¬tau a  ( q'. R p' q' (q =⊳a q'))))

lemma delay_simulation_implies_weak_simulation:
  assumes
    delay_simulation R
  shows
    weak_simulation R
  using assms weak_step_delay_implies_weak_tau steps.refl
  unfolding delay_simulation_def weak_simulation_def by blast

subsection ‹Coupled Equivalences›

abbreviation coupling ::
  ('s  's  bool)  bool
  where coupling R   p q . R p q  ( q'. q ⟼*tau q'  R q' p)

lemma coupling_tau_max_symm:
  assumes
    R p q  ( q'. q ⟼*tau q'  R q' p)
    tau_max q
    R p q
  shows
    R q p
  using assms steps_no_step_pos[of q tau] by blast

corollary coupling_stability_symm:
  assumes
    R p q  ( q'. q ⟼*tau q'  R q' p)
    stable_state q
    R p q
  shows
    R q p
  using coupling_tau_max_symm stable_tauclosure_only_loop assms by metis

end ―‹context @{locale lts_tau}
end