(*>*) section‹ A Temporal Logic of Safety (TLS) \label{sec:tls} ›
text‹
model systems with finite and infinite sequences of states, closed
stuttering following 🚫‹"Lamport:1994"›. This theory relates
safety logic of \S\ref{sec:safety_logic} to the powerset
quotiented by stuttering) representing properties of these sequences
see \S\ref{sec:tls-safety}). Most of this story is standard but the
of finite sequences does have some impact.
: ▪ historical motivations for future-time linear temporal logic (LTL): 🚫‹"MannaPnueli:1991" and "OwickiLamport:1982"›. ▪ a discussion on the merits of proving liveness: 🌐‹https://cs.nyu.edu/acsys/beyond-safety/liveness.htm›
: ▪ Lamport (and Abadi et al) treat infinite stuttering as termination ▪🚫‹‹p189› in "Lamport:1999"›: ``we can represent a terminating execution of any system by an
infinite behavior that ends with a sequence of nothing but stuttering steps. We have no need of
finite behaviors (finite sequences of states), so we consider only infinite ones.'' ▪ this conflates divergence with termination ▪ we separate those concepts here so we can support sequential composition ▪ the traditional account of liveness properties breaks down (see \S\ref{sec:safety_closure})
corecursive collapse :: "'s → ('a × 's, 'v) tllist → ('a × 's, 'v) tllist"where "collapse s xs = (if snd ` tset xs ⊆ {s} then trailing (undefined, s) xs else if snd (thd xs) = s then collapse s (ttl xs) else TCons (thd xs) (collapse (snd (thd xs)) (ttl xs)))" proof - have"(LEAST i. s ≠ snd (tnth (ttl xs) i)) < (LEAST i. s ≠ snd (tnth xs i))" if *: "¬ snd ` tset xs ⊆ {s}" and **: "snd (thd xs) = s" for s and xs :: "('a × 's, 'v) tllist" proof - from * obtain a s' where"(a, s') ∈ tset xs"and"s ≠ s'"by fastforce thenobtain i where"snd (tnth xs i) ≠ s" by (atomize_elim, induct rule: tset_induct) (auto intro: exI[of _ 0] exI[of _ "Suc i"for i]) with * ** have"(LEAST i. s ≠ snd (tnth xs i)) = Suc (LEAST i. s ≠ snd (tnth xs (Suc i)))" by (cases xs) (simp_all add: Least_Suc[where n=i]) with * show"(LEAST i. s ≠ snd (tnth (ttl xs) i)) < (LEAST i. s ≠ snd (tnth xs i))" by (cases xs) simp_all qed thenshow ?thesis by (relation "measure (λ(s, xs). LEAST i. s ≠ snd (tnth xs i))"; simp) qed
setup‹Sign.mandatory_path "tmap"›
lemma trailing: shows"tmap sf vf (trailing s xs) = trailing (sf s) (tmap sf vf xs)" by (simp add: trailing_def tmap_trepeat)
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "tlength"›
lemma trailing: shows"tlength (trailing s xs) ≤ tlength xs" by (fastforce simp: trailing_def dest: not_lfinite_llength)
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "trailing"›
lemma simps[simp]: shows TNil: "trailing s (TNil b) = TNil b" and TCons: "trailing s (TCons x xs) = trailing s xs" and ttl: "ttl (trailing s xs) = trailing s xs" and idempotent: "trailing s (trailing s xs) = trailing s xs" and tset_finite: "tset (trailing s xs) = (if tfinite xs then {} else {s})" and trepeat: "trailing s (trepeat s) = trepeat s" by (simp_all add: trailing_def)
lemma eq_TNil_conv: shows"trailing s xs = TNil b ⟷ tfinite xs ∧ terminal xs = b" and"TNil b = trailing s xs ⟷ tfinite xs ∧ terminal xs = b" and"is_TNil (trailing s xs) ⟷ tfinite xs" by (auto simp: trailing_def dest: is_TNil_tfinite)
lemma eq_TCons_conv: shows"trailing s xs = TCons y ys ⟷¬tfinite xs ∧ TCons y ys = trepeat s" and"TCons y ys = trailing s xs ⟷¬tfinite xs ∧ TCons y ys = trepeat s" by (auto simp: trailing_def)
lemma tmap: shows"trailing s (tmap sf vf xs) = tmap id vf (trailing s xs)" by (simp add: trailing_def tmap_trepeat)
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "collapse"›
lemma unique: assumes"∧s xs. f s xs = (if snd ` tset xs ⊆ {s} then trailing (undefined, s) xs else if snd (thd xs) = s then f s (ttl xs) else TCons (thd xs) (f (snd (thd xs)) (ttl xs)))" shows"f = collapse" proof(intro ext) show"f s xs = collapse s xs"for s xs proof(coinduction arbitrary: s xs) case (Eq_tllist s xs) show ?case apply (induct arg≡"(s, xs)" arbitrary: s xs rule: collapse.inner_induct) apply (subst (123) assms) apply (subst (123) collapse.code) apply simp apply (subst (123) assms) apply (subst (123) collapse.code) apply simp apply (metis assms collapse.code) done qed qed
lemma collapse: shows"collapse s (collapse s xs) = collapse s xs" proof - have"(λs xs. collapse s (collapse s xs)) = collapse" apply (rule collapse.unique) apply (subst (123) collapse.code) apply auto done thenshow ?thesis by (fastforce simp: fun_eq_iff) qed
lemma simps[simp]: shows TNil: "collapse s (TNil b) = TNil b" and TCons: "collapse s (TCons x xs) = (if snd x = s then collapse s xs else TCons x (collapse (snd x) xs))" and trailing: "collapse s (trailing (undefined, s) xs) = trailing (undefined, s) xs" by (simp_all add: collapse.code trailing_def)
lemma tshift_stuttering: assumes"snd ` set xs ⊆ {s}" shows"collapse s (tshift xs ys) = collapse s ys" using assms by (induct xs) simp_all
lemma infinite_trailing: assumes"¬tfinite xs" assumes"snd ` tset xs ⊆ {s'}" shows"collapse s xs = (if s = s' then trepeat (undefined, s') else TCons (thd xs) (trepeat (undefined, s')))" using assms by (cases xs) (simp_all add: assms collapse.code trailing_def)
lemma eq_TNil_conv: shows"collapse s xs = TNil b ⟷ tfinite xs ∧ snd ` tset xs ⊆ {s} ∧ terminal xs = b" (is"?lhs ⟷ ?rhs") and"TNil b = collapse s xs ⟷ tfinite xs ∧ snd ` tset xs ⊆ {s} ∧ terminal xs = b"(is"?thesis1") proof - show"?lhs ⟷ ?rhs" proof(rule iffI) show"?lhs ==> ?rhs" proof(induct arg≡"(s, xs)" arbitrary: s xs rule: collapse.inner_induct[case_names step]) case (step s xs) thenshow ?case by (cases xs; clarsimp split: if_splits)
(subst (asm) collapse.code; clarsimp simp: trailing.eq_TNil_conv split: if_splits) qed show"?rhs ==> ?lhs" by (simp add: conj_explode) (induct arbitrary: s rule: tfinite_induct; simp) qed thenshow ?thesis1 by (rule eq_commute_conv) qed
lemma eq_TConsE: assumes"collapse s xs = TCons y ys" obtains
(trailing_stuttering) "¬ tfinite xs" and"snd ` tset xs = {s}" and"TCons y ys = trepeat (undefined, s)"
| (step) us ys' where"xs = tshift us (TCons y ys')" and"snd ` set us ⊆ {s}" and"snd y ≠ s" and"collapse (snd y) ys' = ys" apply atomize_elim using assms proof(induct arg≡"(s, xs)" arbitrary: s xs rule: collapse.inner_induct[case_names step]) case (step s xs) show ?case proof(cases xs) case (TNil v) with step.prems show ?thesis by simp next case (TCons x xs') show ?thesis proof(cases "snd ` tset xs' ⊆ {snd x}") case True with TCons trans[OF collapse.code[symmetric] step.prems] show ?thesis by (force simp: trailing.eq_TCons_conv tshift_eq_TCons_conv split: if_split_asm) next case False with TCons trans[OF collapse.code[symmetric] step.prems] step.hyps[OF refl] show ?thesis by (cases x, cases y)
(simp add: trailing.eq_TCons_conv tshift_eq_TCons_conv trepeat_eq_TCons_conv
eq_snd_iff exI[where x="[]"]
split: if_split_asm; safe; force dest!: spec[where x="(fst x, s) # us"for us]) qed qed qed
lemma eq_TCons_conv: shows"collapse s xs = TCons y ys ⟷ (¬tfinite xs ∧ snd ` tset xs = {s} ∧ TCons y ys = trepeat (undefined, s)) ∨ (∃xs' ys'. xs = tshift xs' (TCons y ys') ∧ snd ` set xs' ⊆ {s} ∧ snd y ≠ s ∧ collapse (snd y) ys' = ys)" (is"?lhs ⟷ ?rhs") and"TCons y ys = collapse s xs ⟷ (¬tfinite xs ∧ snd ` tset xs = {s} ∧ TCons y ys = trepeat (undefined, s)) ∨ (∃xs' ys'. xs = tshift xs' (TCons y ys') ∧ snd ` set xs' ⊆ {s} ∧ snd y ≠ s ∧ collapse (snd y) ys' = ys)" (is ?thesis1) proof - show"?lhs ⟷ ?rhs" by (auto elim: collapse.eq_TConsE simp: collapse.tshift_stuttering collapse.infinite_trailing) thenshow ?thesis1 by (rule eq_commute_conv) qed
lemma tfinite: shows"tfinite (collapse s xs) ⟷ tfinite xs" (is"?lhs ⟷ ?rhs") proof(rule iffI) show ?lhs if ?rhs using that by (induct arbitrary: s rule: tfinite_induct) simp_all show ?rhs if ?lhs using that by (induct "collapse s xs" arbitrary: s xs rule: tfinite_induct)
(auto simp: collapse.eq_TNil_conv collapse.eq_TCons_conv trepeat_eq_TCons_conv) qed
lemma tfinite_conv: assumes"collapse s xs = collapse s' xs'" shows"tfinite xs ⟷ tfinite xs'" by (metis assms collapse.tfinite)
lemma terminal: shows"terminal (collapse s xs) = terminal xs" proof(cases "tfinite xs") case True thenobtain i where"tlength xs ≤ enat i" using llength_eq_infty_conv_lfinite by fastforce thenshow ?thesis proof(induct i arbitrary: s xs) case (Suc i s xs) thenshow ?case by (cases xs) (simp_all flip: eSuc_enat) qed (clarsimp simp: enat_0 tlength_0_conv) qed (simp add: collapse.tfinite terminal_tinfinite)
lemma tlength: shows"tlength (collapse s xs) ≤ tlength xs" proof(cases "tfinite xs") case True thenshow ?thesis by (induct arbitrary: s rule: tfinite_induct) (auto intro: order.trans[OF _ ile_eSuc]) next case False thenshow ?thesis by (fastforce dest: not_lfinite_llength) qed
lemma tset_memberD: assumes"(a, s') ∈ tset (collapse s xs)" shows"s' ∈ snd ` tset xs" using assms by (induct "collapse s xs" arbitrary: s xs rule: tset_induct)
(auto simp: collapse.eq_TCons_conv trepeat_eq_TCons_conv tset_tshift image_Un)
lemma tset_memberD2: assumes"(a, s') ∈ tset xs" shows"s = s' ∨ s' ∈ snd ` tset (collapse s xs)" using assms by (induct xs arbitrary: a s rule: tset_induct; simp; fast)
lemma tshift: shows"collapse s (tshift xs ys) = tshift (trace.natural' s xs) (collapse (trace.final' s xs) ys)" by (induct xs arbitrary: s) simp_all
lemma trepeat: shows"collapse s (trepeat (a, s)) = trepeat (undefined, s)" by (subst collapse.code) (simp add: trailing_def)
lemma eq_trepeat_conv: shows"trepeat (undefined, s) = collapse s xs ⟷¬tfinite xs ∧ snd ` tset xs = {s}" (is"?thesis1") and"collapse s xs = trepeat (undefined, s) ⟷¬tfinite xs ∧ snd ` tset xs = {s}" (is"?thesis2") proof - show ?thesis1 by (rule iffI,
(subst (asm) trepeat_unfold, simp add: collapse.eq_TCons_conv),
simp add: collapse.infinite_trailing) thenshow ?thesis2 by (rule eq_commute_conv) qed
lemma treplicate: shows"collapse s (treplicate i (a, s) v) = TNil v" by (subst collapse.code) (simp add: trailing.eq_TNil_conv split: nat.split)
lemma eq_tshift_conv: shows"collapse s xs = tshift ys zs ⟷ (∃xs' xs'' ys'. tshift xs' xs'' = xs ∧ trace.natural' s xs' @ ys' = ys ∧ ((¬tfinite xs'' ∧ snd ` tset xs'' = {trace.final' s xs'} ∧ tshift ys' zs = trepeat (undefined, trace.final' s xs')) ∨ (ys' = [] ∧ collapse (trace.final' s xs') xs'' = zs)))" (is"?lhs ⟷ ?rhs") and"tshift ys zs = collapse s xs ⟷ (∃xs' xs'' ys'. tshift xs' xs'' = xs ∧ trace.natural' s xs' @ ys' = ys ∧ ((¬tfinite xs'' ∧ snd ` tset xs'' = {trace.final' s xs'} ∧ tshift ys' zs = trepeat (undefined, trace.final' s xs')) ∨ (ys' = [] ∧ collapse (trace.final' s xs') xs'' = zs)))" (is ?thesis1) proof - show"?lhs ⟷ ?rhs" proof(rule iffI) show"?lhs ==> ?rhs" proof(induct ys arbitrary: s xs) case Nil thenshow ?case by (simp add: exI[where x="[]"]) next case (Cons y ys s xs) from Cons.prems[simplified] show ?case proof(cases rule: collapse.eq_TConsE) case trailing_stuttering thenshow ?thesis by (simp add: exI[where x="[]"]) next case (step xs' ys') from step(1-3) Cons.hyps[OF step(4)] show ?thesis by (fastforce simp: trace.natural'.append tshift_append
simp flip: trace.natural'.eq_Nil_conv
intro: exI[where x="xs' @ y # ys''"for ys'']) qed qed show"?rhs ==> ?lhs" by (auto simp: collapse.tshift tshift_append collapse.infinite_trailing) qed thenshow ?thesis1 by (rule eq_commute_conv) qed
lemma eq_collapse_ttake_dropn_conv: shows"collapse s xs = collapse s ys ⟷ (∃j. trace.natural' s (fst (ttake i xs)) = trace.natural' s (fst (ttake j ys)) ∧ snd (ttake i xs) = snd (ttake j ys) ∧ collapse (trace.final' s (fst (ttake i xs))) (tdropn i xs) = collapse (trace.final' s (fst (ttake i xs))) (tdropn j ys))" (is"?lhs ⟷ (∃j. ?rhs i j s xs ys)") proof(rule iffI) show"?lhs ==> (∃j. ?rhs i j s xs ys)" proof(induct i arbitrary: s xs ys) case (Suc i s xs ys) show ?case proof(cases xs) case (TNil b) with Suc.prems show ?thesis by (fastforce intro: exI[where x="case tlength ys of ∞→ undefined | enat j → Suc j"]
simp: collapse.eq_TNil_conv trace.natural'.eq_Nil_conv
ttake_eq_Some_conv tfinite_tlength_conv tdropn_tlength
dest: in_set_ttakeD) next case (TCons x xs') show ?thesis proof(cases "snd x = s") case True with Suc TCons show ?thesis by simp next case False note Suc.prems TCons False moreoverfrom calculation obtain us ys' where"ys = tshift us (TCons x ys')" and"snd ` set us ⊆ {s}" and"collapse (snd x) ys' = collapse (snd x) xs'" by (auto simp: collapse.eq_TCons_conv trepeat_eq_TCons_conv) moreoverfrom calculation Suc.hyps[of "snd x""xs'""ys'"] obtain j where"?rhs i j (snd x) xs' ys'" by presburger ultimatelyshow ?thesis by (auto simp: ttake_tshift trace.natural'.append tdropn_tshift
simp flip: trace.natural'.eq_Nil_conv
intro: exI[where x="Suc (length us) + j"]) qed qed qed (simp add: exI[where x=0]) show"∃j. ?rhs i j s xs ys ==> ?lhs" by (metis collapse.tshift trace.final'.natural' tshift_fst_ttake_tdropn_id) qed
lemma tshift_tdropn: assumes"trace.natural' s (fst (ttake i xs)) = trace.natural' s ys" shows"collapse s (tshift ys (tdropn i xs)) = collapse s xs" by (metis assms collapse.tshift trace.final'.natural' tshift_fst_ttake_tdropn_id)
lemma map_collapse: shows"collapse (sf s) (tmap (map_prod af sf) vf (collapse s xs)) = collapse (sf s) (tmap (map_prod af sf) vf xs)" (is"?lhs s xs = ?rhs s xs") proof(coinduction arbitrary: s xs) case (Eq_tllist s xs) show ?case proof(intro conjI; (intro impI)?) have *: "sf s' = sf s" if"tfinite xs"and"sf ` snd ` tset (collapse s xs) ⊆ {sf s}"and"(a, s') ∈ tset xs" for a s s' using that by (induct arbitrary: s rule: tfinite_induct; clarsimp split: if_split_asm; metis) show"is_TNil (?lhs s xs) ⟷ is_TNil (?rhs s xs)" by (rule iffI,
fastforce dest!: * simp: collapse.is_TNil_conv collapse.tfinite tllist.set_map snd_image_map_prod,
fastforce dest!: collapse.tset_memberD simp: collapse.is_TNil_conv collapse.tfinite tllist.set_map) show"terminal (?lhs s xs) = terminal (?rhs s xs)" if"is_TNil (?lhs s xs)"and"is_TNil (?rhs s xs)" using that by (simp add: collapse.is_TNil_conv collapse.terminal) assume"¬is_TNil (?lhs s xs)"and"¬is_TNil (?rhs s xs)" thenobtain y ys z zs where l: "?lhs s xs = TCons y ys"and r: "?rhs s xs = TCons z zs" by (simp add: tllist.disc_eq_case(2) split: tllist.split_asm) from l show"thd (?lhs s xs) = thd (?rhs s xs) ∧ (∃s' xs'. ttl (?lhs s xs) = ?lhs s' xs' ∧ ttl (?rhs s xs) = ?rhs s' xs')" proof(cases rule: collapse.eq_TConsE) case trailing_stuttering note left = this from r show ?thesis proof(cases rule: collapse.eq_TConsE) case trailing_stuttering from left(3) trailing_stuttering(3) show ?thesis by (fold l r) (simp; metis) next case (step us zs') from left(2) step(1,3) have False by (clarsimp simp: tset_tshift tset_tmap tmap_eq_tshift_conv TCons_eq_tmap_conv collapse.tshift
split: if_split_asm)
(use step(2) in‹fastforce simp flip: trace.final'.map[where af=af]›) thenshow ?thesis .. qed next case (step us ys') note left = this from r show ?thesis proof(cases rule: collapse.eq_TConsE) case trailing_stuttering have False if"sf s' ≠ sf s" and"(λx. sf (snd x)) ` tset xs = {sf s}" and"(λx. sf (snd x)) ` set us ⊆ {sf s}" and"collapse s xs = tshift us (TCons (a, s') vs)" for a s' us vs using that by (force simp: tset_tshift
dest!: arg_cong[where f="λxs. s' ∈ snd ` tset xs"] collapse.tset_memberD
intro: imageI[where f="λx. sf (snd x)"]) with l left(3) trailing_stuttering(2) have False by (fastforce simp: tset_tmap tmap_eq_tshift_conv TCons_eq_tmap_conv collapse.eq_TCons_conv
trepeat_eq_TCons_conv snd_image_map_prod image_image) thenshow ?thesis .. next case (step vs zs') from left step show ?thesis unfolding l r apply (clarsimp simp: tmap_eq_tshift_conv collapse.tshift TCons_eq_tmap_conv
tmap_tshift trace.natural'.map_natural'[where af=af and sf=sf and s=s]
iffD2[OF trace.natural'.eq_Nil_conv(1)]
dest!: arg_cong[where f="λxs. collapse (sf s) (tmap (map_prod af sf) vf xs)"]
split: if_split_asm) apply (use step(2) in‹fastforce simp flip: trace.final'.map[where af=af]›) apply (metis list.set_map trace.final'.idle trace.final'.map trace.final'.natural') apply metis done qed qed qed qed
lemma takeE: fixes ψ :: "('a, 's, 'v) behavior.t" obtains j where"♮(behavior.take i ψ) = behavior.take j (♮Tψ)" proof atomize_elim have"∃j. trace.natural' s (fst (ttake i xs)) = fst (ttake j (collapse s xs)) ∧ snd (ttake i xs) = snd (ttake j (collapse s xs))" for s and xs :: "('a × 's, 'v) tllist" proof(induct i arbitrary: s xs) case0show ?caseby (fastforce simp: ttake_eq_Nil_conv) next case (Suc i s xs) show ?case proof(cases xs) case (TCons x' xs') with Suc[where s="snd x'"and xs=xs'] show ?thesis by (fastforce intro: exI[where x="Suc j"for j]) qed (simp add: exI[where x=1]) qed thenshow"∃j. ♮ (behavior.take i ψ) = behavior.take j (♮T ψ)" by (simp add: behavior.take_def trace.natural_def split_def) qed
setup‹Sign.parent_path›
subsection‹ The ∗‹('a, 's, 'v) tls› lattice \label{sec:tls-tls} ›
text‹
is our version of Lamport's TLA lattice which we treat in a ``semantic'' way similarly to 🚫‹"AbadiMerz:1996"›.
: ▪ there is a somewhat natural partial ordering on the ‹tls› lattice induced by the connection with
the ‹spec› lattice (see \S\ref{sec:tls-safety} and \S\ref{sec:safety_closure}) which we do not use
›
typedef ('a, 's, 'v) tls = "behavior.stuttering.closed :: ('a, 's, 'v) behavior.t set set" morphisms unTLS TLS by blast
setup_lifting type_definition_tls
instantiation tls :: (type, type, type) complete_boolean_algebra begin
instance by (standard; transfer;
auto simp: behavior.stuttering.cl_bot
behavior.stuttering.closed_strict_complete_distrib_lattice_axiomI[OF behavior.stuttering.cl_bot])
: ▪ as we lack next/X/‹◯› (due to stuttering closure) we do not have induction for‹U› (until) ▪🚫‹"Lamport:1994"› omitted the LTL ``until'' operator from TLA as he considered it too hard to use ▪ As 🚫‹"DeGiacomoVardi:2013"› observe, things get non-standard on finite traces ▪ see \S\ref{sec:safety_closure} for an example ▪🚫‹"Maier:2004"› provides an alternative account
›
setup‹Sign.mandatory_path "raw"›
definition state_prop :: "'s pred → ('a, 's, 'v) behavior.t set"where "state_prop P = {ψ. P (behavior.init ψ)}"
definition
until :: "('a, 's, 'v) behavior.t set → ('a, 's, 'v) behavior.t set → ('a, 's, 'v) behavior.t set" where "until P Q = {ψ . ∃i. ∃ψ'∈Q. behavior.dropn i ψ = Some ψ' ∧ (∀j<i. the (behavior.dropn j ψ) ∈ P)}"
definition
eventually :: "('a, 's, 'v) behavior.t set → ('a, 's, 'v) behavior.t set" where "eventually P = raw.until UNIV P"
definition
always :: "('a, 's, 'v) behavior.t set → ('a, 's, 'v) behavior.t set" where "always P = -raw.eventually (-P)"
abbreviation (input) "unless P Q ≡ raw.until P Q ∪ raw.always P"
lemma untilI: assumes"behavior.dropn i ψ = Some ψ'" assumes"ψ' ∈ Q" assumes"∧j. j < i ==> the (behavior.dropn j ψ) ∈ P" shows"ψ ∈ raw.until P Q" using assms unfolding raw.until_def by blast
lemma eventually_alt_def: shows"raw.eventually P = {ψ . ∃ψ'∈P. ∃i. behavior.dropn i ψ = Some ψ'}" by (auto simp: raw.eventually_def raw.until_def)
lemma always_alt_def: shows"raw.always P = {ψ . ∀i ψ'. behavior.dropn i ψ = Some ψ' ⟶ ψ' ∈ P}" by (auto simp: raw.always_def raw.eventually_alt_def)
lemma alwaysI: assumes"∧i ψ'. behavior.dropn i ψ = Some ψ' ==> ψ' ∈ P" shows"ψ ∈ raw.always P" by (simp add: raw.always_alt_def assms)
lemma alwaysD: assumes"ψ ∈ raw.always P" assumes"behavior.dropn i ψ = Some ψ'" shows"ψ' ∈ P" using assms by (simp add: raw.always_alt_def)
setup‹Sign.mandatory_path "state_prop"›
lemma monotone: shows"mono raw.state_prop" by (fastforce intro: monoI simp: raw.state_prop_def)
lemma base: shows"ψ ∈ Q ==> ψ ∈ raw.until P Q" and"Q ⊆ raw.until P Q" by (force simp: raw.until_def)+
lemma step: assumes"ψ ∈ P" assumes"behavior.tl ψ = Some ψ'" assumes"ψ' ∈ raw.until P Q" shows"ψ ∈ raw.until P Q" proof - from‹ψ' ∈ raw.until P Q› obtain i ψ'' where"ψ'' ∈ Q"and"∀j<i. the (behavior.dropn j ψ') ∈ P"and"behavior.dropn i ψ' = Some ψ''" by (clarsimp simp: raw.until_def) with assms(1,2) show ?thesis by (clarsimp simp: raw.until_def behavior.dropn.Suc less_Suc_eq_0_disj
intro!: exI[where x="Suc i"]) qed
lemma induct[case_names base step, consumes 1, induct set: raw.until]: assumes"ψ ∈ raw.until P Q" assumes base: "∧ψ. ψ ∈ Q ==> R ψ" assumes step: "∧ψ ψ'. [ψ ∈ P; behavior.tl ψ = Some ψ'; ψ' ∈ raw.until P Q; R ψ']==> R ψ" shows"R ψ" proof - from‹ψ ∈ raw.until P Q›obtain ψ' i where"behavior.dropn i ψ = Some ψ'"and"ψ' ∈ Q"and"∀j<i. the (behavior.dropn j ψ) ∈ P" unfolding raw.until_def by blast thenshow ?thesis proof(induct i arbitrary: ψ) case0thenshow ?case by (force intro: base) next case Suc from Suc.prems show ?case by (fastforce intro: step Suc.hyps dest: spec[where x="Suc j"for j]
simp: behavior.dropn.Suc raw.until_def
split: Option.bind_split_asm) qed qed
lemma mono: assumes"P ⊆ P'" assumes"Q ⊆ Q'" shows"raw.until P Q ⊆ raw.until P' Q'" unfolding raw.until_def using assms by blast
lemma botR: shows"raw.until P {} = {}" by (force simp: raw.until_def)
lemma untilR: shows"raw.until P (raw.until P Q) = raw.until P Q" (is"?lhs = ?rhs") proof(rule antisym[OF subsetI]) show"ψ ∈ ?rhs"if"ψ ∈ ?lhs"for ψ using that by induct blast+ show"?rhs ⊆ ?lhs"by blast qed
lemma InfL_not_empty: assumes"X ≠ {}" shows"raw.until (∩X) Q = (∩x∈X. raw.until x Q)" (is"?lhs = ?rhs") proof(rule antisym[OF _ subsetI]) show"?lhs ⊆ ?rhs" by (simp add: INT_greatest Inter_lower raw.until.mono) show"ψ ∈ ?lhs"if"ψ ∈ ?rhs"for ψ proof - from‹X ≠ {}›obtain P where"P ∈ X"by blast with that obtain i ψ' where *: "behavior.dropn i ψ = Some ψ'""ψ' ∈ Q""∀j<i. the (behavior.dropn j ψ) ∈ P" unfolding raw.until_def by blast from this(1,2) obtain k ψ'' where **: "k ≤ i""behavior.dropn k ψ = Some ψ''""ψ'' ∈ Q""∀j<k. the (behavior.dropn j ψ) ∉ Q" using ex_has_least_nat[where k=i and P="λk. k ≤ i ∧ (∀ψ''. behavior.dropn k ψ = Some ψ''⟶ ψ'' ∈ Q)"and m=id] by clarsimp (metis (no_types, lifting) behavior.dropn.shorterD leD nle_le option.sel order.trans) from that * ** show ?thesis by (clarsimp simp: raw.until_def intro!: exI[where x=k])
(metis order.strict_trans1 linorder_not_le option.sel) qed qed
lemma SupR: shows"raw.until P (∪X) = ∪(raw.until P ` X)" unfolding raw.until_def by blast
lemma weakenL: shows"raw.until UNIV P = raw.until (- P) P" (is"?lhs = ?rhs") proof(rule antisym[OF subsetI]) show"ψ ∈ ?rhs"if"ψ ∈ ?lhs"for ψ using that by induct blast+ show"?rhs ⊆ ?lhs"by (simp add: raw.until.mono) qed
lemma implication_ordering_le: ―‹🚫‹‹(16)› in "WarfordVegaStaley:2020"›› shows"raw.until P Q ∩ raw.until (-Q) R ⊆ raw.until P R" by (clarsimp simp: raw.until_def) (metis order.trans linorder_not_le option.sel)
lemma infR_ordering_le: ―‹🚫‹‹(18)› in "WarfordVegaStaley:2020"›› shows"raw.until P (Q ∩ R) ⊆ raw.until (raw.until P Q) R" (is"?lhs⊆ ?rhs") proof(rule subsetI) show"ψ ∈ ?rhs"if"ψ ∈ ?lhs"for ψ using that proof induct case (step ψ ψ') thenshow ?case by - (rule raw.until.step, rule raw.until.step;
blast intro: subsetD[OF raw.until.mono, rotated -1]) qed blast qed
lemma untilL: shows"raw.until (raw.until P Q) Q ⊆ raw.until P Q" (is"?lhs⊆ ?rhs") proof(rule subsetI) show"ψ ∈ ?rhs"if"ψ ∈ ?lhs"for ψ using that by induct auto qed
lemma alwaysR_le: shows"raw.until P (raw.always Q) ⊆ raw.always (raw.until P Q)" (is"?lhs ⊆ ?rhs") proof(rule subsetI) show"ψ ∈ ?rhs"if"ψ ∈ ?lhs"for ψ using that proof induct case (base ψ) thenshow ?caseby (auto simp: raw.always_alt_def) next case (step ψ ψ') show ?case proof(rule raw.alwaysI) fix i ψ'' assume"behavior.dropn i ψ = Some ψ''" with step "behavior.dropn.0"show"ψ'' ∈ raw.until P Q" by (cases i; clarsimp simp: raw.always_alt_def behavior.dropn.Suc; blast) qed qed qed
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "unless"›
lemma neg: shows"- (raw.until P Q ∪ raw.always P) = raw.until (- Q) (- P ∩ - Q)" (is"?lhs = ?rhs") proof(rule antisym[OF subsetI], (unfold Compl_Un Int_iff conj_explode Compl_iff)[1]) fix ψ assume *: "ψ ∉ raw.until P Q" assume"ψ ∉ raw.always P" thenobtain k ψ' where"behavior.dropn k ψ = Some ψ'" and"ψ' ∉ P" by (clarsimp simp: raw.always_alt_def) with ex_has_least_nat[where k=k and P="λi. ∃ψ'. behavior.dropn i ψ = Some ψ' ∧ ψ' ∉ P"andm=id] obtain k ψ' where"behavior.dropn k ψ = Some ψ'" and"ψ' ∉ P" and"∀j<k. the (behavior.dropn j ψ) ∈ P" by clarsimp (metis behavior.dropn.shorterD less_le_not_le option.distinct(1) option.exhaust_sel) with * behavior.dropn.shorterD show"ψ ∈ ?rhs" by (fastforce simp: raw.until_def intro: exI[where x=k]) next show"?rhs ⊆ ?lhs" by (clarsimp simp: raw.always_alt_def raw.until_def subset_iff; metis nat_neq_iff option.sel) qed
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "eventually"›
lemma terminated: shows"raw.eventually raw.terminated = {ψ. tfinite (behavior.rest ψ)}" (is"?lhs = ?rhs") proof(rule antisym[OF _ subsetI]) show"?lhs ⊆ ?rhs" by (clarsimp simp: raw.eventually_alt_def raw.terminated_def behavior.dropn.tfiniteD) show"ψ ∈ ?lhs"if"ψ ∈ ?rhs"for ψ proof - note‹ψ ∈ ?rhs› moreoverfrom calculation obtain i where"tlength (behavior.rest ψ) = enat i" by (clarsimp simp: tfinite_tlength_conv) moreoverfrom calculation obtain ψ' where"behavior.dropn i ψ = Some ψ'" using behavior.dropn.eq_Some_tlength_conv by fastforce moreoverfrom calculation have"behavior.sset ψ' ⊆ {behavior.init ψ'}" by (cases ψ')
(clarsimp dest!: behavior.dropn.eq_Some_tdropnD simp: tdropn_tlength behavior.sset.simps) ultimatelyshow"ψ ∈ ?lhs" by (auto simp: raw.eventually_alt_def raw.terminated_def dest: behavior.dropn.tfiniteD) qed qed
lemma until[intro]: assumes"P ∈ behavior.stuttering.closed" assumes"Q ∈ behavior.stuttering.closed" shows"raw.until P Q ∈ behavior.stuttering.closed" proof - have"ψ2∈ raw.until P Q"if"ψ1∈ raw.until P Q"and"ψ1≃T ψ2"for ψ1 ψ2 using that proof(induct arbitrary: ψ2 rule: raw.until.induct) case (base ψ1 ψ2) with assms(2) show ?case by (blast intro: behavior.stuttering.closed_in) next case (step ψ1 ψ' ψ2) show ?case proof(cases "ψ' ≃T ψ1") case True with‹ψ1≃T ψ2› step.hyps(4) show ?thesis by simp next case False from assms(1) ‹ψ1∈ P›‹ψ1≃T ψ2›have"ψ2∈ P" by (blast intro: behavior.stuttering.closed_in) from False ‹ψ1≃T ψ2›‹behavior.tl ψ1 = Some ψ'› obtain a s0 s1 xs1 xs' ys' where ψ1: "ψ1 = behavior.B s0 (TCons (a, s1) xs1)" and ψ2: "ψ2 = behavior.B s0 (tshift xs' (TCons (a, s1) ys'))" and *: "collapse s0 (TCons (a, s1) xs1) = collapse s0 (tshift xs' (TCons (a, s1) ys'))" "s0≠ s1" and **: "collapse s1 ys' = collapse s1 xs1" and xs': "snd ` set xs' ⊆ {s0}" by (cases ψ1; cases ψ2; cases "behavior.rest ψ1"; simp)
(fastforce simp: behavior.natural_def collapse.eq_TCons_conv trepeat_eq_TCons_conv
split: if_splits) from ψ2‹ψ2∈ P› xs' show ?thesis proof(induct xs' arbitrary: ψ2) case Nil with ψ1 ** step.hyps(2,4) show ?case by (auto simp: behavior.natural_def) next case (Cons x' xs') with behavior.stuttering.closed_in[OF _ _ ‹P ∈ behavior.stuttering.closed›] ψ1 ** step(3) show ?case by (auto simp: behavior.natural_def behavior.split_all) qed qed qed thenshow ?thesis by (fastforce elim: behavior.stuttering.clE) qed
lemma eventually[intro]: assumes"P ∈ behavior.stuttering.closed" shows"raw.eventually P ∈ behavior.stuttering.closed" using assms by (auto simp: raw.eventually_def)
lemma always[intro]: assumes"P ∈ behavior.stuttering.closed" shows"raw.always P ∈ behavior.stuttering.closed" using assms by (auto simp: raw.always_def)
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "tls"›
definition valid :: "('a, 's, 'v) tls → bool"where "valid P ⟷ P = ⊤"
lemma trans[trans]: assumes"⊨ P" assumes"P ≤ Q" shows"⊨ Q" using assms by (simp add: tls.valid_def top.extremum_unique)
lemma mp: assumes"⊨ P \<longrightarrow>B Q" assumes"⊨ P" shows"⊨ Q" using assms by (simp add: tls.valid_def)
lemmas rev_mp = tls.valid.mp[rotated]
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "singleton"›
lemma uminus_le_conv[tls.singleton.le_conv]: shows"(•ψ•)T≤ -P ⟷¬(•ψ•)T≤ P" by transfer
(simp add: raw.singleton_def behavior.stuttering.closed_uminus behavior.stuttering.least_conv)
lemma state_prop_le_conv[tls.singleton.le_conv]: shows"(•ψ•)T≤ tls.state_prop P ⟷ P (behavior.init ψ)" by transfer
(simp add: raw.singleton_def behavior.stuttering.least_conv[OF behavior.stuttering.closed.raw.state_prop];
simp add: raw.state_prop_def)
lemma until_le_conv[tls.singleton.le_conv]: fixes P :: "('a, 's, 'v) tls" shows"(•ψ•)T≤ P U Q ⟷ (∃i ψ'. behavior.dropn i ψ = Some ψ' ∧(•ψ'•)T≤ Q ∧ (∀j<i. (•the (behavior.dropn j ψ)•)T≤ P))" (is"?lhs ⟷ ?rhs") proof(rule iffI) show"?lhs ==> ?rhs" proof transfer fix ψ and P Q :: "('a, 's, 'v) behavior.t set" assume *: "P ∈ behavior.stuttering.closed""Q ∈ behavior.stuttering.closed" and"raw.singleton ψ ⊆ raw.until P Q" thenhave"∃i. ∃ψ'∈Q. behavior.dropn i ψ = Some ψ' ∧ (∀j<i. the (behavior.dropn j ψ) ∈P)" by (auto simp: raw.singleton_def raw.until_def) with * show"∃i ψ'. behavior.dropn i ψ = Some ψ' ∧ raw.singleton ψ' ⊆ Q ∧ (∀j<i. raw.singleton (the (behavior.dropn j ψ)) ⊆ P)" by (auto simp: raw.singleton_def behavior.stuttering.least_conv) qed show"?rhs ==> ?lhs" by transfer
(unfold raw.singleton_def;
rule behavior.stuttering.least[OF _ behavior.stuttering.closed.raw.until];
auto 100 intro: iffD2[OF eqset_imp_iff[OF raw.until_def]]) qed
lemma eventually_le_conv[tls.singleton.le_conv]: shows"(•ψ•)T≤♢P ⟷ (∃i ψ'. behavior.dropn i ψ = Some ψ' ∧(•ψ'•)T≤ P)" by (simp add: tls.eventually_def tls.singleton.le_conv)
lemma always_le_conv[tls.singleton.le_conv]: shows"(•ψ•)T≤ tls.always P ⟷ (∀i ψ'. behavior.dropn i ψ = Some ψ' ⟶(•ψ'•)T≤ P)" by (simp add: tls.always_def tls.singleton.le_conv)
setup‹Sign.parent_path›
interpretation until: closure_complete_lattice_distributive_class "tls.until P"for P proof standard show"(x ≤ tls.until P y) = (tls.until P x ≤ tls.until P y)"for x y by transfer
(intro iffD2[OF order_class.order.closure_axioms_alt_def[unfolded closure_axioms_def], rule_format]
conjI allI raw.until.base monoI raw.until.mono order.refl raw.until.untilR, assumption) show"tls.until P (⊔X) ≤⊔(tls.until P ` X) ⊔ tls.until P ⊥"for X by transfer (simp add: raw.until.SupR behavior.stuttering.cl_bot) qed
setup‹Sign.mandatory_path "until"›
lemmas botL = raw.until.botL[transferred] lemmas botR = raw.until.botR[transferred] lemmas topR = tls.until.cl_top lemmas expansiveR = tls.until.expansive[of P Q for P Q]
lemmas weakenL = raw.until.weakenL[transferred]
lemmas mono = raw.until.mono[transferred]
lemma strengthen[strg]: assumes"st_ord F P P'" assumes"st_ord F Q Q'" shows"st_ord F (P U Q) (P' U Q')" using assms by (cases F) (auto simp: tls.until.mono)
lemma SupL_le: shows"(⊔x∈X. x U R) ≤ (⊔X) U R" by (simp add: SupI tls.until.mono)
lemma supL_le: shows"P U R ⊔ Q U R ≤ (P ⊔ Q) U R" by (simp add: tls.until.mono)
lemma SupR: shows"P U (⊔X) = ⊔((U) P ` X)" by (simp add: tls.until.cl_Sup tls.until.botR)
lemmas supR = tls.until.cl_sup
lemmas InfL_not_empty = raw.until.InfL_not_empty[transferred] lemmas infL = tls.until.InfL_not_empty[where X="{P, Q}"for P Q, simplified, of P Q R for P Q R] lemmas InfR_le = tls.until.cl_Inf_le lemmas infR_le = tls.until.cl_inf_le[of P Q R for P Q R]
lemma implication_ordering_le: ―‹🚫‹‹(16)› in "WarfordVegaStaley:2020"›› shows"P U Q ⊓ (-Q) U R ≤ P U R" by transfer (rule raw.until.implication_ordering_le)
lemma supL_ordering_le: ―‹🚫‹‹(17)› in "WarfordVegaStaley:2020"›› shows"P U (Q U R) ≤ (P ⊔ Q) U R" (is"?lhs ≤ ?rhs") proof - have"?rhs = (P ⊔ Q) U ((P ⊔ Q) U R)"by (rule tls.until.idempotent(1)[symmetric]) alsohave"?lhs ≤…"by (blast intro: tls.until.mono le_supI1 le_supI2) finallyshow ?thesis . qed
lemma infR_ordering_le: ―‹🚫‹‹(18)› in "WarfordVegaStaley:2020"›› shows"P U (Q ⊓ R) ≤ (P U Q) U R" by transfer (rule raw.until.infR_ordering_le)
lemma boolean_implication_distrib_le: ―‹🚫‹‹(19)› in "WarfordVegaStaley:2020"›› shows"(P \<longrightarrow>B Q) U R ≤ (P U R) \<longrightarrow>B (Q U R)" by (metis galois.conj_imp.galois order.refl tls.until.infL tls.until.mono)
lemma excluded_middleR: ―‹🚫‹‹(23)› in "WarfordVegaStaley:2020"›› shows"⊨ P U Q ⊔ P U (-Q)" by (simp add: tls.validI tls.until.cl_top flip: tls.until.cl_sup)
lemmas untilR = tls.until.idempotent(1)[of P Q for P Q]
lemma untilL: shows"(P U Q) U Q = P U Q" (is"?lhs = ?rhs") proof(rule antisym) show"?lhs ≤ ?rhs" by transfer (rule raw.until.untilL) show"?rhs ≤ ?lhs" using tls.until.infR_ordering_le[where P=P and Q=Q and R=Q] by simp qed
lemma absorb: shows"P U P = P" by (metis tls.until.botL tls.until.untilL)
lemma absorb_supL: ―‹🚫‹‹(23)› in "WarfordVegaStaley:2020"›› shows"P ⊔ P U Q = P ⊔ Q" by (metis inf_commute inf_sup_absorb le_iff_sup
tls.until.absorb tls.until.cl_sup tls.until.expansive tls.until.infL)
lemma absorb_supR: ―‹🚫‹‹(23)› in "WarfordVegaStaley:2020"›› shows"Q ⊔ P U Q = P U Q" by (simp add: sup.absorb2 tls.until.expansive)
lemma eventually_le: shows"P U Q ≤♢Q" by (simp add: tls.eventually_def tls.until.mono)
lemma absorb_eventually: shows inf_eventually_absorbR: "P U Q ⊓♢Q = P U Q"―‹🚫‹‹(39)› in "WarfordVegaStaley:2020"›› and sup_eventually_absorbR: "P U Q ⊔♢Q = ♢Q"―‹🚫‹‹(40)› in "WarfordVegaStaley:2020"›› and eventually_absorbR: "P U♢Q = ♢Q"―‹🚫‹‹(41)› in "WarfordVegaStaley:2020"›› by (simp_all add: tls.eventually_def sup.absorb2 tls.until.mono
order.eq_iff order.trans[OF tls.until.supL_ordering_le] tls.until.expansiveR
flip: tls.until.infL)
lemma sup_le: ―‹🚫‹‹(28)› in "WarfordVegaStaley:2020"›› shows"P U Q ≤ P ⊔ Q" by (simp add: ac_simps sup.absorb_iff1 tls.until.absorb_supL tls.until.absorb_supR)
lemma ordering: ―‹🚫‹‹(251)› in "WarfordVegaStaley:2020"›› shows"(-P) U Q ⊔ (-Q) U P = ♢(P ⊔ Q)" (is"?lhs = ?rhs") proof - have"?lhs = ⊤U P ⊓ (- Q) U P ⊔⊤U Q ⊓ (- P) U Q" by (simp add: ac_simps inf.absorb2 tls.until.mono) alsohave"… = (- P) U P ⊓ (- Q) U P ⊔ (- Q) U Q ⊓ (- P) U Q" by (simp add: tls.until.weakenL) alsohave"… = (- (P ⊔ Q)) U (P ⊔ Q)" by (simp add: ac_simps tls.until.cl_sup flip: tls.until.infL) alsohave"… = ?rhs" by (simp add: tls.eventually_def tls.until.weakenL) finallyshow ?thesis . qed
lemma neg: ―‹🚫‹‹(170)› in "WarfordVegaStaley:2020"›› shows"-(P W Q) = (-Q) U (-P ⊓ -Q)" by transfer (rule raw.unless.neg)
lemma alwaysR_le: ―‹🚫‹‹(177)› in "WarfordVegaStaley:2020"›› shows"P W◻Q ≤◻(P W Q)" by (simp add: tls.unless_def order.trans[OF tls.until_alwaysR_le] tls.always.mono
order.trans[OF _ tls.always.sup_le])
lemma sup_le: ―‹🚫‹‹(206)› in "WarfordVegaStaley:2020"›› shows"P W Q ≤ P ⊔ Q" by (rule iffD1[OF compl_le_compl_iff]) (simp add: tls.unless.neg tls.until.expansive)
lemma ordering: ―‹🚫‹‹(252)› in "WarfordVegaStaley:2020"›› shows"⊨ (-P) W Q ⊔ (-Q) W P" by (simp add: ac_simps tls.validI tls.unless_def tls.until.ordering tls.eventually.sup flip: tls.eventually.neg)
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "until"›
lemma eq_unless_inf_eventually: shows"P U Q = (P W Q) ⊓♢Q" by transfer (force simp: raw.until_def raw.eventually_def raw.always_alt_def behavior.dropn.shorterD)
lemma always_strengthen_le: ―‹🚫‹‹(83)› in "WarfordVegaStaley:2020"›› shows"◻P ⊓ (Q U R) ≤ (P ⊓ Q) U (P ⊓ R)" by transfer
(clarsimp simp: raw.until_def raw.always_alt_def;
fastforce simp: behavior.dropn.shorterD del: exI intro!: exI)
lemma until_weakI: shows"◻P ⊓♢Q ≤ P U Q" (is"?lhs ≤ ?rhs") ―‹🚫‹‹(84)› in "WarfordVegaStaley:2020"›› by (simp add: tls.eventually_def order.trans[OF tls.until.always_strengthen_le] tls.until.mono)
lemma always_impL: ―‹🚫‹‹(86)› in "WarfordVegaStaley:2020"›› shows"P \<longrightarrow>\<box> P' ⊓ P U Q ≤ P' U Q" (is ?thesis1) and"P U Q ⊓ P \<longrightarrow>\<box> P' ≤ P' U Q" (is ?thesis2) proof - show ?thesis1 by (rule order.trans[OF tls.until.always_strengthen_le])
(simp add: tls.until.mono boolean_implication.shunt1) thenshow ?thesis2 by (simp add: inf_commute) qed
lemma always_impR: ―‹🚫‹‹(85)› in "WarfordVegaStaley:2020"›› shows"Q \<longrightarrow>\<box> Q' ⊓ P U Q ≤ P U Q'" (is ?thesis1) and"P U Q ⊓ Q \<longrightarrow>\<box> Q' ≤ P U Q'" (is ?thesis2) proof - show ?thesis1 by (rule order.trans[OF tls.until.always_strengthen_le])
(simp add: tls.until.mono boolean_implication.shunt1) thenshow ?thesis2 by (simp add: inf_commute) qed
lemma neg: ―‹🚫‹‹(173)› in "WarfordVegaStaley:2020"›› shows"-(P U Q) = (-Q) W (-P ⊓ -Q)" unfolding tls.unless_def by (simp flip: tls.until.eq_unless_inf_eventually tls.unless.neg tls.eventually.neg
boolean_algebra.de_Morgan_conj)
subsubsection‹ Leads-to and leads-to-via \label{sec:TLS_leads-to} ›
text‹
-called ∗‹response› properties are of the form ‹P \⟶\◻♢Q› (pronounced ``‹P› leads to ‹Q›'', written ‹P \↝ Q›) 🚫‹"MannaPnueli:1991"›. This connective is similar
the ``ensures'' modality of 🚫‹‹\S3.4.4› in "ChandyMisra:1989"›.
🚫‹"Jackson:1998"› used the more general
`‹P› leads to ‹Q› via ‹I›'' form ‹P \⟶\◻ I U Q›
establish liveness properties in a sequential setting.
›
lemma leads_to_refl: shows"⊨ P \<leadsto> P" by (simp add: tls.validI boolean_implication.shunt_top tls.always.top_conv tls.eventually.expansive
top.extremum_unique)
lemma leads_to_leads_to_via: shows"P \<longrightarrow>\<box> Q U R ≤ P \<leadsto> R" by (simp add: boolean_implication.mono tls.always.mono tls.until.eventually_le)
lemma leads_to_trans: shows"P \<leadsto> Q ⊓ Q \<leadsto> R ≤ P \<leadsto> R" (is"?lhs ≤ ?rhs") proof - have"?lhs ≤ P \<leadsto> Q ⊓◻(Q \<leadsto> R)" by (simp add: tls.always.simps) alsohave"…≤ P \<leadsto> Q ⊓♢Q \<leadsto> R" by (meson order.refl inf_mono tls.always.mono tls.always_imp_eventually_generalization) alsohave"…≤ ?rhs" by (simp add: boolean_implication.trans tls.always.mono flip: tls.always.inf) finallyshow ?thesis . qed
lemma leads_to_via_weakenR: shows"Q \<longrightarrow>\<box> Q' ⊓ P \<longrightarrow>\<box> I U Q ≤ P \<longrightarrow>\<box> I U Q'" by transfer
(clarsimp simp: raw.always_alt_def raw.until_def boolean_implication.set_alt_def;
metis behavior.dropn.dropn Option.bind.bind_lunit)
lemma leads_to_via_supL: ―‹ useful for case distinctions › shows"P \<longrightarrow>\<box> I U Q ⊓ P' \<longrightarrow>\<box> I' U Q ≤ P ⊔ P' \<longrightarrow>\<box> (I ⊔ I') U Q" by (simp add: boolean_implication.conv_sup ac_simps le_infI2 le_supI2
monoD[OF tls.always.monotone] tls.until.mono)
lemma leads_to_via_trans: shows"(P \<longrightarrow>\<box> I U Q) ⊓ (Q \<longrightarrow>\<box> I' U R) ≤ P \<longrightarrow>\<box> (I ⊔ I') U R" (is"?lhs ≤ ?rhs") proof - have"?lhs ≤◻(P \<longrightarrow>B I U (I' U R))" by (subst inf.commute) (rule tls.leads_to_via_weakenR) alsohave"…≤ ?rhs" by (strengthen ord_to_strengthen(1)[OF tls.until.supL_ordering_le]) (rule order.refl) finallyshow ?thesis . qed
lemma leads_to_via_disj: ―‹ more like a chaining rule › shows"(P \<longrightarrow>\<box> I U Q) ⊓ (Q \<longrightarrow>\<box> I' U R) ≤ (P ⊔Q \<longrightarrow>\<box> (I ⊔ I') U R)" by (simp add: boolean_implication_def inf.coboundedI2 le_supI2 tls.always.mono tls.until.mono)
subsubsection‹ Fairness\label{sec:tls-fairness} ›
text‹
few renderings of weak fairness. 🚫‹"vanGlabbeekHofner:2019"› call this
`response to insistence'' as a generalisation of weak fairness.
lemma strengthen[strg]: assumes"st_ord (¬F) P P'" assumes"st_ord F Q Q'" shows"st_ord F (tls.weakly_fair P Q) (tls.weakly_fair P' Q')" using assms by (cases F) (auto simp: tls.weakly_fair.mono)
lemma strengthen[strg]: assumes"st_ord (¬F) P P'" assumes"st_ord F Q Q'" shows"st_ord F (tls.strongly_fair P Q) (tls.strongly_fair P' Q')" using assms by (cases F) (auto simp: tls.strongly_fair.mono)
lemma supL: ―‹ does not hold for const‹tls.weakly_fair›› shows"tls.strongly_fair (enabled1 ⊔ enabled2) taken = (tls.strongly_fair enabled1 taken ⊓ tls.strongly_fair enabled2 taken)" by (simp add: boolean_implication.conv_sup sup_inf_distrib2 tls.always.inf tls.always_eventually_sup
tls.strongly_fair_def)
lemma weakly_fair_le: shows"tls.strongly_fair enabled taken ≤ tls.weakly_fair enabled taken" by (simp add: tls.strongly_fair_def3 tls.weakly_fair_def3 boolean_implication.mono
tls.eventually_always_always_eventually_le)
lemma always_enabled_weakly_fair_strongly_fair: shows"◻enabled ≤ tls.weakly_fair enabled taken \<longleftrightarrow>B tls.strongly_fair enabled taken" by (simp add: boolean_eq_def boolean_implication_def)
now carve the safety properties out of the typ‹('a, 's, 'v) tls› lattice.
: ▪🚫‹‹\S2› in "AlpernSchneider:1985" and "AlpernDemersSchneider:1986" and "Schneider:1987"› ▪ observes that Lamport's earlier definitions do not work without stuttering ▪ provides the now standard definition that works with and without stuttering ▪🚫‹‹\S2.2› in "AbadiLamport:1991"›: topological definitions and intuitions ▪🚫‹‹\S2.2› in "Sistla:1994"›
go a different way: we establish a Galois connection with typ‹('a, 's, 'v) spec›.
: ▪ our safety closure for typ‹('a, 's, 'v) tls› introduces infinite sequences to stand for the
prefixes in typ‹('a, 's, 'v) spec› ▪ i.e., the non-termination of trace ‹σ› (‹trace.term σ = None›)
is represented by a behavior ending with ‹trace.final σ› infinitely stuttered ▪🚫‹‹\S2.1› in "AbadiLamport:1991"› consider these behaviors to represent terminating processes
›
setup‹Sign.mandatory_path "raw"›
definition to_spec :: "('a, 's, 'v) behavior.t set → ('a, 's, 'v) trace.t set"where "to_spec T = {behavior.take i ψ |ψ i. ψ ∈ T}"
definition from_spec :: "('a, 's, 'v) trace.t set → ('a, 's, 'v) behavior.t set"where "from_spec S = {ψ . ∀i. behavior.take i ψ ∈ S}"
interpretation safety: galois.powerset raw.to_spec raw.from_spec by standard (fastforce simp: raw.to_spec_def raw.from_spec_def)
setup‹Sign.mandatory_path "from_spec"›
lemma empty: shows"raw.from_spec {} = {}" by (simp add: raw.from_spec_def)
lemma cl_altI: assumes"∧i. ∃ψ' ∈ P. behavior.take i ψ = behavior.take i ψ'" shows"ψ ∈ raw.safety.cl P" using assms by (fastforce simp: raw.safety.cl_def raw.from_spec_def raw.to_spec_def)
lemma cl_altE: assumes"ψ ∈ raw.safety.cl P" obtains ψ' where"ψ' ∈ P"and"behavior.take i ψ = behavior.take i ψ'" proof(atomize_elim, cases "enat i ≤ tlength (behavior.rest ψ)") case True with assms show"∃ψ'. ψ' ∈ P ∧ behavior.take i ψ = behavior.take i ψ'" by (clarsimp simp: raw.safety.cl_def raw.from_spec_def raw.to_spec_def)
(metis behavior.take.length behavior.take.sel(3) ttake_eq_None_conv(1)
min.absorb2 min_enat2_conv_enat the_enat.simps) next case False with assms show"∃ψ'. ψ' ∈ P ∧ behavior.take i ψ = behavior.take i ψ'" by (clarsimp simp: raw.safety.cl_def raw.from_spec_def raw.to_spec_def)
(metis behavior.continue.take_drop_id behavior.take.continue_id leI) qed
lemma cl_alt_def: ―‹🚫‹"AlpernDemersSchneider:1986"›: the classical definition: ‹ψ› belongs to the safety closure of ‹P› if every prefix of ‹ψ› can be extended to a behavior in ‹P›› shows"raw.safety.cl P = {ψ. ∀i. ∃β. behavior.take i ψ @-B β ∈ P}" (is"?lhs = ?rhs") proof(rule antisym) show"?lhs ⊆ ?rhs" by clarsimp (metis behavior.continue.take_drop_id raw.safety.cl_altE) show"?rhs ⊆ ?lhs" proof(clarify intro!: raw.safety.cl_altI) fix ψ i assume"∀j. ∃β. behavior.take j ψ @-B β ∈ P" thenshow"∃ψ'∈P. behavior.take i ψ = behavior.take i ψ'" by (force dest: spec[where x=i]
intro: exI[where x=i] rev_bexI
simp: behavior.take.continue trace.take.behavior.take trace.continue.self_conv
ttake_eq_None_conv length_ttake
split: option.split enat.split) qed qed
lemma closed_alt_def: ―‹ If ‹ψ› is not in ‹P› then some prefix of ‹ψ› has irretrievably gone wrong › shows"raw.safety.closed = {P. ∀ψ. ψ ∉ P ⟶ (∃i. ∀β. behavior.take i ψ @-B β ∉ P)}" unfolding raw.safety.closed_def raw.safety.cl_alt_def by fast
lemma closed_alt_def2: ―‹ Contraposition gives the customary prefix-closure definition › shows"raw.safety.closed = {P. ∀ψ. (∀i. ∃β. behavior.take i ψ @-B β ∈ P) ⟶ ψ ∈ P}" unfolding raw.safety.closed_alt_def by fast
lemma closedI2: assumes"∧ψ. (∧i. ∃β. behavior.take i ψ @-B β ∈ P) ==> ψ ∈ P" shows"P ∈ raw.safety.closed" using assms unfolding raw.safety.closed_alt_def2 by fast
lemma closedE2: assumes"P ∈ raw.safety.closed" assumes"∧i. ψ ∉ P ==>∃β. behavior.take i ψ @-B β ∈ P" shows"ψ ∈ P" using assms unfolding raw.safety.closed_alt_def2 by blast
lemma from_spec: shows"raw.from_spec ` trace.stuttering.closed ⊆ (behavior.stuttering.closed :: ('a, 's, 'v) behavior.t set set)" proof - have *: "behavior.take i ψ2∈ P " if"ψ1≃T ψ2"and"∀i. behavior.take i ψ1∈ P"and"P ∈ trace.stuttering.closed" for ψ1 ψ2 i and P :: "('a, 's, 'v) trace.t set" using that(2-) by - (rule behavior.stuttering.equiv.takeE[OF sym[OF ‹ψ1≃T ψ2›], where i=i];
fastforce intro: trace.stuttering.closed_in) show ?thesis by (fastforce simp: raw.from_spec_def elim: behavior.stuttering.clE *) qed
lemma safety_cl: assumes"P ∈ behavior.stuttering.closed" shows"raw.safety.cl P ∈ behavior.stuttering.closed" unfolding raw.safety.cl_def using assms by (blast intro: subsetD[OF behavior.stuttering.closed.from_spec]
subsetD[OF trace.stuttering.closed.to_spec])
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "tls"›
lift_definition to_spec :: "('a, 's, 'v) tls → ('a, 's, 'v) spec"is raw.to_spec using raw.spec.closed.to_spec by blast
lemma eventually: ―‹ all the infinite traces and any finite ones that satisfy ‹♢P›› assumes"P ≠⊥" shows"tls.safety.cl (♢P) = -♢tls.terminated ⊔♢P" using assms by transfer (rule raw.safety.cl.eventually)
lemma terminated_iff: assumes"(•ψ•)T≤ tls.terminated" shows"(•ψ•)T≤ tls.safety.cl P ⟷(•ψ•)T≤ P" (is"?lhs ⟷ ?rhs") using assms by transfer
(simp add: raw.singleton_def behavior.stuttering.least_conv raw.safety.cl.terminated_iff
behavior.stuttering.closed.safety_cl behavior.stuttering.closed.raw.terminated)
lemma terminated: shows"tls.safety.cl tls.terminated = tls.idle ⊔ tls.terminated" by transfer (simp add: raw.safety.cl.terminated)
lemma le_terminated_conv: shows"tls.safety.cl P ≤ tls.terminated ⟷ P = ⊥" (is"?lhs ⟷ ?rhs") proof(rule iffI) show"?lhs ==> ?rhs" by transfer (rule raw.safety.cl.le_terminated_bot) show"?rhs ==> ?lhs" by simp qed
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "closed"›
lemma transfer[transfer_rule]: shows"rel_set (pcr_tls (=) (=) (=)) (behavior.stuttering.closed ∩ raw.safety.closed) tls.safety.closed" (is"rel_set _ ?lhs ?rhs") proof(rule rel_setI) fix X assume"X ∈ ?lhs"thenshow"∃Y∈?rhs. pcr_tls (=) (=) (=) X Y" by (metis (no_types, opaque_lifting) raw.safety.cl_def raw.safety.closed_conv tls.safety.closed_upper
tls.from_spec.rep_eq TLS_inverse cr_tls_def tls.pcr_cr_eq tls.to_spec.rep_eq Int_iff) next fix Y assume"Y ∈ ?rhs"thenshow"∃X∈?lhs. pcr_tls (=) (=) (=) X Y" by (metis tls.safety.cl_def tls.safety.closed_conv tls.from_spec.rep_eq
tls.pcr_cr_eq cr_tls_def unTLS raw.safety.closed_upper Int_iff) qed
lemma bot: shows"⊥∈ tls.safety.closed" by (simp add: tls.safety.closed_clI)
lemma unless: assumes"P ∈ tls.safety.closed" assumes"Q ∈ tls.safety.closed" shows"tls.unless P Q ∈ tls.safety.closed" using assms by transfer (blast intro: raw.safety.closed.unless)
lemma always: assumes"P ∈ tls.safety.closed" shows"tls.always P ∈ tls.safety.closed" by (simp add: assms tls.always_alt_def tls.safety.closed.bot tls.safety.closed.unless)
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "cl"›
lemma until_unless_le: assumes"P ∈ tls.safety.closed" assumes"Q ∈ tls.safety.closed" shows"tls.safety.cl (tls.until P Q) ≤ tls.unless P Q" by (simp add: order.trans[OF tls.safety.cl_inf_le] tls.until.eq_unless_inf_eventually
flip: tls.safety.closed_conv[OF tls.safety.closed.unless[OF assms]])
setup‹Sign.parent_path›
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "singleton"›
lemma to_spec_le_conv[tls.singleton.le_conv]: notes spec.singleton.transfer[transfer_rule] shows"(•σ•)≤ tls.to_spec P ⟷ (∃ψ i. (•ψ•)T≤ P ∧ σ = behavior.take i ψ)" by transfer
(simp add: TLS.raw.singleton_def behavior.stuttering.least_conv Safety_Logic.raw.singleton_def
raw.spec.least_conv[OF subsetD[OF raw.spec.closed.to_spec]];
fastforce simp: raw.to_spec_def)
lemma from_spec_le_conv[tls.singleton.le_conv]: notes spec.singleton.transfer[transfer_rule] shows"(•ψ•)T≤ tls.from_spec P ⟷ (∀i. (•behavior.take i ψ•)≤ P)" by transfer
(simp add: TLS.raw.singleton_def Safety_Logic.raw.singleton_def raw.spec.least_conv
behavior.stuttering.least_conv
subsetD[OF behavior.stuttering.closed.from_spec
imageI[OF raw.spec.closed.stuttering_closed]];
simp add: raw.from_spec_def)
lemma safety_cl_le_conv[tls.singleton.le_conv]: shows"(•ψ•)T≤ tls.safety.cl P ⟷ (∀i. ∃ψ'. (•ψ'•)T≤ P ∧ behavior.take i ψ = behavior.take i ψ')" by transfer
(simp add: TLS.raw.singleton_def behavior.stuttering.least_conv behavior.stuttering.closed.safety_cl;
fastforce intro: raw.safety.cl_altI
elim: raw.safety.cl_altE)
setup‹Sign.parent_path›
setup‹Sign.parent_path›
subsection‹ Maps\label{sec:tls-maps} ›
setup‹Sign.mandatory_path "tls"›
definition map :: "('a → 'b) → ('s → 't) → ('v → 'w) → ('a, 's, 'v) tls → ('b, 't, 'w) tls"where "map af sf vf P = ⊔(tls.singleton ` behavior.map af sf vf ` {σ. (•σ•)T≤ P})"
definition invmap :: "('a → 'b) → ('s → 't) → ('v → 'w) → ('b, 't, 'w) tls → ('a, 's, 'v) tls"where "invmap af sf vf P = ⊔(tls.singleton ` behavior.map af sf vf -` {σ. (•σ•)T≤ P})"
abbreviation amap ::"('a → 'b) → ('a, 's, 'v) tls → ('b, 's, 'v) tls"where "amap af ≡ tls.map af id id" abbreviation ainvmap ::"('a → 'b) → ('b, 's, 'v) tls → ('a, 's, 'v) tls"where "ainvmap af ≡ tls.invmap af id id" abbreviation smap ::"('s → 't) → ('a, 's, 'v) tls → ('a, 't, 'v) tls"where "smap sf ≡ tls.map id sf id" abbreviation sinvmap ::"('s → 't) → ('a, 't, 'v) tls → ('a, 's, 'v) tls"where "sinvmap sf ≡ tls.invmap id sf id" abbreviation vmap ::"('v → 'w) → ('a, 's, 'v) tls → ('a, 's, 'w) tls"where―‹ aka ‹liftM›› "vmap vf ≡ tls.map id id vf" abbreviation vinvmap ::"('v → 'w) → ('a, 's, 'w) tls → ('a, 's, 'v) tls"where "vinvmap vf ≡ tls.invmap id id vf"
interpretation map_invmap: galois.complete_lattice_distributive_class "tls.map af sf vf" "tls.invmap af sf vf"for af sf vf proof standard show"tls.map af sf vf P ≤ Q ⟷ P ≤ tls.invmap af sf vf Q" (is"?lhs ⟷ ?rhs") for P Q proof(rule iffI) show"?lhs ==> ?rhs" by (fastforce simp: tls.map_def tls.invmap_def intro: tls.singleton_le_extI) show"?rhs ==> ?lhs" by (fastforce simp: tls.map_def tls.invmap_def tls.singleton_le_conv
dest: order.trans[of _ P] behavior.stuttering.equiv.map[where af=af and sf=sf and vf=vf]
cong: tls.singleton_cong) qed show"tls.invmap af sf vf (⊔X) ≤⊔(tls.invmap af sf vf ` X)"for X by (fastforce simp: tls.invmap_def) qed
setup‹Sign.mandatory_path "singleton"›
lemma map_le_conv[tls.singleton.le_conv]: shows"(•ψ•)T≤ tls.map af sf vf P ⟷ (∃ψ'. (•ψ'•)T≤ P ∧(•ψ•)T≤(•behavior.map af sf vf ψ'•)T)" by (simp add: tls.map_def)
lemma invmap_le_conv[tls.singleton.le_conv]: shows"(•ψ•)T≤ tls.invmap af sf vf P ⟷(•behavior.map af sf vf ψ•)T≤ P" by (simp add: tls.invmap_def tls.singleton_le_conv)
(metis behavior.natural.map_natural tls.singleton_eq_conv)
lemma singleton: shows"tls.map af sf vf (•ψ•)T = (•behavior.map af sf vf ψ•)T" by (auto simp: tls.map_def order.eq_iff tls.singleton_le_conv intro: behavior.stuttering.equiv.map)
lemma singleton: shows"tls.invmap af sf vf (•ψ•)T = ⊔(tls.singleton ` {ψ'. (•behavior.map af sf vf ψ'•)T≤(•ψ•)T})" by (simp add: tls.invmap_def)
lemma id: shows"tls.invmap id id id P = P" and"tls.invmap (λx. x) (λx. x) (λx. x) P = P" unfolding id_def[symmetric] by (metis tls.map.id(1) tls.map_invmap.lower_upper_lower(2))+
lemma comp: shows"tls.invmap af sf vf (tls.invmap ag sg vg P) = tls.invmap (λx. ag (af x)) (λs. sg (sf s)) (λv. vg (vf v)) P" (is"?lhs P = ?rhs P") and"tls.invmap af sf vf ∘ tls.invmap ag sg vg = tls.invmap (ag ∘ af) (sg ∘ sf) (vg ∘ vf)" (is ?thesis1) proof - show"?lhs P = ?rhs P"for P by (auto intro: tls.singleton.antisym tls.singleton_le_extI simp: tls.singleton.le_conv) thenshow ?thesis1 by (simp add: fun_eq_iff comp_def) qed
lemmas invmap = tls.invmap.comp
setup‹Sign.parent_path›
setup‹Sign.mandatory_path "to_spec"›
lemma map: shows"tls.to_spec (tls.map af sf vf P) = spec.map af sf vf (tls.to_spec P)" by (rule tls.singleton.exhaust[of P])
(simp add: tls.map.Sup tls.map.singleton spec.map.Sup spec.map.singleton image_image
tls.to_spec.singleton tls.to_spec.Sup behavior.take.map)
setup‹Sign.parent_path›
setup‹Sign.parent_path›
subsection‹ Abadi's axioms for TLA\label{sec:tls-abadi_axioms} ›
text‹
axioms for ``propositional'' TLA due to 🚫‹"Abadi:1990"› hold in this model.
are complete for const‹tls.always› and const‹tls.eventually›.
: ▪ Abadi says that the temporal system is D aka S4.3Dum; see 🚫‹‹\S8› in "Goldblatt:1992"› ▪ the only interesting axiom here is 5: the discrete-time Dummett axiom ▪ ``propositional'' means that actions are treated separately; we omit this part as we don't have actions ala TLA
lemma Ax3: shows"⊨◻P \<longrightarrow>B◻◻P" by (simp add: tls.validI)
lemma Ax4: ―‹ ``a classical way to express that time is linear -- that any two instants in the future are ordered'' 🚫‹‹(254) Lemmon formula› in "WarfordVegaStaley:2020"›› shows"⊨◻(◻P \<longrightarrow>B Q) ⊔◻(◻Q \<longrightarrow>B P)" proof - have"⊨ (-◻P) W◻Q ⊔ (-◻Q) W◻P"by (rule tls.unless.ordering) alsohave"…≤◻((-◻P) W◻Q) ⊔◻((-◻Q) W◻P)" by (metis sup_mono tls.always.idempotent tls.unless.alwaysR_le) alsohave"…≤◻(-◻P ⊔ Q) ⊔◻(-◻Q ⊔ P)" by (strengthen ord_to_strengthen(1)[OF tls.unless.sup_le])
(meson order.refl sup_mono tls.always.contractive tls.always.mono) alsohave"… = ◻(◻P \<longrightarrow>B Q) ⊔◻(◻Q \<longrightarrow>B P)" by (simp add: boolean_implication.conv_sup) finallyshow ?thesis . qed
lemma Ax5: ―‹ ``expresses the discreteness of time''
See also 🚫‹‹\S4.1 ``the Dummett formula''› in "WarfordVegaStaley:2020"›: for them
``next'' encodes discreteness › fixes P :: "('a, 's, 'v) tls" shows"⊨◻(◻(P \<longrightarrow>B◻P) \<longrightarrow>B P) \<longrightarrow>B♢◻P \<longrightarrow>B P" (is"⊨ ?goal") proof - have raw_Ax5: "raw.always (raw.eventually (P ∩ raw.eventually (-P)) ∪ P) ∩ raw.eventually (raw.always P) ⊆ P" (is"?lhs ⊆ ?rhs") for P :: "('a, 's, 'v) behavior.t set" proof(rule subsetI) fix ψ assume"ψ ∈ ?lhs" from IntD2[OF ‹ψ ∈ ?lhs›] obtain i where"∃ψ'. behavior.dropn i ψ = Some ψ' ∧ ψ' ∈ raw.always P" by (force simp: raw.always_alt_def raw.eventually_alt_def) thenobtain i where i: "∃ψ'. behavior.dropn i ψ = Some ψ' ∧ ψ' ∈ raw.always P" and"∀j<i. ∀ψ'. behavior.dropn j ψ = Some ψ' ⟶ ψ' ∉ raw.always P" using ex_has_least_nat[where k=i and P="λi. ∃ψ'. behavior.dropn i ψ = Some ψ' ∧ ψ' ∈ raw.always P"and m=id] by (auto dest: leD) have"∃ψ'. behavior.dropn (i - j) ψ = Some ψ' ∧ ψ' ∈ raw.always P"for j proof(induct j) case (Suc j) show ?case proof(cases "j < i") case True show ?thesis proof(rule ccontr) assume"∄ψ'. behavior.dropn (i - Suc j) ψ = Some ψ' ∧ ψ' ∈ raw.always P" with‹∃ψ'. behavior.dropn i ψ = Some ψ' ∧ ψ' ∈ raw.always P› have"∃ψ'. behavior.dropn (i - Suc j) ψ = Some ψ' ∧ ψ' ∉ raw.always P" using behavior.dropn.shorterD[OF _ diff_le_self] by blast thenobtain k where"∃ψ'. behavior.dropn (i - Suc j + k) ψ = Some ψ' ∧ ψ' ∉ P" by (clarsimp simp: raw.always_alt_def behavior.dropn.add behavior.dropn.Suc) blast with Suc.hyps ‹j < i› have"∃ψ'. behavior.dropn (i - Suc j) ψ = Some ψ' ∧ ψ' ∉ P" by (fastforce simp: raw.always_alt_def behavior.dropn.add
split: nat_diff_split_asm
dest: spec[where x="k - 1"]) with‹j < i› IntD1[OF ‹ψ ∈ ?lhs›] obtain m n where"∃ψ' ψ'' ψ'''. behavior.dropn (i - Suc j) ψ = Some ψ' ∧ ψ' ∉ P ∧ behavior.dropn m ψ' = Some ψ'' ∧ ψ'' ∈ P ∧ behavior.dropn n ψ'' = Some ψ''' ∧ ψ''' ∉ P" by (simp add: raw.always_alt_def raw.eventually_alt_def)
(blast dest: spec[where x="i - Suc j"]) with‹j < i› Suc.hyps show False by (clarsimp simp: raw.always_alt_def dest!: spec[where x="m + n - 1"] split: nat_diff_split_asm)
(metis behavior.dropn.Suc behavior.dropn.bind_tl_commute behavior.dropn.dropn bind.bind_lunit) qed qed (use Suc.hyps in simp) qed (use i in simp) from this[of i] show"ψ ∈ P" by (fastforce simp: raw.always_alt_def dest: spec[where x=0]) qed show ?thesis proof(rule tls.validI) have"◻(♢(P ⊓♢(- P)) ⊔ P) ⊓♢◻P ≤ P" by (rule raw_Ax5[transferred]) thenhave"◻(♢(P ⊓♢(- P)) ⊔ P) ⊓♢◻P ≤ P" by (simp add: boolean_implication.conv_sup tls.always.neg) thenshow"⊤≤ ?goal" by - (intro iffD1[OF boolean_implication.shunt1];
simp add: boolean_implication.conv_sup tls.always.neg) qed qed
lemma Ax6: assumes"⊨ P" shows"⊨◻P" by (rule tls.always.always_necessitation[OF assms])
―‹ Ax7: propositional tautologies: given by the 🚫‹boolean_algebra› instance ›
lemma Ax8: assumes"⊨ P" assumes"⊨ P \<longrightarrow>B Q" shows"⊨ Q" by (rule tls.valid.rev_mp[OF assms])
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.