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
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
end