Theory OpSem_Deadlock_Results
section‹ Deadlock Results ›
theory OpSem_Deadlock_Results
imports After_Trace_Operator
begin
lemma initial_ev_imp_in_events_of: ‹ev a ∈ P⇧0 ⟹ a ∈ α(P)›
by (meson AfterExt.events_of_iff_reachable_ev AfterExt.initial_ev_reachable)
lemma initial_tick_imp_in_ticks_of: ‹✓(r) ∈ P⇧0 ⟹ r ∈ ✓s(P)›
by (meson AfterExt.initial_tick_reachable AfterExt.ticks_of_iff_reachable_tick)
lemma ‹UNIV ∈ ℛ P ⟷ P ⊑⇩F STOP›
unfolding failure_refine_def
apply (simp add: D_STOP F_STOP Refusals_iff)
using is_processT4 by blast
lemma no_events_of_if_at_most_initial_tick: ‹P⇧0 ⊆ range tick ⟹ α(P) = {}›
using empty_ev_initials_iff_empty_events_of by fast
lemma deadlock_free_initial_evE:
‹deadlock_free P ⟹ (⋀a. ev a ∈ P⇧0 ⟹ thesis) ⟹ thesis›
using empty_ev_initials_iff_empty_events_of
nonempty_events_of_if_deadlock_free by fastforce
context AfterExt
begin
text ‹As we said earlier, @{const [source] After⇩t⇩r⇩a⇩c⇩e} allows us to obtain some
very powerful results about \<^const>‹deadlock_free› and \<^const>‹deadlock_free⇩S⇩K⇩I⇩P⇩S›.›
subsection ‹Preliminaries and induction Rules›
context fixes P :: ‹('a, 'r) process⇩p⇩t⇩i⇩c⇩k› begin
lemma initials_After⇩t⇩r⇩a⇩c⇩e_subset_events_of:
‹(P after⇩𝒯 t)⇧0 ⊆ ev ` α(P)› if ‹non_terminating P› ‹t ∈ 𝒯 P›
proof -
have ‹tF t ⟹ ev a ∈ (P after⇩𝒯 t)⇧0 ⟹ reachable_ev P a› for a
using reachable_ev_iff_in_initials_After⇩t⇩r⇩a⇩c⇩e_for_some_tickFree_T that(2) by blast
also have ‹tF t ∧ range tick ∩ (P after⇩𝒯 t)⇧0 = {}›
by (simp add: disjoint_iff image_iff)
(metis T_After⇩t⇩r⇩a⇩c⇩e_eq initials_def mem_Collect_eq non_terminating_is_right
non_tickFree_tick that(1) that(2) tickFree_append_iff)
ultimately show ‹(P after⇩𝒯 t)⇧0 ⊆ ev ` α(P)›
by (simp add: subset_iff image_iff disjoint_iff)
(metis event⇩p⇩t⇩i⇩c⇩k.exhaust events_of_iff_reachable_ev)
qed
end
text ‹With the next result, the general idea appears: instead of doing an induction only
on the process \<^term>‹P› we are interested in, we include a quantification over all
the processes than can be reached from \<^term>‹P› after some trace of \<^term>‹P›.›
theorem After⇩t⇩r⇩a⇩c⇩e_fix_ind [consumes 2, case_names cont step]:
fixes ref :: ‹[('a, 'r) process⇩p⇩t⇩i⇩c⇩k, ('a, 'r) process⇩p⇩t⇩i⇩c⇩k] ⇒ bool› (infix ‹⊑⇩r⇩e⇩f› 60)
assumes adm_ref : ‹⋀u v. cont (u :: ('a, 'r) process⇩p⇩t⇩i⇩c⇩k ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k) ⟹ monofun v
⟹ adm (λx. u x ⊑⇩r⇩e⇩f v x)›
and BOT_le_ref : ‹⋀Q. ⊥ ⊑⇩r⇩e⇩f Q›
and cont_f : ‹cont f›
and hyp : ‹⋀s x. ∀Q ∈ {Q. ∃s ∈ 𝒯 P. g s Q ∧ Q = P after⇩𝒯 s}. x ⊑⇩r⇩e⇩f Q ⟹
s ∈ 𝒯 P ⟹ g s (P after⇩𝒯 s) ⟹ f x ⊑⇩r⇩e⇩f P after⇩𝒯 s›
shows ‹∀Q ∈ {Q. ∃s ∈ 𝒯 P. g s Q ∧ Q = P after⇩𝒯 s}. (μ X. f X) ⊑⇩r⇩e⇩f Q›
apply (induct rule: fix_ind)
apply (solves ‹simp add: adm_ref monofunI›)
apply (solves ‹simp add: BOT_le_ref›)
using hyp cont_f by auto
lemma After⇩t⇩r⇩a⇩c⇩e_fix_ind_F [consumes 1, case_names cont step]:
‹⟦Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}; cont f;
⋀t x. ⟦∀Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}. x ⊑⇩F Q;
t ∈ 𝒯 P; g t (P after⇩𝒯 t)⟧ ⟹ f x ⊑⇩F P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩F Q›
and After⇩t⇩r⇩a⇩c⇩e_fix_ind_D [consumes 1, case_names cont step]:
‹⟦Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}; cont f;
⋀t x. ⟦∀Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}. x ⊑⇩D Q;
t ∈ 𝒯 P; g t (P after⇩𝒯 t)⟧ ⟹ f x ⊑⇩D P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩D Q›
and After⇩t⇩r⇩a⇩c⇩e_fix_ind_T [consumes 1, case_names cont step]:
‹⟦Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}; cont f;
⋀t x. ⟦∀Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}. x ⊑⇩T Q;
t ∈ 𝒯 P; g t (P after⇩𝒯 t)⟧ ⟹ f x ⊑⇩T P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩T Q›
and After⇩t⇩r⇩a⇩c⇩e_fix_ind_FD [consumes 1, case_names cont step]:
‹⟦Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}; cont f;
⋀t x. ⟦∀Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}. x ⊑⇩F⇩D Q;
t ∈ 𝒯 P; g t (P after⇩𝒯 t)⟧ ⟹ f x ⊑⇩F⇩D P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩F⇩D Q›
and After⇩t⇩r⇩a⇩c⇩e_fix_ind_DT [consumes 1, case_names cont step]:
‹⟦Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}; cont f;
⋀t x. ⟦∀Q ∈ {Q. ∃t ∈ 𝒯 P. g t Q ∧ Q = P after⇩𝒯 t}. x ⊑⇩D⇩T Q;
t ∈ 𝒯 P; g t (P after⇩𝒯 t)⟧ ⟹ f x ⊑⇩D⇩T P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩D⇩T Q›
by (all ‹rule After⇩t⇩r⇩a⇩c⇩e_fix_ind[rule_format]›) simp_all
corollary reachable_processes_fix_ind [consumes 3, case_names cont step]:
‹⟦Q ∈ ℛ⇩p⇩r⇩o⇩c P;
⋀u v. ⟦cont (u :: ('a, 'r) process⇩p⇩t⇩i⇩c⇩k ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k); monofun v⟧ ⟹ adm (λx. ref (u x) (v x));
⋀Q. ref ⊥ Q;
cont f;
⋀t x. ⟦∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. ref x Q; t ∈ 𝒯 P; tickFree t⟧ ⟹ ref (f x) (P after⇩𝒯 t)⟧ ⟹
ref (μ x. f x) Q›
by (simp add: reachable_processes_is,
rule After⇩t⇩r⇩a⇩c⇩e_fix_ind[where g = ‹λs Q. tickFree s›, simplified, rule_format]; simp)
corollary reachable_processes_fix_ind_F [consumes 1, case_names cont step]:
‹⟦Q ∈ ℛ⇩p⇩r⇩o⇩c P; cont f;
⋀t x. ∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩F Q ⟹ t ∈ 𝒯 P ⟹ tickFree t ⟹ f x ⊑⇩F P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩F Q›
and reachable_processes_fix_ind_D [consumes 1, case_names cont step]:
‹⟦Q ∈ ℛ⇩p⇩r⇩o⇩c P; cont f;
⋀t x. ∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩D Q ⟹ t ∈ 𝒯 P ⟹ tickFree t ⟹ f x ⊑⇩D P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩D Q›
and reachable_processes_fix_ind_T [consumes 1, case_names cont step]:
‹⟦Q ∈ ℛ⇩p⇩r⇩o⇩c P; cont f;
⋀t x. ∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩T Q ⟹ t ∈ 𝒯 P ⟹ tickFree t ⟹ f x ⊑⇩T P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩T Q›
and reachable_processes_fix_ind_FD [consumes 1, case_names cont step]:
‹⟦Q ∈ ℛ⇩p⇩r⇩o⇩c P; cont f;
⋀t x. ∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩F⇩D Q ⟹ t ∈ 𝒯 P ⟹ tickFree t ⟹ f x ⊑⇩F⇩D P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩F⇩D Q›
and reachable_processes_fix_ind_DT [consumes 1, case_names cont step]:
‹⟦Q ∈ ℛ⇩p⇩r⇩o⇩c P; cont f;
⋀t x. ∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩D⇩T Q ⟹ t ∈ 𝒯 P ⟹ tickFree t ⟹ f x ⊑⇩D⇩T P after⇩𝒯 t⟧ ⟹
(μ X. f X) ⊑⇩D⇩T Q›
by (all ‹rule reachable_processes_fix_ind›) simp_all
subsection ‹New idea: \<^const>‹After› induct instead of \<^const>‹After⇩t⇩r⇩a⇩c⇩e››
subsection ‹New results on \<^term>‹ℛ⇩p⇩r⇩o⇩c››
lemma reachable_processes_FD_refinement_propagation_induct [consumes 1, case_names cont base step]:
assumes reachable : ‹(Q :: ('a, 'r) process⇩p⇩t⇩i⇩c⇩k) ∈ ℛ⇩p⇩r⇩o⇩c P›
and cont_f : ‹cont f›
and base : ‹(μ x. f x) ⊑⇩F⇩D P›
and step : ‹⋀a. a ∈ α(P) ⟹ f (μ x. f x) after a = (μ x. f x)›
shows ‹(μ x. f x) ⊑⇩F⇩D Q›
proof (use reachable in ‹induct rule: reachable_processes.induct›)
case reachable_self
show ‹(μ x. f x) ⊑⇩F⇩D P› by (fact base)
next
case (reachable_after Q a)
from reachable_after.hyps(2) have ‹f (μ x. f x) ⊑⇩F⇩D Q›
by (subst (asm) cont_process_rec[OF refl cont_f])
hence * : ‹f (μ x. f x) after a ⊑⇩F⇩D Q after a›
by (simp add: mono_After_FD reachable_after.hyps(3))
from reachable_after.hyps(1, 3) have ‹a ∈ α(P)›
using events_of_reachable_processes_subset initial_ev_imp_in_events_of by (metis in_mono)
hence ** : ‹f (μ x. f x) after a = (μ x. f x)› by (fact local.step)
from "*"[unfolded "**"] show ‹(μ x. f x) ⊑⇩F⇩D Q after a› .
qed
theorem ℛ⇩p⇩r⇩o⇩c_fix_ind [consumes 3, case_names cont step]:
fixes ref :: ‹[('a, 'r) process⇩p⇩t⇩i⇩c⇩k, ('a, 'r) process⇩p⇩t⇩i⇩c⇩k] ⇒ bool› (infix ‹⊑⇩r⇩e⇩f› 60)
assumes reachable : ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P›
and adm_ref : ‹⋀u v. cont (u :: ('a, 'r) process⇩p⇩t⇩i⇩c⇩k ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k) ⟹ monofun v
⟹ adm (λx. u x ⊑⇩r⇩e⇩f v x)›
and BOT_le_ref : ‹⋀Q. ⊥ ⊑⇩r⇩e⇩f Q›
and cont_f : ‹cont f›
and hyp : ‹⋀x. ∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩r⇩e⇩f Q ⟹ ∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. f x ⊑⇩r⇩e⇩f Q›
shows ‹(μ X. f X) ⊑⇩r⇩e⇩f Q›
proof -
have ‹∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. (μ X. f X) ⊑⇩r⇩e⇩f Q›
apply (induct rule: fix_ind)
apply (solves ‹simp add: adm_ref monofunI›)
apply (solves ‹simp add: BOT_le_ref›)
using hyp cont_f by auto
with reachable show ‹(μ X. f X) ⊑⇩r⇩e⇩f Q› by blast
qed
lemma ℛ⇩p⇩r⇩o⇩c_fix_ind_FD [consumes 1, case_names cont step]:
‹⟦Q ∈ ℛ⇩p⇩r⇩o⇩c P; cont f; ⋀x Q. ∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩F⇩D Q ⟹ Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ f x ⊑⇩F⇩D Q⟧
⟹ (μ X. f X) ⊑⇩F⇩D Q›
by (rule ℛ⇩p⇩r⇩o⇩c_fix_ind) auto
subsection ‹Induction Proofs›
subsubsection ‹Generalizations›
lemma ‹Mprefix A P = Mprefix B Q ⟹ A = B›
by (drule arg_cong[where f = initials]) (auto simp add: initials_Mprefix)
lemma ‹Mndetprefix A P = Mprefix B Q ⟹ A = B›
by (drule arg_cong[where f = initials]) (auto simp add: initials_Mprefix initials_Mndetprefix)
lemma ‹Mndetprefix A P = Mndetprefix B Q ⟹ A = B›
by (drule arg_cong[where f = initials]) (auto simp add: initials_Mndetprefix)
print_context
lemma superset_initials_restriction_Mndetprefix_FD:
‹⊓a ∈ B → P a ⊑⇩F⇩D Q›
if ‹⊓a ∈ A → P a ⊑⇩F⇩D Q› and ‹{e. ev e ∈ Q⇧0} ⊆ B› and ‹A ≠ {} ∨ B = {}›
supply that' = that(1)[unfolded failure_divergence_refine_def failure_refine_def divergence_refine_def]
proof (unfold failure_divergence_refine_def failure_refine_def divergence_refine_def, safe)
from that'[THEN conjunct2] that(2)
show ‹s ∈ 𝒟 Q ⟹ s ∈ 𝒟 (Mndetprefix B P)› for s
by (simp add: D_Mndetprefix write0_def D_Mprefix subset_iff split: if_split_asm)
(metis initials_memI D_T empty_iff)
next
from that have that'' : ‹Q⇧0 ⊆ ev ` A›
using anti_mono_initials_FD initials_Mndetprefix by blast
fix s X
assume * : ‹(s, X) ∈ ℱ Q›
with set_mp[OF that'[THEN conjunct1] this]
consider ‹s = []› | e s' where ‹s = ev e # s'› ‹ev e ∈ Q⇧0›
by (simp add: F_Mndetprefix write0_def F_Mprefix split: if_split_asm)
(metis initials_memI F_T)
thus ‹(s, X) ∈ ℱ (Mndetprefix B P)›
proof cases
assume ‹s = []›
hence ‹([], X ∪ (- Q⇧0)) ∈ ℱ Q›
by (metis "*" ComplD initials_memI is_processT5_S7' self_append_conv2)
from set_mp[OF that'[THEN conjunct1] this] that'' that(2, 3)
show ‹(s, X) ∈ ℱ (Mndetprefix B P)›
by (simp add: ‹s = []› F_Mndetprefix write0_def F_Mprefix split: if_split_asm) blast
next
fix e s' assume ‹s = ev e # s'› ‹ev e ∈ Q⇧0›
with set_mp[OF that'[THEN conjunct1] "*"] that(2)
show ‹(s, X) ∈ ℱ (Mndetprefix B P)›
by (simp add: F_Mndetprefix write0_def F_Mprefix subset_iff split: if_split_asm) blast
qed
qed
corollary initials_restriction_Mndetprefix_FD:
‹⊓a ∈ A → P a ⊑⇩F⇩D Q ⟹ ⊓a ∈ {e. ev e ∈ Q⇧0} → P a ⊑⇩F⇩D Q›
by (cases ‹A = {}›, simp add: STOP_FD_iff)
(simp add: superset_initials_restriction_Mndetprefix_FD)
corollary events_of_restriction_Mndetprefix_FD:
‹⊓a ∈ A → P a ⊑⇩F⇩D (Q :: ('a, 'r) process⇩p⇩t⇩i⇩c⇩k) ⟹ ⊓a ∈ α(Q) → P a ⊑⇩F⇩D Q›
by (cases ‹A = {}›, simp add: STOP_FD_iff)
(erule superset_initials_restriction_Mndetprefix_FD,
simp_all add: subset_iff initial_ev_imp_in_events_of)
lemma superset_initials_restriction_Mprefix_FD:
‹□a ∈ B → P a ⊑⇩F⇩D Q›
if ‹□a ∈ A → P a ⊑⇩F⇩D Q› and ‹{e. ev e ∈ Q⇧0} ⊆ B›
and ‹B ⊆ A›
supply that' = that(1)[unfolded failure_divergence_refine_def failure_refine_def divergence_refine_def]
proof (unfold failure_divergence_refine_def failure_refine_def divergence_refine_def, safe)
from that'[THEN conjunct2] that(2)
show ‹s ∈ 𝒟 Q ⟹ s ∈ 𝒟 (Mprefix B P)› for s
by (simp add: D_Mprefix subset_iff image_iff)
(metis initials_memI D_T)
next
from that have that'' : ‹Q⇧0 ⊆ ev ` A›
using anti_mono_initials_FD initials_Mprefix by blast
fix s X
assume * : ‹(s, X) ∈ ℱ Q›
with set_mp[OF that'[THEN conjunct1] this]
consider ‹s = []› | ‹∃e s'. s = ev e # s' ∧ ev e ∈ Q⇧0›
by (simp add: F_Mprefix) (metis initials_memI F_T)
thus ‹(s, X) ∈ ℱ (Mprefix B P)›
proof cases
assume ‹s = []›
hence ‹([], X ∪ (- Q⇧0)) ∈ ℱ Q›
by (metis "*" ComplD initials_memI is_processT5_S7' self_append_conv2)
from set_mp[OF that'[THEN conjunct1] this] that'' that(2, 3)
show ‹(s, X) ∈ ℱ (Mprefix B P)› by (simp add: ‹s = []› F_Mprefix) blast
next
assume ‹∃e s'. s = ev e # s' ∧ ev e ∈ Q⇧0›
with set_mp[OF that'[THEN conjunct1] "*"] that(2)
show ‹(s, X) ∈ ℱ (Mprefix B P)› by (auto simp add: F_Mprefix image_iff)
qed
qed
corollary initials_restriction_Mprefix_FD:
‹{e. ev e ∈ Q⇧0} ⊆ A ⟹ □a ∈ A → P a ⊑⇩F⇩D Q ⟹
□a ∈ {e. ev e ∈ Q⇧0} → P a ⊑⇩F⇩D Q›
by (erule superset_initials_restriction_Mprefix_FD; simp)
corollary events_of_restriction_Mprefix_FD:
‹α(Q) ⊆ A ⟹ □a ∈ A → P a ⊑⇩F⇩D (Q :: ('a, 'r) process⇩p⇩t⇩i⇩c⇩k) ⟹
□a ∈ α(Q) → P a ⊑⇩F⇩D Q›
by (erule superset_initials_restriction_Mprefix_FD,
simp add: subset_iff initial_ev_imp_in_events_of)
lemma superset_initials_restriction_Mprefix_DT:
‹□a ∈ B → P a ⊑⇩D⇩T Q› if ‹□a ∈ A → P a ⊑⇩D⇩T Q› and ‹{e. ev e ∈ Q⇧0} ⊆ B›
supply that' = that(1)[unfolded trace_divergence_refine_def
trace_refine_def divergence_refine_def]
proof (unfold trace_divergence_refine_def trace_divergence_refine_def
trace_refine_def divergence_refine_def, safe)
from that'[THEN conjunct2] that(2)
show ‹s ∈ 𝒟 Q ⟹ s ∈ 𝒟 (Mprefix B P)› for s
by (simp add: D_Mprefix subset_iff image_iff)
(metis initials_memI D_T)
next
from that have that'' : ‹Q⇧0 ⊆ ev ` A›
using anti_mono_initials_DT initials_Mprefix by blast
fix s
assume * : ‹s ∈ 𝒯 Q›
with set_mp[OF that'[THEN conjunct1] this]
consider ‹s = []› | ‹∃e s'. s = ev e # s' ∧ ev e ∈ Q⇧0›
by (simp add: T_Mprefix) (metis initials_memI)
thus ‹s ∈ 𝒯 (Mprefix B P)›
proof cases
show ‹s = [] ⟹ s ∈ 𝒯 (Mprefix B P)› by simp
next
assume ‹∃e s'. s = ev e # s' ∧ ev e ∈ Q⇧0›
with set_mp[OF that'[THEN conjunct1] "*"] that(2)
show ‹s ∈ 𝒯 (Mprefix B P)› by (auto simp add: T_Mprefix)
qed
qed
corollary initials_restriction_Mprefix_DT:
‹□a ∈ A → P a ⊑⇩D⇩T Q ⟹ □a ∈ {e. ev e ∈ Q⇧0} → P a ⊑⇩D⇩T Q›
by (erule superset_initials_restriction_Mprefix_DT) simp
corollary events_restriction_Mprefix_DT:
‹□a ∈ A → P a ⊑⇩D⇩T (Q :: ('a, 'r) process⇩p⇩t⇩i⇩c⇩k) ⟹ □a ∈ α(Q) → P a ⊑⇩D⇩T Q›
by (erule superset_initials_restriction_Mprefix_DT)
(simp add: subset_iff initial_ev_imp_in_events_of)
paragraph ‹Admissibility›
lemma not_le_F_adm[simp]: ‹cont u ⟹ adm (λx. ¬ u x ⊑⇩F P)›
by (simp add: adm_def cont2contlubE ch2ch_cont failure_refine_def
limproc_is_thelub F_LUB subset_iff) blast
lemma not_le_T_adm[simp]: ‹cont u ⟹ adm (λx. ¬ u x ⊑⇩T P)›
by (simp add: adm_def cont2contlubE ch2ch_cont trace_refine_def
limproc_is_thelub T_LUB subset_iff) blast
lemma not_le_D_adm[simp]: ‹cont u ⟹ adm (λx. ¬ u x ⊑⇩D P)›
by (simp add: adm_def cont2contlubE ch2ch_cont divergence_refine_def
limproc_is_thelub D_LUB subset_iff) blast
lemma not_le_FD_adm[simp]: ‹cont u ⟹ adm (λx. ¬ u x ⊑⇩F⇩D P)›
by (simp add: adm_def cont2contlubE ch2ch_cont failure_divergence_refine_def
failure_refine_def divergence_refine_def limproc_is_thelub F_LUB D_LUB subset_iff) blast
lemma not_le_DT_adm[simp]: ‹cont u ⟹ adm (λx. ¬ u x ⊑⇩D⇩T P)›
by (simp add: adm_def cont2contlubE ch2ch_cont trace_divergence_refine_def trace_refine_def
divergence_refine_def limproc_is_thelub D_LUB T_LUB subset_iff) blast
lemma initials_refusal:
‹(t, UNIV) ∈ ℱ P› if assms: ‹t ∈ 𝒯 P› ‹tF t› ‹(t, (P after⇩𝒯 t)⇧0) ∈ ℱ P›
proof (rule ccontr)
assume ‹(t, UNIV) ∉ ℱ P›
from is_processT5_S7'[OF assms(3), of UNIV, simplified, OF this]
obtain e where ‹e ∉ (P after⇩𝒯 t)⇧0 ∧ t @ [e] ∈ 𝒯 P› ..
thus False by (simp add: initials_def T_After⇩t⇩r⇩a⇩c⇩e_eq assms(1, 2))
qed
lemma leF_ev_initialE' :
assumes ‹STOP ⊓ (⊓a ∈ UNIV → P a) ⊑⇩F Q› ‹Q ≠ STOP› obtains a where ‹ev a ∈ Q⇧0›
proof -
from ‹Q ≠ STOP› initials_empty_iff_STOP obtain e where ‹e ∈ Q⇧0› by blast
with ‹STOP ⊓ (⊓a ∈ UNIV → P a) ⊑⇩F Q› obtain a where ‹e = ev a›
by (auto simp add: failure_refine_def F_Ndet F_STOP F_Mndetprefix'
intro: T_F dest!: initials_memD)
with ‹e ∈ Q⇧0› that show thesis by blast
qed
corollary leF_ev_initialE :
assumes ‹⊓a ∈ UNIV → P a ⊑⇩F Q› obtains a where ‹ev a ∈ Q⇧0›
proof -
from ‹⊓a ∈ UNIV → P a ⊑⇩F Q› Ndet_F_self_right trans_F
have ‹STOP ⊓ (⊓a ∈ UNIV → P a) ⊑⇩F Q› by blast
moreover from ‹⊓a ∈ UNIV → P a ⊑⇩F Q› have ‹Q ≠ STOP›
by (auto simp add: Process_eq_spec failure_refine_def F_Mndetprefix' F_STOP)
ultimately obtain a where ‹ev a ∈ Q⇧0› by (rule leF_ev_initialE')
with that show thesis by blast
qed
lemma leFD_ev_initialE' :
‹STOP ⊓ (⊓a ∈ UNIV → P a) ⊑⇩F⇩D Q ⟹ Q ≠ STOP ⟹ (⋀a. ev a ∈ Q⇧0 ⟹ thesis) ⟹ thesis›
by (meson leFD_imp_leF leF_ev_initialE')
lemma leFD_ev_initialE :
‹⊓a ∈ UNIV → P a ⊑⇩F⇩D Q ⟹ (⋀a. ev a ∈ Q⇧0 ⟹ thesis) ⟹ thesis›
by (meson leFD_imp_leF leF_ev_initialE)
method prove_propagation uses simp base =
induct rule: reachable_processes_FD_refinement_propagation_induct,
solves simp, solves ‹use base in ‹simp add: simp››, solves ‹simp add: simp›
text ‹The three following results illustrate how powerful are our new rules of induction.›
text ‹Really ? The second version with @{thm cont_parallel_fix_ind} seems easier...›
lemma
‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ DF α(P) ⊑⇩F Q› if df_P: ‹deadlock_free P›
proof (unfold DF_def, induct rule: reachable_processes_fix_ind_F)
show ‹cont (λx. ⊓ a ∈ events_of P → x)› by simp
next
fix x
assume hyp : ‹∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩F Q›
show ‹s ∈ 𝒯 P ⟹ tickFree s ⟹ ⊓a ∈ events_of P → x ⊑⇩F P after⇩𝒯 s› for s
proof (unfold failure_refine_def, safe)
show ‹s ∈ 𝒯 P ⟹ tickFree s ⟹ (t, X) ∈ ℱ (P after⇩𝒯 s) ⟹
(t, X) ∈ ℱ (⊓a ∈ events_of P → x)› for t X
proof (induct t arbitrary: s)
case Nil
have * : ‹deadlock_free (P after⇩𝒯 s)›
by (metis After⇩t⇩r⇩a⇩c⇩e.simps(1) ‹s ∈ 𝒯 P› deadlock_free_After⇩t⇩r⇩a⇩c⇩e_characterization df_P)
have ‹([], X ∪ (- initials (P after⇩𝒯 s))) ∈ ℱ (P after⇩𝒯 s)›
by (metis ComplD Nil.prems T_After⇩t⇩r⇩a⇩c⇩e_eq is_processT5_S7'
mem_Collect_eq initials_After⇩t⇩r⇩a⇩c⇩e self_append_conv2)
from this[THEN set_rev_mp, OF "*"[unfolded deadlock_free_F failure_refine_def]]
show ‹([], X) ∈ ℱ (⊓a ∈ events_of P → x)›
apply (subst (asm) F_DF, simp add: F_Mndetprefix write0_def F_Mprefix image_iff)
using Nil.prems(1) deadlock_free_implies_non_terminating events_of_iff_reachable_ev
reachable_ev_iff_in_initials_After⇩t⇩r⇩a⇩c⇩e_for_some_tickFree_T that by blast
next
case (Cons e t)
from Cons.prems(1, 2) have * : ‹P after⇩𝒯 s ∈ ℛ⇩p⇩r⇩o⇩c P›
by (auto simp add: reachable_processes_is)
obtain e' where ** : ‹e = ev e'› ‹e' ∈ events_of P›
by (meson Cons.prems(1, 3) initials_memI F_T set_mp
deadlock_free_implies_non_terminating df_P imageE
non_terminating_is_right initials_After⇩t⇩r⇩a⇩c⇩e_subset_events_of)
from Cons.prems F_After⇩t⇩r⇩a⇩c⇩e_eq "**"(1)
have ‹(t, X) ∈ ℱ (P after⇩𝒯 (s @ [e]))› by (simp add: F_After⇩t⇩r⇩a⇩c⇩e)
also have ‹… ⊆ ℱ x›
apply (rule hyp[rule_format, unfolded failure_refine_def,
of ‹P after⇩𝒯 (s @ [e])›, simplified])
apply (simp add: After⇩t⇩r⇩a⇩c⇩e_snoc "**"(1) After⇩t⇩i⇩c⇩k_def)
apply (rule reachable_after[OF "*" ])
using Cons.prems(3) initials_memI F_T "**"(1) by blast
finally have ‹(t, X) ∈ ℱ x› .
with "**" show ?case by (auto simp add: F_Mndetprefix write0_def F_Mprefix)
qed
qed
qed
lemma
‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ DF⇩S⇩K⇩I⇩P⇩S α(P) UNIV ⊑⇩F Q› if df⇩S⇩K⇩I⇩P_P: ‹deadlock_free⇩S⇩K⇩I⇩P⇩S P›
proof (unfold DF⇩S⇩K⇩I⇩P⇩S_def, induct rule: reachable_processes_fix_ind_F)
show ‹cont (λx. (⊓a ∈ events_of P → x) ⊓ SKIPS UNIV)› by simp
next
fix x
assume hyp : ‹∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩F Q›
show ‹s ∈ 𝒯 P ⟹ tickFree s ⟹ (⊓a ∈ events_of P → x) ⊓ SKIPS UNIV ⊑⇩F P after⇩𝒯 s› for s
proof (unfold failure_refine_def, safe)
show ‹s ∈ 𝒯 P ⟹ tickFree s ⟹ (t, X) ∈ ℱ (P after⇩𝒯 s) ⟹
(t, X) ∈ ℱ ((⊓a ∈ events_of P → x) ⊓ SKIPS UNIV)› for t X
proof (induct t arbitrary: s)
case Nil
have * : ‹deadlock_free⇩S⇩K⇩I⇩P⇩S (P after⇩𝒯 s)›
by (metis After⇩t⇩r⇩a⇩c⇩e.simps(1) Nil.prems(1, 2) deadlock_free⇩S⇩K⇩I⇩P⇩S_After⇩t⇩r⇩a⇩c⇩e_characterization df⇩S⇩K⇩I⇩P_P)
have ‹([], X ∪ (- initials (P after⇩𝒯 s))) ∈ ℱ (P after⇩𝒯 s)›
by (metis (no_types, opaque_lifting) ComplD initials_memI
Nil.prems(3) append_eq_Cons_conv is_processT5_S7')
from this[THEN set_rev_mp, OF "*"[unfolded deadlock_free⇩S⇩K⇩I⇩P⇩S_def failure_refine_def]]
show ‹([], X) ∈ ℱ ((⊓a ∈ events_of P → x) ⊓ SKIPS UNIV)›
apply (subst (asm) F_DF⇩S⇩K⇩I⇩P⇩S, simp add: F_Ndet F_SKIPS F_Mndetprefix write0_def F_Mprefix image_iff)
using Nil.prems(1, 2) events_of_iff_reachable_ev
reachable_ev_iff_in_initials_After⇩t⇩r⇩a⇩c⇩e_for_some_tickFree_T by blast
next
case (Cons e t)
from Cons.prems(1, 2) have * : ‹P after⇩𝒯 s ∈ ℛ⇩p⇩r⇩o⇩c P›
by (auto simp add: reachable_processes_is)
have ‹deadlock_free⇩S⇩K⇩I⇩P⇩S (P after⇩𝒯 s)›
by (metis After⇩t⇩r⇩a⇩c⇩e.simps(1) Cons.prems(1, 2) deadlock_free⇩S⇩K⇩I⇩P⇩S_After⇩t⇩r⇩a⇩c⇩e_characterization df⇩S⇩K⇩I⇩P_P)
then consider a where ‹e = ev a› ‹a ∈ events_of P› | r where ‹e = ✓(r)›
unfolding deadlock_free⇩S⇩K⇩I⇩P⇩S_def failure_refine_def
apply (subst (asm) F_DF⇩S⇩K⇩I⇩P⇩S, simp add: subset_iff image_iff)
by (metis reachable_ev_iff_in_initials_After⇩t⇩r⇩a⇩c⇩e_for_some_tickFree_T Cons.prems
initials_memI F_T events_of_iff_reachable_ev list.distinct(1) list.sel(1))
thus ?case
proof cases
fix a assume ** : ‹e = ev a› ‹a ∈ events_of P›
from Cons.prems F_After⇩t⇩r⇩a⇩c⇩e "**"(1)
have ‹(t, X) ∈ ℱ (P after⇩𝒯 (s @ [e]))› by (simp add: F_After⇩t⇩r⇩a⇩c⇩e_eq)
also have ‹… ⊆ ℱ x›
apply (rule hyp[rule_format, unfolded failure_refine_def,
of ‹P after⇩𝒯 (s @ [e])›, simplified])
apply (simp add: After⇩t⇩r⇩a⇩c⇩e_snoc "**"(1) After⇩t⇩i⇩c⇩k_def)
apply (rule reachable_after[OF "*" ])
using Cons.prems(3) initials_memI F_T "**"(1) by blast
finally have ‹(t, X) ∈ ℱ x› .
with "**" show ?case by (auto simp add: F_Ndet F_Mndetprefix write0_def F_Mprefix)
next
fix r assume ‹e = ✓(r)›
hence ‹t = []›
by (metis Cons.prems(3) F_imp_front_tickFree event⇩p⇩t⇩i⇩c⇩k.disc(2) front_tickFree_Cons_iff)
thus ?case by (simp add: ‹e = ✓(r)› F_Ndet F_SKIPS)
qed
qed
qed
qed
context fixes P :: ‹('a, 'r) process⇩p⇩t⇩i⇩c⇩k› begin
theorem deadlock_free_iff_empty_ticks_of_and_deadlock_free⇩S⇩K⇩I⇩P⇩S :
‹deadlock_free P ⟷ ✓s(P) = {} ∧ deadlock_free⇩S⇩K⇩I⇩P⇩S P›
proof (intro iffI conjI)
from deadlock_free_implies_non_terminating tickFree_traces_iff_empty_ticks_of
show ‹deadlock_free P ⟹ ✓s(P) = {}› by fast
next
show ‹deadlock_free P ⟹ deadlock_free⇩S⇩K⇩I⇩P⇩S P›
by (fact deadlock_free_imp_deadlock_free⇩S⇩K⇩I⇩P⇩S)
next
have ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ DF⇩S⇩K⇩I⇩P⇩S UNIV UNIV ⊑⇩F Q ⟹ DF UNIV ⊑⇩F Q› if ‹✓s(P) = {}› for Q
proof (unfold DF_def DF⇩S⇩K⇩I⇩P⇩S_def, induct arbitrary: Q rule: cont_parallel_fix_ind)
show ‹cont (λx. (⊓a∈UNIV → x) ⊓ SKIPS UNIV)› by simp
next
show ‹cont (λx. ⊓a∈UNIV → x)› by simp
next
show ‹adm (λx. ∀Q. Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟶ fst x ⊑⇩F Q ⟶ snd x ⊑⇩F Q)› by simp
next
show ‹⋀Q. ⊥ ⊑⇩F Q› by simp
next
fix x y Q assume hyp : ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ x ⊑⇩F Q ⟹ y ⊑⇩F Q› for Q
assume ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q›
from ‹✓s(P) = {}› ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› have ‹✓s(Q) = {}›
using ticks_of_reachable_processes_subset by auto
from ‹✓s(Q) = {}› initial_tick_imp_in_ticks_of have ‹{r. ✓(r) ∈ Q⇧0} = {}› by force
moreover from ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q›
have ‹Q⇧0 ≠ {}› by (auto simp add: initials_empty_iff_STOP Process_eq_spec failure_refine_def
F_Ndet F_Mndetprefix' F_SKIPS subset_iff F_STOP)
ultimately have ‹{a. ev a ∈ Q⇧0} ≠ {}›
by (metis empty_Collect_eq equals0I event⇩p⇩t⇩i⇩c⇩k.exhaust)
hence ‹⊓a ∈ UNIV → y ⊑⇩F ⊓a ∈ {a. ev a ∈ Q⇧0} → y›
by (metis Mndetprefix_F_subset top_greatest)
moreover have ‹… ⊑⇩F ⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a›
proof (rule mono_Mndetprefix_F, clarify, rule hyp)
show ‹ev a ∈ Q⇧0 ⟹ Q after a ∈ ℛ⇩p⇩r⇩o⇩c P› for a
by (simp add: ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› reachable_after)
next
show ‹ev a ∈ Q⇧0 ⟹ x ⊑⇩F Q after a› for a
by (frule mono_After_F[OF _ ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q›])
(simp add: After_Ndet initials_Mndetprefix image_iff After_Mndetprefix)
qed
moreover have ‹… ⊑⇩F Q›
proof (unfold failure_refine_def, safe)
show ‹(t, X) ∈ ℱ (⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a)› if ‹(t, X) ∈ ℱ Q› for t X
proof (cases t)
from initial_tick_imp_in_ticks_of ‹✓s(Q) = {}› have ‹range tick ⊆ - Q⇧0› by force
assume ‹t = []›
with ‹(t, X) ∈ ℱ Q› have ‹([], X ∪ - Q⇧0) ∈ ℱ Q›
by (metis ComplD initials_memI is_processT5_S7' self_append_conv2)
with ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q›
show ‹(t, X) ∈ ℱ (⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a)›
by (simp add: failure_refine_def F_Ndet F_SKIPS ‹t = []› F_Mndetprefix' subset_iff)
(meson Compl_iff UnI1 UnI2 ‹range tick ⊆ - Q⇧0› list.distinct(1) range_subsetD)
next
from ‹(t, X) ∈ ℱ Q› ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q› ‹{a. ev a ∈ Q⇧0} ≠ {}› ‹✓s(Q) = {}›
show ‹t = e # t' ⟹ (t, X) ∈ ℱ (⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a)› for e t'
by (simp add: failure_refine_def F_Ndet F_SKIPS F_Mndetprefix' F_After subset_iff)
(metis F_T empty_iff event⇩p⇩t⇩i⇩c⇩k.exhaust initial_tick_imp_in_ticks_of initials_memI)
qed
qed
ultimately show ‹⊓a ∈ UNIV → y ⊑⇩F Q› using trans_F by blast
qed
thus ‹✓s(P) = {} ∧ deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟹ deadlock_free P›
by (simp add: reachable_self deadlock_free⇩S⇩K⇩I⇩P⇩S_def deadlock_free_F)
qed
lemma reachable_processes_DF_UNIV_leF_imp_DF_events_of_leF :
‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ DF UNIV ⊑⇩F Q ⟹ DF α(P) ⊑⇩F Q› for Q
proof (unfold DF_def, induct arbitrary: Q rule: cont_parallel_fix_ind)
show ‹cont (λx. ⊓a ∈ UNIV → x)› by simp
next
show ‹cont (λx. ⊓a ∈ α(P) → x)› by simp
next
show ‹adm (λx. ∀Q. Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟶ fst x ⊑⇩F Q ⟶ snd x ⊑⇩F Q)› by simp
next
show ‹⋀Q. ⊥ ⊑⇩F Q› by simp
next
fix x y Q assume hyp : ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ x ⊑⇩F Q ⟹ y ⊑⇩F Q› for Q
assume ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› and ‹⊓a ∈ UNIV → x ⊑⇩F Q›
from ‹⊓a ∈ UNIV → x ⊑⇩F Q› obtain a where ‹ev a ∈ Q⇧0› by (elim leF_ev_initialE)
have ‹⊓a ∈ α(P) → y ⊑⇩F ⊓a ∈ {a. ev a ∈ Q⇧0} → y›
by (metis (mono_tags, lifting) Mndetprefix_F_subset ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P›
‹ev a ∈ Q⇧0› empty_iff events_of_reachable_processes_subset
initial_ev_imp_in_events_of mem_Collect_eq subset_iff)
moreover have ‹… ⊑⇩F ⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a›
proof (rule mono_Mndetprefix_F, clarify)
show ‹ev a ∈ Q⇧0 ⟹ y ⊑⇩F Q after a› for a
by (metis mono_After_F After_Mndetprefix UNIV_I ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P›
‹⊓a∈UNIV → x ⊑⇩F Q› hyp reachable_processes.simps)
qed
moreover have ‹… ⊑⇩F Q›
proof (unfold failure_refine_def, safe)
show ‹(t, X) ∈ ℱ (⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a)› if ‹(t, X) ∈ ℱ Q› for t X
proof (cases t)
assume ‹t = []›
with ‹(t, X) ∈ ℱ Q› have ‹([], X ∪ (- Q⇧0)) ∈ ℱ Q›
by (metis ComplD initials_memI is_processT5_S7' self_append_conv2)
from ‹⊓a ∈ UNIV → x ⊑⇩F Q› ‹([], X ∪ (- Q⇧0)) ∈ ℱ Q› have ‹¬ range ev ⊆ X ∪ - Q⇧0›
by (simp add: failure_refine_def F_Mndetprefix' subset_iff) blast
then obtain b where ‹ev b ∈ Q⇧0› ‹ev b ∉ X› by auto
with ‹t = []› ‹ev a ∈ Q⇧0› show ‹(t, X) ∈ ℱ (⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a)›
by (auto simp add: F_Mndetprefix')
next
from ‹⊓a ∈ UNIV → x ⊑⇩F Q› ‹(t, X) ∈ ℱ Q› ‹ev a ∈ Q⇧0›
show ‹t = e # t' ⟹ (t, X) ∈ ℱ (⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a)› for e t'
by (auto simp add: failure_refine_def F_Mndetprefix' F_After intro!: F_T initials_memI)
qed
qed
ultimately show ‹⊓a ∈ α(P) → y ⊑⇩F Q› using trans_F by blast
qed
lemma reachable_processes_CHAOS_UNIV_leF_imp_CHAOS_events_of_leF :
‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ CHAOS UNIV ⊑⇩F Q ⟹ CHAOS α(P) ⊑⇩F Q› for Q
proof (unfold CHAOS_def, induct arbitrary: Q rule: cont_parallel_fix_ind)
show ‹cont (λx. STOP ⊓ (□a ∈ UNIV → x))› by simp
next
show ‹cont (λx. STOP ⊓ (□a ∈ α(P) → x))› by simp
next
show ‹adm (λx. ∀Q. Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟶ fst x ⊑⇩F Q ⟶ snd x ⊑⇩F Q)› by simp
next
show ‹⋀Q. ⊥ ⊑⇩F Q› by simp
next
fix x y Q assume hyp : ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ x ⊑⇩F Q ⟹ y ⊑⇩F Q› for Q
assume ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› and ‹STOP ⊓ (□a∈UNIV → x) ⊑⇩F Q›
from ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› events_of_reachable_processes_subset initial_ev_imp_in_events_of
have ‹STOP ⊓ (□a ∈ α(P) → y) ⊑⇩F STOP ⊓ (□a ∈ {a. ev a ∈ Q⇧0} → y)›
by (fastforce simp add: failure_refine_def Ndet_projs Mprefix_projs STOP_projs)
moreover have ‹… ⊑⇩F STOP ⊓ (□a ∈ {a. ev a ∈ Q⇧0} → Q after a)›
proof (intro mono_Ndet_F[OF idem_F] mono_Mprefix_F, clarify)
show ‹ev a ∈ Q⇧0 ⟹ y ⊑⇩F Q after a› for a
by (frule mono_After_F[OF _ ‹STOP ⊓ (□a∈UNIV → x) ⊑⇩F Q›])
(simp add: After_Ndet initials_Mprefix After_Mprefix
‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› hyp reachable_after)
qed
moreover have ‹… ⊑⇩F Q›
proof (unfold failure_refine_def, safe)
from ‹STOP ⊓ (□a∈UNIV → x) ⊑⇩F Q›
show ‹(t, X) ∈ ℱ Q ⟹ (t, X) ∈ ℱ (STOP ⊓ (□a ∈ {a. ev a ∈ Q⇧0} → Q after a))› for t X
by (auto simp add: refine_defs F_Ndet F_Mprefix F_After intro!: F_T initials_memI)
qed
ultimately show ‹STOP ⊓ (□a ∈ α(P) → y) ⊑⇩F Q› using trans_F by blast
qed
lemma reachable_processes_CHAOS⇩S⇩K⇩I⇩P⇩S_UNIV_UNIV_leF_imp_CHAOS_events_of_ticks_of_leFD :
‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ CHAOS⇩S⇩K⇩I⇩P⇩S UNIV UNIV ⊑⇩F⇩D Q ⟹ CHAOS⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F⇩D Q› for Q
proof (unfold CHAOS⇩S⇩K⇩I⇩P⇩S_def, induct arbitrary: Q rule: cont_parallel_fix_ind)
show ‹cont (λx. SKIPS UNIV ⊓ STOP ⊓ (□a ∈ UNIV → x))› by simp
next
show ‹cont (λx. SKIPS ✓s(P) ⊓ STOP ⊓ (□a ∈ α(P) → x))› by simp
next
show ‹adm (λx. ∀Q. Q ∈ℛ⇩p⇩r⇩o⇩c P ⟶ fst x ⊑⇩F⇩D Q ⟶ snd x ⊑⇩F⇩D Q)› by simp
next
show ‹⋀Q. ⊥ ⊑⇩F⇩D Q› by simp
next
fix x y Q assume hyp : ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ x ⊑⇩F⇩D Q ⟹ y ⊑⇩F⇩D Q› for Q
assume ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› and ‹SKIPS UNIV ⊓ STOP ⊓ (□a ∈ UNIV → x) ⊑⇩F⇩D Q›
from ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› ticks_of_reachable_processes_subset initial_tick_imp_in_ticks_of
have ‹SKIPS ✓s(P) ⊓ STOP ⊑⇩F⇩D SKIPS {r. ✓(r) ∈ Q⇧0} ⊓ STOP›
by (fastforce simp add: refine_defs Ndet_projs STOP_projs SKIPS_projs)
moreover from ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› events_of_reachable_processes_subset initial_ev_imp_in_events_of
have ‹STOP ⊓ (□a ∈ α(P) → y) ⊑⇩F⇩D STOP ⊓ (□a ∈ {a. ev a ∈ Q⇧0} → y)›
by (fastforce simp add: refine_defs Ndet_projs STOP_projs Mprefix_projs)
ultimately have ‹SKIPS ✓s(P) ⊓ STOP ⊓ (□a ∈ α(P) → y) ⊑⇩F⇩D
SKIPS {r. ✓(r) ∈ Q⇧0} ⊓ STOP ⊓ (□a ∈ {a. ev a ∈ Q⇧0} → y)›
by (auto simp add: refine_defs Ndet_projs)
moreover have ‹… ⊑⇩F⇩D SKIPS {r. ✓(r) ∈ Q⇧0} ⊓ STOP ⊓ (□a ∈ {a. ev a ∈ Q⇧0} → Q after a)›
proof (intro mono_Ndet_FD[OF idem_FD] mono_Mprefix_FD, clarify)
show ‹ev a ∈ Q⇧0 ⟹ y ⊑⇩F⇩D Q after a› for a
by (frule mono_After_FD[OF _ ‹SKIPS UNIV ⊓ STOP ⊓ (□a ∈ UNIV → x) ⊑⇩F⇩D Q›])
(simp add: After_Ndet initials_Mprefix initials_Ndet image_iff
After_Mprefix ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› hyp reachable_after)
qed
moreover have ‹… ⊑⇩F⇩D Q›
proof (unfold refine_defs, safe)
from ‹SKIPS UNIV ⊓ STOP ⊓ (□a ∈ UNIV → x) ⊑⇩F⇩D Q›
show ‹t ∈ 𝒟 Q ⟹ t ∈ 𝒟 (SKIPS {r. ✓(r) ∈ Q⇧0} ⊓ STOP ⊓ (□a ∈ {a. ev a ∈ Q⇧0} → Q after a))› for t
by (auto simp add: refine_defs D_Ndet D_Mprefix D_STOP D_After D_SKIPS)
(use D_T initials_memI in blast)
next
from ‹SKIPS UNIV ⊓ STOP ⊓ (□a ∈ UNIV → x) ⊑⇩F⇩D Q›
show ‹(t, X) ∈ ℱ Q ⟹ (t, X) ∈ ℱ (SKIPS {r. ✓(r) ∈ Q⇧0} ⊓ STOP ⊓ (□a ∈ {a. ev a ∈ Q⇧0} → Q after a))› for t X
by (cases t, simp_all add: refine_defs F_Ndet F_Mprefix F_After F_SKIPS F_STOP)
(use F_T initials_memI in blast)
qed
ultimately show ‹SKIPS ✓s(P) ⊓ STOP ⊓ (□a ∈ α(P) → y) ⊑⇩F⇩D Q› by force
qed
theorem deadlock_free_iff_DF_events_of_leF :
‹deadlock_free P ⟷ α(P) ≠ {} ∧ DF α(P) ⊑⇩F P›
proof (intro iffI conjI)
show ‹α(P) ≠ {} ∧ DF α(P) ⊑⇩F P ⟹ deadlock_free P›
by (meson DF_Univ_freeness deadlock_free_F order_refl trans_F)
next
show ‹deadlock_free P ⟹ α(P) ≠ {}› by (simp add: nonempty_events_of_if_deadlock_free)
next
show ‹deadlock_free P ⟹ DF α(P) ⊑⇩F P›
by (simp add: deadlock_free_F reachable_self
reachable_processes_DF_UNIV_leF_imp_DF_events_of_leF)
qed
corollary deadlock_free_iff_DF_events_of_leFD :
‹deadlock_free P ⟷ α(P) ≠ {} ∧ DF α(P) ⊑⇩F⇩D P›
by (metis deadlock_free_iff_DF_events_of_leF deadlock_free_def div_free_DF
divergence_refine_def failure_divergence_refine_def)
corollary deadlock_free_iff_DF_strict_events_of_leF :
‹deadlock_free P ⟷ ❙α(P) ≠ {} ∧ DF ❙α(P) ⊑⇩F P›
by (metis anti_mono_events_of_F deadlock_free_iff_DF_events_of_leF
deadlock_free_implies_div_free events_of_DF events_of_is_strict_events_of_or_UNIV
order_class.order_eq_iff strict_events_of_subset_events_of)
corollary deadlock_free_iff_DF_strict_events_of_leFD :
‹deadlock_free P ⟷ ❙α(P) ≠ {} ∧ DF ❙α(P) ⊑⇩F⇩D P›
by (metis DF_Univ_freeness deadlock_free_iff_DF_events_of_leFD
deadlock_free_implies_div_free events_of_is_strict_events_of_or_UNIV)
theorem lifelock_free_iff_CHAOS_events_of_leF :
‹lifelock_free P ⟷ CHAOS α(P) ⊑⇩F P›
proof (intro iffI conjI)
show ‹CHAOS α(P) ⊑⇩F P ⟹ lifelock_free P›
by (meson CHAOS_subset_FD lifelock_free_def non_terminating_F
non_terminating_FD top_greatest trans_F)
next
show ‹lifelock_free P ⟹ CHAOS α(P) ⊑⇩F P›
by (simp add: leFD_imp_leF lifelock_free_def reachable_self
reachable_processes_CHAOS_UNIV_leF_imp_CHAOS_events_of_leF)
qed
corollary lifelock_free_iff_CHAOS_strict_events_of_leF :
‹lifelock_free P ⟷ CHAOS ❙α(P) ⊑⇩F P›
by (metis anti_mono_ticks_of_F bot.extremum_uniqueI empty_not_UNIV
events_of_is_strict_events_of_or_UNIV lifelock_free_iff_CHAOS_events_of_leF
ticks_CHAOS ticks_of_is_strict_ticks_of_or_UNIV)
corollary lifelock_free_iff_CHAOS_events_of_leFD :
‹lifelock_free P ⟷ CHAOS α(P) ⊑⇩F⇩D P›
by (metis div_free_CHAOS divergence_refine_def failure_divergence_refine_def
lifelock_free_def lifelock_free_iff_CHAOS_events_of_leF)
corollary lifelock_free_iff_CHAOS_strict_events_of_leFD :
‹lifelock_free P ⟷ CHAOS ❙α(P) ⊑⇩F⇩D P›
by (metis anti_mono_events_of_F antisym events_of_CHAOS leFD_imp_leF
lifelock_free_iff_CHAOS_events_of_leFD
lifelock_free_iff_CHAOS_strict_events_of_leF strict_events_of_subset_events_of)
theorem lifelock_free⇩S⇩K⇩I⇩P⇩S_iff_CHAOS⇩S⇩K⇩I⇩P⇩S_events_of_ticks_of_FD :
‹lifelock_free⇩S⇩K⇩I⇩P⇩S P ⟷ CHAOS⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F⇩D P›
proof (intro iffI)
show ‹CHAOS⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F⇩D P ⟹ lifelock_free⇩S⇩K⇩I⇩P⇩S P›
by (metis events_of_is_strict_events_of_or_UNIV lifelock_free⇩S⇩K⇩I⇩P⇩S_def
lifelock_free⇩S⇩K⇩I⇩P⇩S_iff_div_free ticks_of_is_strict_ticks_of_or_UNIV)
next
show ‹lifelock_free⇩S⇩K⇩I⇩P⇩S P ⟹ CHAOS⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F⇩D P›
by (simp add: lifelock_free⇩S⇩K⇩I⇩P⇩S_def reachable_self
reachable_processes_CHAOS⇩S⇩K⇩I⇩P⇩S_UNIV_UNIV_leF_imp_CHAOS_events_of_ticks_of_leFD)
qed
corollary lifelock_free⇩S⇩K⇩I⇩P⇩S_iff_CHAOS⇩S⇩K⇩I⇩P⇩S_strict_events_of_strict_ticks_of_FD :
‹lifelock_free⇩S⇩K⇩I⇩P⇩S P ⟷ CHAOS⇩S⇩K⇩I⇩P⇩S ❙α(P) ❙✓❙s(P) ⊑⇩F⇩D P›
by (metis (no_types) anti_mono_events_of_FD anti_mono_ticks_of_FD events_of_CHAOS⇩S⇩K⇩I⇩P⇩S
events_of_is_strict_events_of_or_UNIV lifelock_free⇩S⇩K⇩I⇩P⇩S_iff_CHAOS⇩S⇩K⇩I⇩P⇩S_events_of_ticks_of_FD
lifelock_free⇩S⇩K⇩I⇩P⇩S_iff_div_free ticks_CHAOS⇩S⇩K⇩I⇩P⇩S ticks_of_is_strict_ticks_of_or_UNIV top.extremum_uniqueI)
theorem deadlock_free⇩S⇩K⇩I⇩P⇩S_iff_DF⇩S⇩K⇩I⇩P⇩S_events_of_ticks_of_leF :
‹deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷ ( if α(P) = {} ∧ ✓s(P) = {} then False
else if ✓s(P) = {} then DF α(P) ⊑⇩F P
else if α(P) = {} then SKIPS ✓s(P) ⊑⇩F P
else DF⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F P)›
(is ‹_ ⟷ ?rhs›)
proof (split if_split, intro conjI impI)
from deadlock_free_iff_empty_ticks_of_and_deadlock_free⇩S⇩K⇩I⇩P⇩S nonempty_events_of_if_deadlock_free
show ‹α(P) = {} ∧ ✓s(P) = {} ⟹ deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷ False› by blast
next
assume ‹¬ (α(P) = {} ∧ ✓s(P) = {})›
show ‹deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷
( if ✓s(P) = {} then DF α(P) ⊑⇩F P
else if α(P) = {} then SKIPS ✓s(P) ⊑⇩F P else DF⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F P)›
proof (split if_split, intro conjI impI)
from ‹¬ (α(P) = {} ∧ ✓s(P) = {})› deadlock_free_iff_DF_events_of_leF
deadlock_free_iff_empty_ticks_of_and_deadlock_free⇩S⇩K⇩I⇩P⇩S
show ‹✓s(P) = {} ⟹ deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷ DF α(P) ⊑⇩F P› by blast
next
show ‹deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷
(if α(P) = {} then SKIPS ✓s(P) ⊑⇩F P else DF⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F P)› if ‹✓s(P) ≠ {}›
proof (split if_split, intro conjI impI)
assume ‹α(P) = {}›
with initial_ev_imp_in_events_of have ‹range ev ⊆ - P⇧0› by force
show ‹deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷ SKIPS ✓s(P) ⊑⇩F P›
proof (rule iffI)
show ‹SKIPS ✓s(P) ⊑⇩F P ⟹ deadlock_free⇩S⇩K⇩I⇩P⇩S P›
by (metis deadlock_free⇩S⇩K⇩I⇩P⇩S_SKIPS deadlock_free⇩S⇩K⇩I⇩P⇩S_def ‹✓s(P) ≠ {}› trans_F)
next
show ‹SKIPS ✓s(P) ⊑⇩F P› if ‹deadlock_free⇩S⇩K⇩I⇩P⇩S P›
proof (unfold failure_refine_def, safe)
show ‹(t, X) ∈ ℱ (SKIPS ✓s(P))› if ‹(t, X) ∈ ℱ P› for t X
proof (cases t)
assume ‹t = []›
with ‹(t, X) ∈ ℱ P› have ‹(t, X ∪ - P⇧0) ∈ ℱ P›
by (metis ComplD initials_memI is_processT5_S7' self_append_conv2)
with ‹deadlock_free⇩S⇩K⇩I⇩P⇩S P› have ‹(t, X ∪ - P⇧0) ∈ ℱ (DF⇩S⇩K⇩I⇩P⇩S UNIV UNIV)›
by (auto simp add: deadlock_free⇩S⇩K⇩I⇩P⇩S_def failure_refine_def)
with ‹range ev ⊆ - P⇧0› ‹✓s(P) ≠ {}› show ‹(t, X) ∈ ℱ (SKIPS ✓s(P))›
by (subst (asm) DF⇩S⇩K⇩I⇩P⇩S_unfold)
(auto simp add: F_Ndet F_Mndetprefix' F_SKIPS ‹t = []›
intro: initial_tick_imp_in_ticks_of)
next
fix e t' assume ‹t = e # t'›
with F_T ‹(t, X) ∈ ℱ P› ‹α(P) = {}› obtain r where ‹r ∈ ✓s(P)› ‹e = ✓(r)› ‹t' = []›
by (metis F_imp_front_tickFree empty_iff event⇩p⇩t⇩i⇩c⇩k.exhaust events_of_memI
front_tickFree_Cons_iff initial_tick_imp_in_ticks_of
initials_memI is_ev_def list.set_intros(1))
thus ‹(t, X) ∈ ℱ (SKIPS ✓s(P))›
by (simp add: F_Mndetprefix' F_SKIPS ‹✓s(P) ≠ {}› ‹t = e # t'›)
qed
qed
qed
next
show ‹deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷ DF⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F P› if ‹α(P) ≠ {}›
proof (rule iffI)
show ‹DF⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F P ⟹ deadlock_free⇩S⇩K⇩I⇩P⇩S P›
by (meson DF⇩S⇩K⇩I⇩P⇩S_subset ‹✓s(P) ≠ {}› ‹α(P) ≠ {}›
deadlock_free⇩S⇩K⇩I⇩P⇩S_def leFD_imp_leF subset_UNIV that trans_F)
next
have ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ DF⇩S⇩K⇩I⇩P⇩S UNIV UNIV ⊑⇩F Q ⟹ DF⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F Q› for Q
proof (unfold DF⇩S⇩K⇩I⇩P⇩S_def, induct arbitrary: Q rule: cont_parallel_fix_ind)
show ‹cont (λx. (⊓a ∈ UNIV → x) ⊓ SKIPS UNIV)› by simp
next
show ‹cont (λx. (⊓a ∈ α(P) → x) ⊓ SKIPS ✓s(P))› by simp
next
show ‹adm (λx. ∀Q. Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟶ fst x ⊑⇩F Q ⟶ snd x ⊑⇩F Q)› by simp
next
show ‹⋀Q. ⊥ ⊑⇩F Q› by simp
next
fix x y Q assume hyp : ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ x ⊑⇩F Q ⟹ y ⊑⇩F Q› for Q
assume ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› and ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q›
consider ‹{a. ev a ∈ Q⇧0} = {}› ‹{r. ✓(r) ∈ Q⇧0} = {}›
| ‹{a. ev a ∈ Q⇧0} = {}› ‹{r. ✓(r) ∈ Q⇧0} ≠ {}›
| ‹{a. ev a ∈ Q⇧0} ≠ {}› by blast
thus ‹(⊓a ∈ α(P) → y) ⊓ SKIPS ✓s(P) ⊑⇩F Q›
proof cases
assume ‹{a. ev a ∈ Q⇧0} = {}› ‹{r. ✓(r) ∈ Q⇧0} = {}›
hence ‹Q⇧0 = {}› by (metis Collect_empty_eq all_not_in_conv event⇩p⇩t⇩i⇩c⇩k.exhaust)
hence ‹Q = STOP› by (simp add: initials_empty_iff_STOP)
with ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q› have False
by (auto simp add: failure_refine_def Process_eq_spec
F_STOP F_Ndet F_Mndetprefix' F_SKIPS)
thus ‹(⊓a ∈ α(P) → y) ⊓ SKIPS ✓s(P) ⊑⇩F Q› ..
next
assume ‹{a. ev a ∈ Q⇧0} = {}› ‹{r. ✓(r) ∈ Q⇧0} ≠ {}›
have ‹SKIPS {r. ✓(r) ∈ Q⇧0} ⊑⇩F Q›
proof (unfold failure_refine_def, safe)
show ‹(t, X) ∈ ℱ (SKIPS {r. ✓(r) ∈ Q⇧0})› if ‹(t, X) ∈ ℱ Q› for t X
proof (cases t)
assume ‹t = []›
with ‹(t, X) ∈ ℱ Q› have ‹([], X ∪ - Q⇧0) ∈ ℱ Q›
by (metis ComplD initials_memI is_processT5_S7' self_append_conv2)
with ‹t = []› ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q› ‹{a. ev a ∈ Q⇧0} = {}›
show ‹(t, X) ∈ ℱ (SKIPS {r. ✓(r) ∈ Q⇧0})›
by (simp add: failure_refine_def F_Ndet F_Mndetprefix' F_SKIPS subset_iff)
(metis Compl_iff Un_iff neq_Nil_conv)
next
from ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q› ‹{a. ev a ∈ Q⇧0} = {}›
‹(t, X) ∈ ℱ Q› F_T initials_memI
show ‹t = e # t' ⟹ (t, X) ∈ ℱ (SKIPS {r. ✓(r) ∈ Q⇧0})› for e t'
by (simp add: failure_refine_def F_Ndet F_Mndetprefix' F_SKIPS) blast
qed
qed
moreover from ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› ‹{r. ✓(r) ∈ Q⇧0} ≠ {}› initial_tick_imp_in_ticks_of
ticks_of_reachable_processes_subset
have ‹SKIPS ✓s(P) ⊑⇩F SKIPS {r. ✓(r) ∈ Q⇧0}›
by (force simp add: SKIPS_F_SKIPS_iff ‹✓s(P) ≠ {}›)
ultimately show ‹(⊓a ∈ α(P) → y) ⊓ SKIPS ✓s(P) ⊑⇩F Q›
using Ndet_F_self_right trans_F by blast
next
assume ‹{a. ev a ∈ Q⇧0} ≠ {}›
from ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› initial_tick_imp_in_ticks_of ticks_of_reachable_processes_subset
have ‹{r. ✓(r) ∈ Q⇧0} ⊆ ✓s(P)› by force
from ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› events_of_reachable_processes_subset initial_ev_imp_in_events_of
have ‹(⊓a ∈ α(P) → y) ⊓ SKIPS ✓s(P) ⊑⇩F (⊓a ∈ {a. ev a ∈ Q⇧0} → y) ⊓ SKIPS ✓s(P)›
by (force intro: mono_Ndet_F[OF Mndetprefix_F_subset[OF ‹{a. ev a ∈ Q⇧0} ≠ {}›] idem_F])
moreover have ‹… ⊑⇩F (⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a) ⊓ SKIPS ✓s(P)›
proof (rule mono_Ndet_F[OF mono_Mndetprefix_F idem_F], clarify)
show ‹ev a ∈ Q⇧0 ⟹ y ⊑⇩F Q after a› for a
by (frule mono_After_F[OF _ ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q›])
(simp add: After_Ndet initials_Mndetprefix image_iff
After_Mndetprefix reachable_after ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P› hyp)
qed
moreover have ‹… ⊑⇩F Q›
proof (unfold failure_refine_def, safe)
show ‹(t, X) ∈ ℱ ((⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a) ⊓ SKIPS ✓s(P))› if ‹(t, X) ∈ ℱ Q› for t X
proof (cases t)
assume ‹t = []›
with ‹(t, X) ∈ ℱ Q› have ‹([], X ∪ - Q⇧0) ∈ ℱ Q›
by (metis ComplD eq_Nil_appendI initials_memI' is_processT5_S7')
with ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q› ‹{r. ✓(r) ∈ Q⇧0} ⊆ ✓s(P)›
show ‹(t, X) ∈ ℱ ((⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a) ⊓ SKIPS ✓s(P))›
by (simp add: failure_refine_def F_Ndet F_Mndetprefix' ‹t = []› F_SKIPS ‹✓s(P) ≠ {}› subset_iff)
(meson ComplI UnI1 UnI2 list.distinct(1))
next
from ‹(t, X) ∈ ℱ Q› ‹(⊓a ∈ UNIV → x) ⊓ SKIPS UNIV ⊑⇩F Q› ‹{r. ✓(r) ∈ Q⇧0} ⊆ ✓s(P)›
show ‹t = e # t' ⟹ (t, X) ∈ ℱ ((⊓a ∈ {a. ev a ∈ Q⇧0} → Q after a) ⊓ SKIPS ✓s(P))› for e t'
by (simp add: failure_refine_def F_Ndet F_Mndetprefix' F_SKIPS F_After ‹✓s(P) ≠ {}› subset_iff)
(metis F_T initials_memI list.distinct(1) list.inject)
qed
qed
ultimately show ‹(⊓a ∈ α(P) → y) ⊓ SKIPS ✓s(P) ⊑⇩F Q› using trans_F by blast
qed
qed
thus ‹deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟹ DF⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F P›
by (simp add: deadlock_free⇩S⇩K⇩I⇩P⇩S_def reachable_self)
qed
qed
qed
qed
corollary deadlock_free⇩S⇩K⇩I⇩P⇩S_iff_DF⇩S⇩K⇩I⇩P⇩S_events_of_ticks_of_leFD :
‹deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷ ( if α(P) = {} ∧ ✓s(P) = {} then False
else if ✓s(P) = {} then DF α(P) ⊑⇩F⇩D P
else if α(P) = {} then SKIPS ✓s(P) ⊑⇩F⇩D P
else DF⇩S⇩K⇩I⇩P⇩S α(P) ✓s(P) ⊑⇩F⇩D P)›
by (metis deadlock_free⇩S⇩K⇩I⇩P⇩S_iff_DF⇩S⇩K⇩I⇩P⇩S_events_of_ticks_of_leF D_SKIPS deadlock_free⇩S⇩K⇩I⇩P⇩S_FD
div_free_DF div_free_DF⇩S⇩K⇩I⇩P⇩S divergence_refine_def failure_divergence_refine_def)
corollary deadlock_free⇩S⇩K⇩I⇩P⇩S_iff_DF⇩S⇩K⇩I⇩P⇩S_strict_events_of_strict_ticks_of_leF :
‹deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷ ( if ❙α(P) = {} ∧ ❙✓❙s(P) = {} then False
else if ❙✓❙s(P) = {} then DF ❙α(P) ⊑⇩F P
else if ❙α(P) = {} then SKIPS ❙✓❙s(P) ⊑⇩F P
else DF⇩S⇩K⇩I⇩P⇩S ❙α(P) ❙✓❙s(P) ⊑⇩F P)›
by (simp add: deadlock_free⇩S⇩K⇩I⇩P⇩S_iff_DF⇩S⇩K⇩I⇩P⇩S_events_of_ticks_of_leF
events_of_is_strict_events_of_or_UNIV ticks_of_is_strict_ticks_of_or_UNIV)
(meson deadlock_free_iff_DF_strict_events_of_leF DF⇩S⇩K⇩I⇩P⇩S_subset deadlock_free⇩S⇩K⇩I⇩P⇩S_SKIPS
deadlock_free⇩S⇩K⇩I⇩P⇩S_def deadlock_free⇩S⇩K⇩I⇩P⇩S_implies_div_free trans_F
deadlock_free_implies_div_free failure_divergence_refine_def subset_UNIV)
corollary deadlock_free⇩S⇩K⇩I⇩P⇩S_iff_DF⇩S⇩K⇩I⇩P⇩S_strict_events_of_strict_ticks_of_leFD :
‹deadlock_free⇩S⇩K⇩I⇩P⇩S P ⟷ ( if ❙α(P) = {} ∧ ❙✓❙s(P) = {} then False
else if ❙✓❙s(P) = {} then DF ❙α(P) ⊑⇩F⇩D P
else if ❙α(P) = {} then SKIPS ❙✓❙s(P) ⊑⇩F⇩D P
else DF⇩S⇩K⇩I⇩P⇩S ❙α(P) ❙✓❙s(P) ⊑⇩F⇩D P)›
by (metis deadlock_free⇩S⇩K⇩I⇩P⇩S_iff_DF⇩S⇩K⇩I⇩P⇩S_events_of_ticks_of_leFD
deadlock_free⇩S⇩K⇩I⇩P⇩S_iff_DF⇩S⇩K⇩I⇩P⇩S_strict_events_of_strict_ticks_of_leF
deadlock_free⇩S⇩K⇩I⇩P⇩S_implies_div_free events_of_is_strict_events_of_or_UNIV
leFD_imp_leF ticks_of_is_strict_ticks_of_or_UNIV)
subsection ‹Big results›
text ‹As consequences, we have very powerful results,
and especially a ``data independence'' deadlock freeness theorem.›
lemma deadlock_free_is_right:
‹deadlock_free P ⟷ (∀t ∈ 𝒯 P. tF t ∧ (t, UNIV) ∉ ℱ P)›
‹deadlock_free P ⟷ (∀t ∈ 𝒯 P. tF t ∧ (t, ev ` UNIV) ∉ ℱ P)›
proof -
from deadlock_free_iff_empty_ticks_of_and_deadlock_free⇩S⇩K⇩I⇩P⇩S
deadlock_free⇩S⇩K⇩I⇩P⇩S_is_right tickFree_traces_iff_empty_ticks_of
show ‹deadlock_free P ⟷ (∀t ∈ 𝒯 P. tF t ∧ (t, UNIV) ∉ ℱ P)› by blast
thus ‹deadlock_free P ⟷ (∀t ∈ 𝒯 P. tF t ∧ (t, ev ` UNIV) ∉ ℱ P)›
by (auto intro: is_processT4)
(metis After⇩t⇩r⇩a⇩c⇩e.simps(1) deadlock_free_After⇩t⇩i⇩c⇩k_characterization
F_imp_R_After⇩t⇩r⇩a⇩c⇩e deadlock_free_After⇩t⇩r⇩a⇩c⇩e_characterization)
qed
end
theorem data_independence_deadlock_free_Sync:
fixes P Q :: ‹('a, 'r) process⇩p⇩t⇩i⇩c⇩k›
assumes df_P : ‹deadlock_free P› and df_Q : ‹deadlock_free Q›
and hyp : ‹events_of Q ∩ S = {} ∨ (∃y. events_of Q ∩ S = {y} ∧ events_of P ∩ S ⊆ {y})›
shows ‹deadlock_free (P ⟦S⟧ Q)›
proof -
have non_BOT : ‹P ≠ ⊥› ‹Q ≠ ⊥›
by (simp_all add: BOT_iff_Nil_D deadlock_free_implies_div_free df_P df_Q)
have nonempty_events : ‹events_of P ≠ {}› ‹events_of Q ≠ {}›
by (simp_all add: df_P df_Q nonempty_events_of_if_deadlock_free)
obtain a b where initial : ‹ev a ∈ P⇧0› ‹ev b ∈ Q⇧0›
by (meson deadlock_free_initial_evE df_P df_Q)
have ‹ev a ∈ (P ⟦S⟧ Q)⇧0 ∨ ev b ∈ (P ⟦S⟧ Q)⇧0›
by (simp add: initials_Sync non_BOT image_iff)
(metis events_of_iff_reachable_ev reachable_ev.intros(1)
Int_iff initial empty_iff hyp insert_iff subset_singleton_iff)
hence nonempty_events_Sync: ‹α(P ⟦S⟧ Q) ≠ {}›
by (metis events_of_iff_reachable_ev empty_iff reachable_ev.intros(1))
have * : ‹DF (α(P) ∪ α(Q)) ⊑⇩F⇩D DF α(P) ⟦S⟧ DF α(Q)›
by (simp add: DF_FD_DF_Sync_DF hyp nonempty_events)
also have ‹… ⊑⇩F⇩D P ⟦S⟧ Q›
by (meson deadlock_free_iff_DF_events_of_leFD df_P df_Q mono_Sync_FD)
ultimately show ‹deadlock_free (P ⟦S⟧ Q)›
by (meson DF_Univ_freeness Un_empty nonempty_events(1) trans_FD)
qed
lemma data_independence_deadlock_free_Sync_bis:
‹⟦deadlock_free P; deadlock_free Q; α(Q) ∩ S = {}⟧ ⟹
deadlock_free (P ⟦S⟧ Q)› for P :: ‹('a, 'r) process⇩p⇩t⇩i⇩c⇩k›
by (simp add: data_independence_deadlock_free_Sync)
text ‹We can't expect much better without hypothesis on the processes \<^term>‹P› and \<^term>‹Q›.
We can easily build the following counter example.›
lemma ‹∃P Q S. deadlock_free P ∧ deadlock_free Q ∧
(∃y z. events_of Q ∩ S ⊆ {y, z} ∧ events_of P ∩ S ⊆ {y, z}) ∧
¬ deadlock_free (P ⟦S :: nat set⟧ Q)›
proof (intro exI conjI)
show ‹deadlock_free (DF {0})› and ‹deadlock_free (DF {Suc 0})›
by (metis DF_Univ_freeness empty_not_insert idem_FD)+
next
show ‹events_of (DF {Suc 0}) ∩ {0, Suc 0} ⊆ {0, Suc 0}›
and ‹events_of (DF {0}) ∩ {0, Suc 0} ⊆ {0, Suc 0}› by simp_all
next
have ‹DF {0} ⟦{0, Suc 0}⟧ DF {Suc 0} = STOP›
by (simp add: initials_empty_iff_STOP[symmetric]
initials_Sync initials_DF BOT_iff_Nil_D div_free_DF)
from this[THEN arg_cong[where f = deadlock_free]]
show ‹¬ deadlock_free (DF {0} ⟦{0, Suc 0}⟧ DF {Suc 0})›
by (simp add: non_deadlock_free_STOP)
qed
end
find_theorems name: data_independence_deadlock_free_Sync_bis
subsection ‹Results with other references Processes ›
subsubsection ‹\<^const>‹RUN› and \<^const>‹non_terminating››
lemma non_terminating_STOP [simp] : ‹non_terminating STOP›
unfolding non_terminating_def by simp
lemma not_non_terminating_SKIP [simp]: ‹¬ non_terminating (SKIP r)›
unfolding non_terminating_is_right by (simp add: T_SKIP)
lemma not_non_terminating_BOT [simp] : ‹¬ non_terminating ⊥›
unfolding non_terminating_is_right T_BOT
using front_tickFree_single non_tickFree_tick by (metis mem_Collect_eq)
context AfterExt begin
lemma non_terminating_iff_RUN_events_T:
‹non_terminating P ⟷ RUN α(P) ⊑⇩T P› for P :: ‹('a, 'r) process⇩p⇩t⇩i⇩c⇩k›
proof (intro iffI)
have RUN_subset_T: ‹(A :: 'a set) ⊆ B ⟹ RUN B ⊑⇩T RUN A› for A B
by (drule RUN_subset_DT, unfold trace_divergence_refine_def, elim conjE, assumption)
show ‹RUN (events_of P) ⊑⇩T P ⟹ non_terminating P›
unfolding non_terminating_def by (meson RUN_subset_T UNIV_I subsetI trans_T)
next
assume non_terminating_P: ‹non_terminating P›
have ‹Q ∈ ℛ⇩p⇩r⇩o⇩c P ⟹ RUN (events_of P) ⊑⇩T Q› for Q
proof (unfold RUN_def, induct rule: reachable_processes_fix_ind_T)
show ‹cont (λx. □e ∈ events_of P → x)› by simp
next
fix x s
assume hyp: ‹∀Q ∈ ℛ⇩p⇩r⇩o⇩c P. x ⊑⇩T Q›
show ‹s ∈ 𝒯 P ⟹ tickFree s ⟹ □e ∈ events_of P → x ⊑⇩T P after⇩𝒯 s›
proof (unfold trace_refine_def, safe)
show ‹s ∈ 𝒯 P ⟹ tickFree s ⟹ t ∈ 𝒯 (P after⇩𝒯 s) ⟹
t ∈ 𝒯 (□e ∈ events_of P → x)› for t
proof (induct t arbitrary: s)
show ‹[] ∈ 𝒯 (□e∈events_of P → x)› by simp
next
case (Cons e t)
from Cons.prems(1, 2) have * : ‹P after⇩𝒯 s ∈ ℛ⇩p⇩r⇩o⇩c P›
by (auto simp add: reachable_processes_is)
obtain e' where ** : ‹e = ev e'› ‹e' ∈ events_of P›
by (meson Cons.prems(1, 3) initials_memI imageE
non_terminating_P initials_After⇩t⇩r⇩a⇩c⇩e_subset_events_of set_mp)
from Cons.prems T_After⇩t⇩r⇩a⇩c⇩e "**"(1)
have ‹t ∈ 𝒯 (P after⇩𝒯 (s @ [e]))› by (simp add: T_After⇩t⇩r⇩a⇩c⇩e_eq)
also have ‹… ⊆ 𝒯 x›
apply (rule hyp[rule_format, unfolded trace_refine_def,
of ‹P after⇩𝒯 (s @ [e])›, simplified])
apply (simp add: After⇩t⇩r⇩a⇩c⇩e_snoc "**"(1) After⇩t⇩i⇩c⇩k_def)
apply (rule reachable_after[OF "*" ])
using Cons.prems(3) initials_memI F_T "**"(1) by blast
finally have ‹t ∈ 𝒯 x› .
with "**" show ?case by (auto simp add: T_Mprefix)
qed
qed
qed
with reachable_self show ‹RUN α(P) ⊑⇩T P› by blast
qed
lemma lifelock_free_F: ‹lifelock_free P ⟷ CHAOS UNIV ⊑⇩F P›
by (simp add: lifelock_free_is_non_terminating non_terminating_F)
end
end