text‹Traces extend transitions to finitely many intermediate events.›
theory Trace imports "HOL-Library.Sublist"
Distributed_System
begin
context distributed_system
begin
text‹We can think of a trace as the transitive closure of the next
. A trace consists of initial and final configurations $c$ and
c'$, with an ordered list of events $t$ occurring sequentially on $c$,
$c'$.›
inductive (in distributed_system) trace where
tr_init: "trace c [] c"
| tr_step: "[ c ⊨ ev ↦ c'; trace c' t c'' ] ==> trace c (ev # t) c''"
subsection‹Properties of traces›
lemma trace_trans: shows "[ trace c t c'; trace c' t' c'' ]==> trace c (t @ t') c''" proof (induct c t c' rule:trace.induct) case tr_init thenshow ?caseby simp next case tr_step thenshow ?caseusing trace.tr_step by auto qed
lemma trace_decomp_head: assumes "trace c (ev # t) c'" shows "∃c''. c ⊨ ev ↦ c'' ∧ trace c'' t c'" using assms trace.simps by blast
lemma trace_decomp_tail: shows "trace c (t @ [ev]) c' ==>∃c''. trace c t c'' ∧ c'' ⊨ ev ↦ c'" proof (induct t arbitrary: c) case Nil thenshow ?case by (metis (mono_tags, lifting) append_Nil distributed_system.trace.simps distributed_system_axioms list.discI list.sel(1) list.sel(3)) next case (Cons ev' t) thenobtain d where step: "c ⊨ ev' ↦ d"and"trace d (t @ [ev]) c'"using trace_decomp_head by force thenobtain d' where tr: "trace d t d'"and"d' ⊨ ev ↦ c'"using Cons.hyps by blast moreoverhave"trace c (ev' # t) d'"using step tr trace.tr_step by simp ultimatelyshow ?caseby auto qed
lemma trace_snoc: assumes "trace c t c'"and "c' ⊨ ev ↦ c''" shows "trace c (t @ [ev]) c''" using assms(1) assms(2) tr_init tr_step trace_trans by auto
lemma trace_rev_induct [consumes 1, case_names tr_rev_init tr_rev_step]: "[ trace c t c'; (∧c. P c [] c); (∧c t c' ev c''. trace c t c' ==> P c t c' ==> c' ⊨ ev ↦ c'' ==> P c (t @ [ev]) c'') ]==> P c t c'" proof (induct t arbitrary: c' rule:rev_induct) case Nil thenshow ?case using distributed_system.trace.cases distributed_system_axioms by blast next case (snoc ev t) thenobtain c'' where"trace c t c''""c'' ⊨ ev ↦ c'"using trace_decomp_tail by blast thenshow ?caseusing snoc by simp qed
lemma trace_and_start_determines_end: shows "trace c t c' ==> trace c t d' ==> c' = d'" proof (induct c t c' arbitrary: d' rule:trace_rev_induct) case tr_rev_init thenshow ?caseusing trace.cases by fastforce next case (tr_rev_step c t c' ev c'') thenobtain d'' where"trace c t d''""d'' ⊨ ev ↦ d'"using trace_decomp_tail by blast thenshow ?caseusing tr_rev_step state_and_event_determine_next by simp qed
lemma suffix_split_trace: shows "[ trace c t c'; suffix t' t ]==>∃c''. trace c'' t' c'" proof (induct t arbitrary: c) case Nil thenhave"t' = []"by simp thenhave"trace c' t' c'"using tr_init by simp thenshow ?caseby blast next case (Cons ev t'') from Cons.prems have q: "suffix t' t'' ∨ t' = ev # t''"by (meson suffix_Cons) thus ?case proof (cases "suffix t' t''") case True thenshow ?thesis using Cons.hyps Cons.prems(1) trace.simps by blast next case False hence"t' = ev # t''"using q by simp thus ?thesis using Cons.hyps Cons.prems by blast qed qed
lemma prefix_split_trace: fixes
c :: "('p, 's, 'm) configuration"and
t :: "('p, 's, 'm) trace" shows "[∃c'. trace c t c'; prefix t' t ]==>∃c''. trace c t' c''" proof (induct t rule:rev_induct) case Nil thenshow ?caseby simp next case (snoc ev t'') from snoc.prems have q: "prefix t' t'' ∨ t' = t'' @ [ev]"by auto thus ?case proof (cases "prefix t' t''") case True thus ?thesis using trace_decomp_tail using snoc.hyps snoc.prems(1) trace.simps by blast next case False thus ?thesis using q snoc.prems by fast qed qed
lemma split_trace: shows "[ trace c t c'; t = t' @ t'' ]==>∃c''. trace c t' c'' ∧ trace c'' t'' c'" proof (induct t'' arbitrary: t') case Nil thenshow ?caseusing tr_init by auto next case (Cons ev t'') obtain c'' where p: "trace c (t' @ [ev]) c''" using Cons.prems prefix_split_trace rotate1.simps(2) by force thenhave"trace c'' t'' c'" using Cons.hyps Cons.prems trace_and_start_determines_end by force thenshow ?case by (meson distributed_system.tr_step distributed_system.trace_decomp_tail distributed_system_axioms p) qed
definition construct_fun_from_rel :: "('a * 'b) set ==> 'a ==> 'b"where "construct_fun_from_rel R x = (THE y. (x,y) ∈ R)"
definition trace_rel where "trace_rel ≡ {((x, t'), y). trace x t' y}"
lemma fun_must_admit_trace: shows "single_valued R ==> x ∈ Domain R ==> (x, construct_fun_from_rel R x) ∈ R" unfolding construct_fun_from_rel_def by (rule theI') (auto simp add: single_valued_def)
lemma single_valued_trace_rel: shows "single_valued trace_rel" proof (rule single_valuedI) fix x y y' assume asm: "(x, y) ∈ trace_rel""(x, y') ∈ trace_rel" thenobtain x' t where"x = (x', t)" by (meson surj_pair) thenhave"trace x' t y""trace x' t y'" using asm trace_rel_def by auto thenshow"y = y'" using trace_and_start_determines_end by blast qed
definition run_trace where "run_trace ≡ construct_fun_from_rel trace_rel"
text‹In order to describe intermediate configurations
a trace we introduce the $s$ function definition, which,
an initial configuration $c$, a trace $t$ and an index $i \in\mathbb{N}$,
the unique state after the first $i$ events of $t$.›
definition s where "s c t i = (THE c'. trace c (take i t) c')"
lemma s_is_partial_execution: shows "s c t i = run_trace (c, take i t)" unfolding s_def run_trace_def
construct_fun_from_rel_def trace_rel_def by auto
lemma exists_trace_for_any_i: assumes "∃c'. trace c t c'" shows "trace c (take i t) (s c t i)" proof - have"prefix (take i t) t"using take_is_prefix by auto thenobtain c'' where tr: "trace c (take i t) c''"using assms prefix_split_trace by blast thenshow ?thesis proof - have"((c, take i t), s c t i) ∈ trace_rel" unfolding s_def trace_rel_def construct_fun_from_rel_def by (metis case_prod_conv distributed_system.trace_and_start_determines_end distributed_system_axioms mem_Collect_eq the_equality tr) thenshow ?thesis by (simp add: trace_rel_def) qed qed
lemma exists_trace_for_any_i_j: assumes "∃c'. trace c t c'"and "i ≤ j" shows "trace (s c t i) (take (j - i) (drop i t)) (s c t j)" proof - have"trace c (take j t) (s c t j)"using exists_trace_for_any_i assms by simp from‹j ≥ i›have"take j t = take i t @ (take (j - i) (drop i t))" by (metis le_add_diff_inverse take_add) thenhave"trace c (take i t) (s c t i) ∧ trace (s c t i) (take (j - i) (drop i t)) (s c t j)" by (metis (no_types, lifting) assms(1) exists_trace_for_any_i split_trace trace_and_start_determines_end) thenshow ?thesis by simp qed
lemma step_Suc: assumes "i < length t"and
valid: "trace c t c'" shows"(s c t i) ⊨ (t ! i) ↦ (s c t (Suc i))" proof - have ex_trace: "trace (s c t i) (take (Suc i - i) (drop i t)) (s c t (Suc i))" using exists_trace_for_any_i_j le_less valid by blast moreoverhave"Suc i - i = 1"by auto moreoverhave"take 1 (drop i t) = [t ! i]" by (metis ‹Suc i - i = 1› assms(1) hd_drop_conv_nth le_add_diff_inverse lessI nat_less_le same_append_eq take_add take_hd_drop) ultimatelyshow ?thesis by (metis list.discI trace.simps trace_decomp_head) qed
subsection‹Trace-related lemmas›
lemma snapshot_state_unchanged_trace: assumes "trace c t c'"and "ps c p = Some u" shows "ps c' p = Some u" using assms snapshot_state_unchanged by (induct c t c', auto)
lemma no_state_change_if_only_nonregular_events: shows "[ trace c t c'; ∄ev. ev ∈ set t ∧ regular_event ev ∧ occurs_on ev = p; states c p = st ]==> states c' p = st" proof (induct c t c' rule:trace_rev_induct) case (tr_rev_init c) thenshow ?caseby simp next case (tr_rev_step c t c' ev c'') thenhave"states c' p = st" proof - have"∄ev. ev : set t ∧ regular_event ev ∧ occurs_on ev = p" using tr_rev_step by auto thenshow ?thesis using tr_rev_step by blast qed thenshow ?case using tr_rev_step no_state_change_if_no_event no_state_change_if_nonregular_event by auto qed
lemma message_must_be_delivered_2_trace: assumes "trace c t c'"and "m : set (msgs c i)"and "m ∉ set (msgs c' i)"and "channel i = Some (q, p)" shows "∃ev ∈ set t. (∃p q. ev = RecvMarker i p q ∧ m = Marker) ∨ (∃p q s s' m'. ev = Recv i q p s s' m' ∧ m = Msg m')" proof (rule ccontr) assume"~ (∃ev ∈ set t. (∃p q. ev = RecvMarker i p q ∧ m = Marker) ∨ (∃p q s s' m'. ev = Recv i q p s s' m' ∧ m = Msg m'))" (is ?P) have"[ trace c t c'; m : set (msgs c i); ?P ]==> m : set (msgs c' i)" proof (induct c t c' rule:trace_rev_induct) case (tr_rev_init c) thenshow ?caseby simp next case (tr_rev_step c t d ev c') thenhave m_in_set: "m : set (msgs d i)" using tr_rev_step by auto thenshow ?case proof (cases ev) case (Snapshot r) thenshow ?thesis using distributed_system.message_must_be_delivered_2 distributed_system_axioms m_in_set tr_rev_step.hyps(3) by blast next case (RecvMarker i' r s) thenshow ?thesis proof (cases "m = Marker") case True thenhave"i' ≠ i"using tr_rev_step RecvMarker by simp thenshow ?thesis using RecvMarker m_in_set message_must_be_delivered_2 tr_rev_step.hyps(3) by blast next case False thenshow ?thesis using RecvMarker tr_rev_step.hyps(3) m_in_set message_must_be_delivered_2 by blast qed next case (Trans r u u') thenshow ?thesis using tr_rev_step.hyps(3) m_in_set by auto next case (Send i' r s u u' m') thenshow ?thesis using distributed_system.message_must_be_delivered_2 distributed_system_axioms m_in_set tr_rev_step.hyps(3) by blast next case (Recv i' r s u u' m') thenshow ?thesis proof (cases "Msg m' = m") case True thenhave"i' ≠ i"using Recv tr_rev_step by auto thenshow ?thesis using Recv m_in_set tr_rev_step(3) by auto next case False thenshow ?thesis by (metis Recv event.distinct(17) event.inject(3) m_in_set message_must_be_delivered_2 tr_rev_step.hyps(3)) qed qed qed thenhave"m : set (msgs c' i)"using assms ‹?P›by auto thenshow False using assms by simp qed
lemma marker_must_be_delivered_2_trace: assumes "trace c t c'"and "Marker : set (msgs c i)"and "Marker ∉ set (msgs c' i)"and "channel i = Some (p, q)" shows "∃ev ∈ set t. (∃p q. ev = RecvMarker i p q)" proof - show"∃ev ∈ set t. (∃p q. ev = RecvMarker i p q)" using assms message_must_be_delivered_2_trace by fast qed
lemma snapshot_stable: shows "[ trace c t c'; has_snapshotted c p ]==> has_snapshotted c' p" proof (induct c t c' rule:trace_rev_induct) case (tr_rev_init c) thenshow ?caseby blast next case (tr_rev_step c t c' ev c'') thenshow ?case proof (cases ev) case (Snapshot q) thenhave"p ≠ q"using tr_rev_step next_snapshot can_occur_def by auto thenshow ?thesis using Snapshot tr_rev_step by auto next case (RecvMarker i q r) with tr_rev_step show ?thesis by (cases "p = q"; auto) qed simp_all qed
lemma snapshot_stable_2: shows "trace c t c' ==> ~ has_snapshotted c' p ==> ~ has_snapshotted c p" using snapshot_stable by blast
lemma no_markers_if_all_snapshotted: shows "[ trace c t c'; ∀p. has_snapshotted c p; Marker ∉ set (msgs c i) ]==> Marker ∉ set (msgs c' i)" proof (induct c t c' rule:trace_rev_induct) case (tr_rev_init c) thenshow ?caseby simp next case (tr_rev_step c t c' ev c'') have all_snapshotted: "∀p. has_snapshotted c' p"using snapshot_stable tr_rev_step by auto have no_marker: "Marker ∉ set (msgs c' i)"using tr_rev_step by blast thenshow ?case proof (cases ev) case (Snapshot r) thenshow ?thesis using can_occur_def tr_rev_step all_snapshotted by auto next case (RecvMarker i' r s) have"i' ≠ i" proof (rule ccontr) assume"~ i' ≠ i" thenhave"Marker : set (msgs c i)" using can_occur_def RecvMarker tr_rev_step RecvMarker_implies_Marker_in_set by blast thenshow False using tr_rev_step by simp qed thenshow ?thesis using tr_rev_step all_snapshotted no_marker RecvMarker by auto next case (Trans p s s') thenshow ?thesis using tr_rev_step no_marker by auto next case (Send i' r s u u' m) thenshow ?thesis proof (cases "i' = i") case True thenhave"msgs c'' i = msgs c' i @ [Msg m]"using tr_rev_step Send by auto thenshow ?thesis using no_marker by auto next case False thenshow ?thesis using Send tr_rev_step no_marker by auto qed next case (Recv i' r s u u' m) thenshow ?thesis proof (cases "i = i'") case True thenhave"msgs c'' i = tl (msgs c' i)"using tr_rev_step Recv by auto thenshow ?thesis using no_marker by (metis list.sel(2) list.set_sel(2)) next case False thenshow ?thesis using Recv tr_rev_step no_marker by auto qed qed qed
lemma event_stays_valid_if_no_occurrence_trace: shows "[ trace c t c'; list_all (λev. occurs_on ev ≠ occurs_on ev') t; can_occur ev' c ]==> can_occur ev' c'" proof (induct c t c' rule:trace_rev_induct) case tr_rev_init thenshow ?caseby blast next case tr_rev_step thenshow ?caseusing event_stays_valid_if_no_occurrence by auto qed
lemma event_can_go_back_if_no_sender_trace: shows "[ trace c t c'; list_all (λev. occurs_on ev ≠ occurs_on ev') t; can_occur ev' c'; ~ isRecvMarker ev'; list_all (λev. ~ isSend ev) t ]==> can_occur ev' c" proof (induct c t c' rule:trace_rev_induct) case tr_rev_init thenshow ?caseby blast next case tr_rev_step thenshow ?caseusing event_can_go_back_if_no_sender by auto qed
lemma done_only_from_recv_marker_trace: assumes "trace c t c'"and "t ≠ []"and "snd (cs c cid) ≠ Done"and "snd (cs c' cid) = Done"and "channel cid = Some (p, q)" shows "RecvMarker cid q p ∈ set t" proof (rule ccontr) assume"~ RecvMarker cid q p ∈ set t" moreoverhave"[ trace c t c'; ~ RecvMarker cid q p ∈ set t; snd (cs c cid) ≠ Done; channel cid = Some (p, q) ] ==> snd (cs c' cid) ≠ Done" proof (induct t arbitrary: c' rule:rev_induct) case Nil thenshow ?case by (metis list.discI trace.simps) next case (snoc ev t) thenobtain d where ind: "trace c t d"and step: "d ⊨ ev ↦ c'" using trace_decomp_tail by blast thenhave"snd (cs d cid) ≠ Done" proof - have"~ RecvMarker cid q p ∈ set t" using snoc.prems(2) by auto thenshow ?thesis using snoc ind by blast qed thenshow ?case using done_only_from_recv_marker local.step snoc.prems(2) snoc.prems(4) by auto qed ultimatelyhave"snd (cs c' cid) ≠ Done"using assms by blast thenshow False using assms by simp qed
lemma cs_not_not_started_stable_trace: shows "[ trace c t c'; snd (cs c cid) ≠ NotStarted; channel cid = Some (p, q) ]==> snd (cs c' cid) ≠ NotStarted" proof (induct t arbitrary:c' rule:rev_induct) case Nil thenshow ?case by (metis list.discI trace.simps) next case (snoc ev t) thenobtain d where tr: "trace c t d"and step: "d ⊨ ev ↦ c'" using trace_decomp_tail by blast thenhave"snd (cs d cid) ≠ NotStarted"using snoc by blast thenshow ?caseusing cs_not_not_started_stable snoc step by blast qed
lemma no_messages_introduced_if_no_channel: assumes
trace: "trace init t final"and
no_msgs_if_no_channel: "∀i. channel i = None ⟶ msgs init i = []" shows "channel cid = None ==> msgs (s init t i) cid = []" proof (induct i) case0 thenshow ?case by (metis assms exists_trace_for_any_i no_msgs_if_no_channel take0 tr_init trace_and_start_determines_end) next case (Suc n) have f: "trace (s init t n) (take ((Suc n) - n) (drop n t)) (s init t (Suc n))" using exists_trace_for_any_i_j order_le_less trace assms by blast thenshow ?case proof (cases "drop n t = Nil") case True thenshow ?thesis using Suc.hyps Suc.prems by (metis f tr_init trace_and_start_determines_end take_Nil) next case False have suc_n_minus_n: "Suc n - n = 1"by auto thenhave"length (take ((Suc n) - n) (drop n t)) = 1"using False by auto thenobtain ev where"ev # Nil = take ((Suc n) - n) (drop n t)" by (metis False One_nat_def suc_n_minus_n length_greater_0_conv self_append_conv2 take_eq_Nil take_hd_drop) thenhave g: "(s init t n) ⊨ ev ↦ (s init t (Suc n))" by (metis f tr_init trace_and_start_determines_end trace_decomp_head) thenshow ?thesis proof (cases ev) case (Snapshot r) thenshow ?thesis using Suc.hyps Suc.prems g by auto next case (RecvMarker cid' sr r) have"cid' ≠ cid"using RecvMarker can_occur_def g Suc by auto with RecvMarker Suc g show ?thesis by (cases "has_snapshotted (s init t n) sr", auto) next case (Trans r u u') thenshow ?thesis by (metis Suc.hyps Suc.prems g next_trans) next case (Send cid' r s u u' m) have"cid' ≠ cid"using Send can_occur_def g Suc by auto thenshow ?thesis using Suc g Send by simp next case (Recv cid' s r u u' m) have"cid' ≠ cid"using Recv can_occur_def g Suc by auto thenshow ?thesis using Suc g Recv by simp qed qed qed
end(* context distributed_system *)
end(* theory Trace *)
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.