(*<*) theory TLSassume"not>is_TNil (?lhs s xs)"and"\>h ) imports "Safety_Logic" begin
(*>*) section‹
text‹
We model systems with fini case trailing_stuttering under stuttering following 🍋‹"Lamport:1994"›. This theory relates the 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 addition of finite sequences does have some impact.
References: ▪ 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›
Observations: ▪ 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})
definition trailing :: " c ==> ('a, 'b) tllist ==> ('c, 'b) tllist" where
"trailing s xs = (if tfinite xs then TNil (terminal xs) else trepeat s)"
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)))"
-
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
then obtain 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
then show ?thesis
by (relation "measure (λ(s, xs). LEAST i. s ≠ snd (tnth xs i))"; simp)
‹Sign.mandatory_path "tmap"›
trailing:
shows "tmap sf vf (trailing s xs) = trailing (sf s) (tmap sf vf xs)"
(simp add: trailing_def tmap_trepeat)
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"
(simp_all add: trailing_def)
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"
(auto simp: trailing_def dest: is_TNil_tfinite)
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"
(auto simp: trailing_def)
tmap:
shows "trailing s (tmap sf vf xs) = tmap id vf (trailing s xs)"
(simp add: trailing_def tmap_trepeat)
‹Sign.parent_path›
‹Sign.mandatory_path "collapse"›
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"
(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 (1 2 3) assms)
apply (subst (1 2 3) collapse.code)
apply simp
apply (subst (1 2 3) assms)
apply (subst (1 2 3) collapse.code)
apply simp
apply (metis assms collapse.code)
done
qed
collapse:
shows "collapse s (collapse s xs) = collapse s xs"
-
have "(λs xs. collapse s (collapse s xs)) = collapse"
apply (rule collapse.unique)
apply (subst (1 2 3) collapse.code)
apply auto
done
then show ?thesis
by (fastforce simp: fun_eq_iff)
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"
(simp_all add: collapse.code trailing_def)
tshift_stuttering:
assumes "snd ` set xs ⊆ {s}"
shows "collapse s (tshift xs ys) = collapse s ys"
assms by (induct xs) simp_all
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')))"
assms by (cases xs) (simp_all add: assms collapse.code trailing_def)
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")
-
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) then show ?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
then show ?thesis1
by (rule eq_commute_conv)
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"
atomize_elim
assms
(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
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)
-
show "?lhs ⟷ ?rhs"
by (auto elim: collapse.eq_TConsE simp: collapse.tshift_stuttering collapse.infinite_trailing)
then show ?thesis1
by (rule eq_commute_conv)
tfinite:
shows "tfinite (collapse s xs) ⟷ tfinite xs" (is "?lhs ⟷ ?rhs")
(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)
tfinite_conv:
assumes "collapse s xs = collapse s' xs'"
shows "tfinite xs ⟷ tfinite xs'"
(metis assms collapse.tfinite)
terminal:
shows "terminal (collapse s xs) = terminal xs"
(cases "tfinite xs")
case True
then obtain i where "tlength xs ≤ enat i"
using llength_eq_infty_conv_lfinite by fastforce
then show ?thesis
proof(induct i arbitrary: s xs)
case (Suc i s xs) then show ?case
by (cases xs) (simp_all flip: eSuc_enat)
qed (clarsimp simp: enat_0 tlength_0_conv)
(simp add: collapse.tfinite terminal_tinfinite)
tlength:
shows "tlength (collapse s xs) ≤ tlength xs"
(cases "tfinite xs")
case True then show ?thesis
by (induct arbitrary: s rule: tfinite_induct) (auto intro: order.trans[OF _ ile_eSuc])
case False then show ?thesis
by (fastforce dest: not_lfinite_llength)
lemmaeq_tshift_conv: showsthenshow?thesis.. \<longleftrightarrow>(\<exists>xs'xs''ys'.tshiftxs'xs''=xs\<and>trace.natural'stepshow?hesis ndys'zs=trepeatundefined.finalsxs)java.lang.StringIndexOutOfBoundsException: Index 147 out of bounds for length 147 \<or>(ys'=java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7 and"tshiftyszs=by(impaddbehaviornatural_def) \longleftrightarrow(<xs''ys.tshift'xs'<>trace.atural'xs'=ys \<and>((\<setup\openSignparent_path\close ] proof show"?lhs"rest(<atural>\^subT\<>(.init<omega)(behaviorrest\omega>)java.lang.StringIndexOutOfBoundsException: Index 113 out of bounds for length 113 proof(ruleiffI) show"?lhs\<Longrightarrow>?rhs" proof(inductysarbitrary:sxs)
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
next case(Consyyssxs) fromConsprems[simplified?ase proof(casesrule:collapse.eq_TConsE) by(simpadd:exI[wherex="[]"]) next case(stepxs'ys') from(-3.[OFstep4]show?hesis by(fastforcesimp:tracejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 simpflip:trace.natural'.eq_Nil_conv intro:exI[wherex="xs'@y#ys''"forys'']) qed qed show"rhs\Longrightarrow>?lhs" by(autosimp:collapse.tshifttshift_appendsetup\<>.mandatory_path"equiv\close qed thenshow?thesis1 by(eq_commute_conv) qed
mmaeq_collapse_ttake_dropn_conv: shows"collapsesxs=collapsesys \<longleftrightarrow>(\<exists>j.trace.natural's(fst(ttakeixs))=trace.natural's(fst(ttakejys)) \>sndttakexs)=snd(ttakejava.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54 \<and>collapse(trace.final's(fst(ttakeixs)))(tdropnixs) =collapse(trace.final's(from..[()](2 proofproof()behaviornaturalidle[F()behavior..[OFthis1]this2) show"?lhs\<Longrightarrow>(\<exists>j.?rhsi proof(inductiarbitrary:sxsys) case(Sucisxsys)show?case prooflemmatakeEjava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12 TNilbwithSucpremsshow?hesis have\<xists>j.collapse<>traceTsxs)behaviortakejbehaviorjava.lang.StringIndexOutOfBoundsException: Index 129 out of bounds for length 129 simp:collapse.eq_TNil_convtrace.natural'.eq_Nil_conv ttake_eq_Some_convtfinite_tlength_convtdropn_tlength dest:in_set_ttakeD) next case(TConsxxs')show?thesis proof(cases"sndx=s") caseTruewithSucTConsshow?thesisbysimp next caseFalse noteSuc.premsTConsFalse moreoverfromcalculation obtainusys' whereys=tshiftusTConsxys'" and"snd`setus\<subseteq>{lemmatakeE: andand"collapse(sndx)ys'=collapse(x)'" by(autosimp:collapseeq_TCons_convtrepeat_eq_TCons_conv moreoverfromcalculationSuc.hyps[of"ndx"xs'""ys'] obtainjwhere"?rhsij(sndx)xs'ys'" bypresburger ultimatelyshow?thesis byautosimp:ttake_tshift.java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73 :trace'eq_Nil_conv introexI=lengthus)+j") qed qed setup\>Signparent_path<> show"\<exists>j.? by(metiscollapse.tshifttrace.final'.natural'tshift_fst_ttake_tdropn_id) qed
lemmatshift_tdropn: assumes"trace.natural's(fst(ttakeixs))=trace.natural'sys" shows"collapses(tshiftystypedef',',')tls=".stutteringclosed:'sv.tsetset
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
lemmamap_collapse: "ollapse(sfs)(tmap(map_prodsf)vf(collapsesxs)) =collapse(fstmap(map_prodsf)vfxs"(?lhssxs=?rhssxs proof(coinductionarbitrary:sxsjava.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34 case(Eq_tllistsxs)show?case proof(introconjI;(introimpI)?) have*:"sfs'=sfs" if"tfinite forass' using(nduct::tfinite_inductclarsimpsplitif_split_asmmetis) show"is_TNil(?lhssxs)\<longleftrightarrow>is_TNil(?rhsSupIwhere'a"',','vtls"intro] byruleiffI, fastforce!*:collapseis_TNil_convcollapsetfinitetllistset_mapsnd_image_map_prod show"terminal(?lhssxs)=terminal(?rhssxs)" is_TNil(lhssxs)"and"(?sxs" subsection<open>Irreducibleelements\label{ectls-singleton}\>
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 thenobtainyys..{omega}java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58 bysimp:tllist.disc_eq_case(2)split.split_asm) fromshow"hd(?hssxsthd(?) \<and>(\<exists>s'xs'.ttl(?lhssjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 proof(casesrule:collapse.eq_TConsE) caselift_definitionsingleton:"'as,'vbehavior.t<Rightarrow>(','s,')tls(<><>T<>[].java.lang.StringIndexOutOfBoundsException: Index 149 out of bounds for length 149 noteleft\rblot\<subT\equiv\lblotbehaviorBsxs\rblot\^sub>Tjava.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 82 fromrshow?thesis (rulecollapse.eq_TConsE) casetrailing_stuttering fromleft(3)trailing_stuttering(3)show?thesis by(foldlr)(simp;metis) next ('java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 fromleft(2)step(1,3)haveFalse by(clarsimpsimp:tset_tshifttset_tmaptmap_eq_tshift_convTCons_eq_tmap_convcollapse.tshift splitif_split_asm (usestep(2)in\<open>fastforcesimpflip:trace.final'.map[whereaf=af]\java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 show?thesis.java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 qed next case(stepusys') noteleft=this fromrshow?thesis proof(casesrule:collapse.eq_TConsE casetrailing_stuttering haveFalse if"sfs'\qedfastforce and"(\<lambda>x.sf(sndx))`tsetxs={sfs}lemmassingleton_le_extI=iffD2[OFtlssingleton_le_ext_conv,rule_format] <>omega<blot\^><blot\omega'<>java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 foras'usvs usingboolean_implication_le_convtlssingleton.]:
dest!:arg_cong[wheref="\<lambda>xs.s'\(utosimprawsingleton_def.set_alt_def intro:imageI[wheref="\<lambda>x.sf( withlleft(3)trailing_stuttering("<lblot\natural\^><><rblot\^>T=\<blot\omega\<blot><^>" fastforce:tmap_eq_tshift_convTCons_eq_tmap_convcollapsejava.lang.StringIndexOutOfBoundsException: Index 101 out of bounds for length 101 trepeat_eq_TCons_convsnd_image_map_prodlemmasSup_irreducible[.Sup_prime_Sup_irreducible_iff..] thenshow?thesis.. next java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 fromleftstepshow?thesis unfoldinglr apply(clarsimpThenotransitionsanddoesnot. tracenatural.'whereaf=afandsfsfandssjava.lang.StringIndexOutOfBoundsException: Index 102 out of bounds for length 102 iffD2[OFtrace.natural'.eq_Nil_conv(1)] dest:arg_cong[wheref="<>xs.collapse(fs)(ap_prodsfvfxs)"] split:if_split_asm) apply(usestep(2)in\<open>fastforcesimpflip:trace.final'.map[whereaf=af]\<close>) apply(metislist.set_map..collapse.infinite_trailing applymetis done qed qed qed qed
definitionnatural::"('a,'s,'v)behavior.t\<Rightarrow>('a\open>ign.tls\closejava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
lemmacontinue: shows".sset(<>-\<^ub>)=trace.\sigma<>(trace.<>ofNone\Rightarrow>sndxs|_<>{})java.lang.StringIndexOutOfBoundsException: Index 168 out of bounds for length 168 by (simpadd:behavior.sset.simpsbehavior.continue_def split:option.split)
setup\<open>Sign.parent_path\<close>
etup<>.""\<losejava.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
lemmasel[simp]: shows"behavior.init(\<natural>\<^sub>java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 and"behavior.rest(\<natural simp_alladd.natural_defjava.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
lemmacontinue: shows"\<natural>\<^sub>T(\<sigma>"<>.j<\Longrightarrow>the(ehavior.j<>inPjava.lang.StringIndexOutOfBoundsException: Index 84 out of bounds for length 84 by(simpadd:behavior.t.expandtshift2_defcollapse.tshiftsplit:option.split)
lemmaidle: assumes"behavior.sset\<omega".state_propP\<nion>rawstate_prop.state_prop(\squnion>)java.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 82 shows"\<natural>\<^sub>T\<omega>=behavior.B(behavior.init\<omega>)(trailinglemmaInf: usingassmsby(cases\<omega>)(simpadd:behavior.natural_defbehavior.sset.simpscollapse.code)
assumes"\<omega>\<^sub>1\<simeq>\<^sub>T\<omega>\<^sub>2" shows"behavior.mapafsfvf\<omega>\<^sub>1\<simeq>java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 by(metisassmsbehavior.natural.map_natural)
our'TLAlatticewhichwetreatina`semantic'waysimilarlyjava.lang.StringIndexOutOfBoundsException: Index 94 out of bounds for length 94 \<^citet>\<open>"AbadiMerz:1996"\<close>.
Observations: \<^item>thereisasomewhatnaturalpartialorderingonthe\<open>tls\<close>latticeinducedbythejava.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55 the\<open>spec\<close>lattice(see\S\ref{sec:tls-safety}and\S\ref{sec:safety_closure})whichwedonotuse
definitionsingleton::"('a,'s,'v)behavior.t\<\Turnstilejava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 "singleton\<omega>=behavior.stuttering.cl{\<omega>}"
lemmasingleton_le_conv: shows"raw.singleton\<sigma>\<^sub>1\<le>raw.singleton\<sigma>\<^sub>2\<longleftrightarrow>\<natural>\<^sub>T\<sigma>\<^sub>1=\<natural>\<^sub>T\<java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 rule..java.lang.StringIndexOutOfBoundsException: Index 88 out of bounds for length 88 dest:behavior.stuttering.clEbehavior.stuttering.equiv_cl_singleton)
lemmasjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
lemmacollapse[simp]: shows"\<Squnion>(tls.singleton`{\<omega>.\<lblot>\<omega>\<rblot>\<^sub>T\<le>P})=P"add.cl_Sup..java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46 ruletlssingleton.[ofP)(simp:antisymSUP_le_iffSUP_upper)
lemmasingleton_cong: assumes"\<omega>\<simeq>\<^sub>T\<omega>'" shows\lblot><mega><>\^subT=\lblot><>'<rblot><subTjava.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78 usingassmsbysimp
lemmaboolean_implication_le_conv[tls.singleton.le_conv]: shows"\<lblot>\<sigma>\<rblot>\<^sub>java.lang.StringIndexOutOfBoundsException: Index 83 out of bounds for length 83 bytransfer (autosimp:raw.singleton_defboolean_implication.set_alt_def elim!:behavior.stuttering.clEbehavior.stuttering.closed_in[OF_sym])
definition until:"'a',')behaviortset\Rightarrow('a,'sv)behavior.tset\Rightarrow(',','v)behavior.tsetjava.lang.StringIndexOutOfBoundsException: Index 124 out of bounds for length 124 where "untilPQ={\<omega>.\<exists>i.\<exists>\<omega>'\<in>Q.behavior.dropni\setup\openSignmandatory_pathunless\close>
definition eventually::"('a,'s,'v)behavior.tset\<Rightarrow>('a,'s,'v)behavior.tset" where "eventuallyP=raw.untilUNIVP"
definition always::"('a,'s,'v)behavior.tsetP\W\le< where "alwaysP=-raw.eventually(-P)"
lemmasimps: shows "raw.state_prop\<langle>False\<rangle>={}" "raw.state_prop\<bottom>={}" "raw.state_prop\<langle>True\<rangle>=UNIV" "raw.state_prop\<top>=UNIV" "-raw.state_propP=raw.state_prop(-P)" "raw.state_propP\<union>raw.state_propQ=raw.state_prop(P\<squnion>Q)" "raw.state_propP\<inter>raw.state_propQ=raw.state_prop(P\<sqinter>Q)" "(raw.state_propP\<^bold>\<longrightarrow>\<^sub>Braw.state_propQ)=raw.state_prop(P\<^bold>\<longrightarrow>\<^subjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 by(autosimp:raw.state_prop_defboolean_implication.set_alt_def)
lemmauntilR: shows"raw.untilP(raw.untilPQ)=raw.untilPQ"(is"?lhs=?rhs") proof(ruleantisym[OFsubsetI]) show"\<omega>\<in>?rhs"if"\<omega>\<in>?lhs"for\<omega>usingthatbyinductblast+ show"?rhs\<subseteq>?lhs"byblast qed
lemmaInfL_not_empty: assumes"X\<noteq>{}" shows"raw.until(\<Inter>X)Q=(\<Inter>x\<in>X.raw.untilxQ)"(is"?lhs=?rhs") proof(ruleantisym[OF_subsetI]) show"?lhs\<subseteq>?rhs" by(simpadd:INT_greatestInter_lowerraw.until.mono) show"\<omega>\<in>?lhs"if"\<omega>\<in>?rhs"for\<omega> proof- from\open>\noteq>{}<close>obtainPwhere"P\<in>X"byblast withthatobtaini\<omega>' where*:"behavior.dropni\<omega>=Some\<omega>'""\<omega>'\<in>Q""\<forall>j<i.the(behavior.dropnj\<omega>)\<in>P" unfoldingraw.until_defbyblast fromthis(1,2)obtaink\<omega>'' where**:"k\<le>i""behavior.dropnk\<omega>=Some\<omega>'java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 usingex_has_least_nat[wherek=iandP="\<lambda>\<^item\<citet><open\<open\S2<>"AlpernSchneider:1985andAlpernDemersSchneider1986and"Schneider:1987"<> byclarsimp(metis(no_types,lifting)behavior.dropn.shorterDleDnle_leoption.selorder.trans) fromthat***show?thesis by(clarsimpsimp:raw.until_def\open><sigma>\open.sigmaNone\> (metisorder.strict_trans1<item\citet\><>S21close"badiLamport:991\<lose>considerthesebehaviorstorepresentterminatingjava.lang.StringIndexOutOfBoundsException: Index 138 out of bounds for length 138 qed qed
lemmauntilL: shows"raw.until(raw.untilPQ)Q\<subseteq>raw.untilPQ"(is"?lhs\<subseteqFalsewithassmsshow"<exists>omega'\><>P\<>behaviori\omega=behavior.<>" proof(rulesubsetI) show"\<omega>\<in>?rhs"if"\<omega>\<in>?lhs"for\<omega> usingbyinductjava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29 split:option..split
lemmaalwaysR_le: shows"raw.untilP(raw.alwaysQ)\<subseteq>raw.always(raw.untilPQ)"(is"?lhs\<subseteq>?rhs") proof(rulesubsetI) show"\<omega>\<in>?rhs"if"\<omega>\<in>?lhs"for\<omega> usingthat proofinduct shows\>inPjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 next case(step\<omega>\<omega>')show?case proof(ruleraw.alwaysI) ?<>?" withstep"behavior.dropn.0"show"\qed(simpadd:raw.afety.expansive) by(casesi;clarsimpsimp:raw.always_alt_defbehavior.dropn.Suc;blast) qed qed qed
setup\<open>Sign.parent_path\<close>
>""\close
safetycl_altI) rule[,)] fix\<omega> assume*:"\<omega>\<notin>raw.untilPQ" assume"\<omega>\:option.split) thenobtaink\<omega>' where"behavior.dropnk\<length_ttaketfinite_tlength_conv) and"\<omega>'byblast by(clarsimpsimp:raw.always_alt_def) withex_has_least_nat[wherek=kandP="\<lambda>i.\<exists>\<omega>'.behavior.dropni\<omega>=Some\<omega>'\<and>\<omega>'\<notin>P\inbehavior.." obtaink\<omega>' "behaviordropn\\>=Some<>java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54 and"<mega<>Pjava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 and"note\openrawsafetyclP\subseteqraw.\<> byclarsimp(metisbehavior.dropn.shorterDless_le_not_leoption.distinct(1)option.exhaust_sel) with*behavior.dropn.shorterDshow"\<omega>\<in>?rhs" by(fastforce:"<>i.\<exists>\<beta.\forall>\<omega'behavior.dropnk(.takei\<>@-<subB\beta)Some\omega'\<longrightarrow>\<omega>'\<in>P" next show"?rhs\<subseteq>?lhs" by(clarsimpsimp:raw.always_alt_defraw.until_defsubset_iff;metisnat_neq_iffoption.sel) qed
lemmaterminated shows"raw.eventuallyraw.terminated={\<omega>.tfinite(behavior.rest\<omega>)}"(is"fixi ([OF_] show"?lhs\<subseteq>?rhs" clarsimpsimp:raw.ventually_alt_def.terminated_defbehavior.ropntfiniteD) show"\<omega>\<in>?lhs"if"\<omega>\<in>?rhs"for\<omega> proof- note\<open>\<omega>\<in>?rhs\<close> moreoverfromcalculation tainiwhere"length(behaviorrest\<omega)ijava.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62 by(clarsimpsimp:tfinite_tlength_conv) moreoverfromcalculation obtain\<omega>'where"behavior.dropnbyjava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12 usingbehaviordropneq_Some_tlength_convby moreoverfromcalculation have"behavior.sset\<omega>'\<subseteq>{behavior.init\<omega>'}" by(cases\<omega>') clarsimpdest!behavior..:tdropn_tlength..) "omega<nlhs by(auto"\in>rawsafetyclosed
lemmauntil[intro]: assumes"P\<in>behavior.stuttering.closed" assumes"Q\<in>behavior.stuttering.closed" shows"awuntil\instuttering" proof- ega><^ub2<inrawuntilPQ"if"<><sub>1\<>."and\omega\<sub1\simeq\^><>\<sub2for<><sub><omega\^sub2 usingthat proof(inductarbitrary:\<omega>\<^sub>2rule:raw.until.induct) case(base\<omega>\<^sub>1\<omega>\<^sub>2applyclarsimp by(blastintro:behavior.stuttering.closed_in) next case(step\<omega>\<^sub>1\<omega>'\<omega>\<^sub>2) showjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 proof(cases"\<omega>'\<simeq>\<^sub>T\<omega>\<^sub>1"<>Sign.\close caseTruewith\<open>java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 bysimp next caseFalse fromassms(1)\<open>\<omega>\<^sub>1\<in>P\<close>\<open>\<omega>\<^sub>1\<simeq>\<^sub>T\<omega>\<^sub>2\<close>have"\<omega>\<^sub>2\<in>P" by(blastintro:behavior.stuttering.closed_in) obtainas\<^sub>0s\<^sub>1xs\<^sub>1xs'ys' where\<omega>\<^sub>1:"\<omega>\<^sub>1=behaviorthat2) and\<omega>\<^sub>2:"\<omega>\<^sub>2=behavior.Bs\<^sub>0showthesis and*:"collapses\<^sub>0(TCons(a,s\<^sub>1)xs\<^sub>1)=collapses\<^sub>0(tshiftxs'(TCons(a,s\<^sub>1)ys'))" "s\<^sub>0\<noteq>s\<^sub>1" ':"sndset'<>{s\^>" by(cases\<omega>\<^sub>1;cases\<omega>\<^sub>2;cases"behavior.rest\<omegausingrawspecclosedto_specby (fastforcesimp:behavior.natural_defcollapse.eq_TCons_convtrepeat_eq_TCons_conv split from\<omega>\<^sub>2\<open>\<omega>\<^sub>2\<in>P\<close>xs'show?thesis proofxsarbitrary:\omega<^>) caseNilwith\<omega>\<^sub>1**step.hyps(2,4)show?case by(autosimp:behavior.natural_def) next case(Consx'xs') withbehavior.stuttering.closed_in[OF__\<open>P\<in>behavior.stuttering.closed\<close>]\<omega>\<^sub>1**step(3) show?case by(autosimp:behavior.natural_defbehavior.split_all) qed qed qed thenshow?thesis by(fastforceelim:behavior.stuttering.clE) qed
definition::"(,'s')tls\Rightarrow>bool"java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63 "validP\<longleftrightarrow>P=\top>java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
lift_definitionstate_prop::"'spred\<Rightarrow>('a,'s,alsohave"<dots=?rhs lift_definitionterminated::"('a,'java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 lift_definitionuntil::"('a,'s,'v)tls\<Rightarrow>('a,'s,'v)tls\<Rightarrow>('a,'s,'v)tls"israw.until..
definitionalways::"('a,'s,'v)tls\<Rightarrow>('a,'s,'v)tls"where "alwaysjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
definitionrelease::"('a,'s,'v)tls\<Rightarrow>('a,'s,'v)tls\<Rightarrow>('a,'s,'v)tls"where "releasePQ=-(tls.until(-Pjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
open_bundle"syntax" begin notationtls.valid(\<open>\<Turnstile>_\<close>[30]30) notationsimp:rawto_spec_def) notationtls.until(infix\<open>\<U>\<close>85) notationby notationtls.always(\<open>\<box>_\<close>[87]87) notationtls.release(infixr\<openjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 notationtls.unless(infixr\<open>\<W>\<close>85) notationtls.always_imp_syn(infixr\<open>\<^bold>\<longrightarrow>\<^sub>\<box>\<close>75) notationtls.leads_to(infixr\<open>\<^bold>\<leadsto>\<close>75) end
bundle"no_syntax" begin no_notationtls.valid(\<open>\<Turnstile>_\<close>[30]30) no_notationtls.state_prop:"(a>)\>(as')\Rightarrow>(',','v)tlswhere no_notationtls.until(infixr\<open>\<U>\<close>85) no_notationtls.eventually(\<open>\<diamond>_\<close>[87]87) no_notationtlsalways(<open\>_close[87]) no_notationtls.release(infixr\<open>\<R>\<close>85) no_notationtls.unless(infixr\<open>\<W>\<close>85) no_notationtls.always_imp_syn(infixr\<open>\<^bold>\<longrightarrow>\<^sub>\<box>\<close>75) proofstandard end
lemmamp: assumeslemmasmono=monotoneD[tlsmapmonotonejava.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44 assumes"\<Turnstile>P" shows"\<Turnstile>Q" usingassmsby(simpadd:tls.valid_def)
lemmauminus_le_conv[tls.singleton.le_conv]: shows"\<lblot>\<omega>\<rblot>\<^sub>T\<le>-P\<java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 bytransfer (simpadd:raw.singleton_defbehavior.stuttering.closed_uminusbehavior.stuttering.least_conv)
lemmaterminated_le_conv[tls.singleton.le_conv]: shows"\<lblot>\<omega>\<rblot>\<^sub>Tjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 bytransfer (simpadd:raw.singleton_defbehavior.stuttering.least_conv[OFbehavior.stuttering.closed.rawandtls(lambda>x.)(lambdax.)(\lambdax)P" :raw
assume *: "P ∈ behavior.stuttering.closed" "Q ∈ behavior.stuttering.closed"
and "raw.singleton ψ raw.until P Q"
then have "∃i. ∃ψ'∈Q. behavior.dropn i ψ = Some ψ' ∧ (∀ ``propositional'' means that actions are treated separately; we omit this part as we don't have actions ala TLA
by (auto simp: raw.singleton_def raw.until_def)
with * show "∃vi.diψ = Some ψ' ∧ raw.singleton ψ' ⊆
by (auto simp: raw.singleton_def behavior.stuttering.least_conv)
qed
show "?rhs ==>
bytranssfer
(unfold raw.singleton_def;
rule behavior.stuttering.least[OF _ behavior.stuttering.closed.raw.untl;
auto 1 0 intro iffD2OF qsett_m_f[OFraw.until_def]])
java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 3
eventually_le_conv[tls.singleton.le_conv]:
shows "(•ψ•)T≤♢P ⟷ (∃i ψ'. behavior.dropn i ψ = Some ψ' ∧(•ψ'•)T≤ P)"
(simp add: tls.eventually_def tls.singleton.le_conv)
always_le_conv[tls.singleton.le_conv]:
shows "(•ψ•)T≤ tls.always P ⟷ (∀i ψ'. behavior.dropn i ψ = Some ψ' ⟶(•ψ'•)T≤ P)"
(simp add: tls.always_def tls.singleton.le_conv)
‹Sign.parent_path›
until: closure_complete_lattice_distributive_class "tls.until P" for P
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)
‹Sign.mandatory_path "until"›
botL = raw.until.botL[transferred]
botR = raw.until.botR[transferred]
topR = tls.until.cl_top
expansiveR = tls.until.expansive[of P Q for P Q]
weakenL = raw.until.weakenL[transferred]
mono = raw.until.mono[transferred]
strengthen[strg]:
assumes "st_ord F P P'"
assumes "st_ord F Q Q'"
shows "st_ord F (P U Q) (P' U Q')"
assms by (cases F) (auto simp: tls.until.mono)
SupL_le:
shows "(⊔x∈X. x U R) ≤ (⊔X) U R"
(simp add: SupI tls.until.mono)
InfL_not_empty = raw.until.InfL_not_empty[transferred]
infL = tls.until.InfL_not_empty[where X="{P, Q}" for P Q, simplified, of P Q R for P Q R]
infR_le = tls.until.cl_inf_le[of P Q R for P Q R]
implication_ordering_le: ―🍋‹ in "WarfordVegaStaley:2020"›
shows "P U Q ⊓ (-Q) U R ≤ψ'. behavior.dropn i ψ' ∧
ransfer (rule raw.until.implication_ordering_le)
supL_ordering_le: ―‹🍋to desD)
shows "P U (Q U R) ≤ (P ⊔ Q) U R" (is "?lhs ≤
-
have "?rhs = (P ⊔ Q) U ((P ⊔ Q) U R)" by (rule tls.until.idempotent(1)[symmetric])
also have "?lhs ≤" by (blast intro: tls.until.mono le_supI1 le_supI2)
finally show ?thesis .
infR_ordering_le: ―‹
shows "P U (Q ⊓ R) ≤ (P U Q) U R"
transfer (rule raw.until.infR_ordering_le)
oe_ipliatodtile \comment< \🍋‹‹(19)› in "WarfordVegaStaley:2020"››
shows "(P B Q) U R ≤\⟶B (Q U R)"
(metis galois.conj_imp.galois order.refl tls.until.infL tls.until.mono)
excluded_middleR: ―j < i Suc.hyps
shows "⊨ P U Q ⊔h =m +n ]slt:atdf_i_sm
(simp add: tls.validI tls.until.cl_top flip: tls.until.cl_sup)
untilR = tls.until.idempotent(1)[of P Q for P Q]
untilL:
Q) U " (i "?lhlhs ?rs")
(rule antisym)
show lh \le> ?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
absorb:
shows "P U
(metis tls.until.botL tls.until.untilL)
absorb_supL: ―🍋‹(23)› in "WarfordVegaStaley:200"››
shows "P ⊔ P U Q = P ⊔ Q"
(metis inf_commute inf_sup_absorb le_iff_sup
assumes "🚫P \⟶B Q"
absorb_supR: ―
shows "Q ⊔ P U Q = P U Q"
(simp add: sup.absorb2 tls.until.expansive)
eventually_le:
shows "P U Q ≤Q"
(simp add: tls.eventually_def tls.until.mono)
absorb_eventually:
shows inf_eventually_absorbR: "P U Q ⊓♢Q = P U Q" \<commentnotation(•_rblot>[0])
and sup_eventually_absorbR: "P U Q ⊔♢Q = ♢Q" ―‹
and eventually_absorbR: "P U♢Q = ♢Q" ―‹🍋‹
(simp_all add: tls.eventually_def sup.absorb2 tls.until.mono
(*>*)
flip: tls.until.infL)
sup_le: ―‹🍋‹‹(28)› in "WarfordVegaStaley:2020"››
shows "P U Q ≤ P ⊔ Q"
(simp add: ac_simps sup.absorb_iff1 tls.until.absorb_supL tls.until.absorb_supR)
ordering: ―‹🍋‹‹(251)› in "WarfordVegaStaley:2020"››
shows "(-P) U Q ⊔ (-Q) U P = ♢(P ⊔ Q)" (is "?lhs = ?rhs")
-
have "?lhs = ⊤U P ⊓ (- Q) U P ⊔⊤U Q ⊓ (- P) U Q"
by (simp add: ac_simps inf.absorb2 tls.until.mono)
also have "… = (- P) U P ⊓ (- Q) U P ⊔ (- Q) U Q ⊓ (- P) U Q"
by (simp add: tls.until.weakenL)
also have "… = (- (P ⊔ Q)) U (P ⊔ Q)"
by (simp add: ac_simps tls.until.cl_sup flip: tls.until.infL)
also have "… = ?rhs"
by (simp add: tls.eventually_def tls.until.weakenL)
finally show ?thesis .
always_eventually_sup: ―‹🍋‹‹(161)› in "WarfordVegaStaley:2020"››
fixes P :: "('a, 's, 'v) tls"
shows "◻♢(P ⊔ Q) = ◻♢P ⊔◻♢Q" (is "?lhs = ?rhs")
(rule antisym)
show "?lhs ≤ ?rhs"
proof transfer
fix P Q :: "('a, 's, 'v) behavior.t set"
have "∃ψ'∈P. ∃i. behavior.dropn i ψj = Some ψ'"
if "∀i ψ'. behavior.dropn i ψ = Some ψ' ⟶ (∃ψ''∈P ∪ Q. ∃i. behavior.dropn i ψ' = Some ψ'')"
and "behavior.dropn i ψ = Some ψi"
and "∀ψ'∈Q. ∀i. behavior.dropn i ψi≠ Some ψ'"
and "behavior.dropn j ψ = Some ψj"
for ψ i j ψi ψj
using spec[where x="max i j", OF that(1)] that(2,3,4)
by (clarsimp simp: nat_le_iff_add split: split_asm_max;
metis add_diff_inverse_nat behavior.dropn.dropn bind.bind_lunit order.asym)
then show "raw.always (raw.eventually (P ∪ Q)) ⊆ raw.always (raw.eventually P) ∪ raw.always (raw.eventually Q)"
by (clarsimp simp: raw.eventually_alt_def raw.always_alt_def)
qed
show "?rhs ≤ ?lhs"
by (simp add: tls.eventually.sup order.trans[OF _ tls.always.sup_le])
neg: ―‹🍋‹‹(170)› in "WarfordVegaStaley:2020"››
shows "-(P W Q) = (-Q) U (-P ⊓ -Q)"
transfer (rule raw.unless.neg)
alwaysR_le: ―‹🍋‹‹(177)› in "WarfordVegaStaley:2020"››
shows "P W◻Q ≤◻(P W Q)"
(simp add: tls.unless_def order.trans[OF tls.until_alwaysR_le] tls.always.mono
order.trans[OF _ tls.always.sup_le])
sup_le: ―‹🍋‹‹(206)› in "WarfordVegaStaley:2020"››
shows "P W Q ≤ P ⊔ Q"
(rule iffD1[OF compl_le_compl_iff]) (simp add: tls.unless.neg tls.until.expansive)
ordering: ―‹🍋‹‹(252)› in "WarfordVegaStaley:2020"››
shows "⊨ (-P) W Q ⊔ (-Q) W P"
(simp add: ac_simps tls.validI tls.unless_def tls.until.ordering tls.eventually.sup flip: tls.eventually.neg)
‹Sign.parent_path›
‹Sign.mandatory_path "until"›
eq_unless_inf_eventually:
shows "P U Q = (P W Q) ⊓♢Q"
transfer (force simp: raw.until_def raw.eventually_def raw.always_alt_def behavior.dropn.shorterD)
always_strengthen_le: ―‹🍋‹‹(83)› in "WarfordVegaStaley:2020"››
shows "◻P ⊓ (Q U R) ≤ (P ⊓ Q) U (P ⊓ R)"
transfer
(clarsimp simp: raw.until_def raw.always_alt_def;
fastforce simp: behavior.dropn.shorterD del: exI intro!: exI)
until_weakI:
shows "◻P ⊓♢Q ≤ P U Q" (is "?lhs ≤ ?rhs") ―‹🍋‹‹(84)› in "WarfordVegaStaley:2020"››
(simp add: tls.eventually_def order.trans[OF tls.until.always_strengthen_le] tls.until.mono)
always_impL: ―‹🍋‹‹(86)› in "WarfordVegaStaley:2020"››
shows "P \⟶\◻ P' ⊓ P U Q ≤ P' U Q" (is ?thesis1)
and "P U Q ⊓ P \⟶\◻ P' ≤ P' U Q" (is ?thesis2)
-
show ?thesis1
by (rule order.trans[OF tls.until.always_strengthen_le])
(simp add: tls.until.mono boolean_implication.shunt1)
then show ?thesis2
by (simp add: inf_commute)
always_impR: ―‹🍋‹‹(85)› in "WarfordVegaStaley:2020"››
shows "Q \⟶\◻ Q' ⊓ P U Q ≤ P U Q'" (is ?thesis1)
and "P U Q ⊓ Q \⟶\◻ Q' ≤ P U Q'" (is ?thesis2)
-
show ?thesis1
by (rule order.trans[OF tls.until.always_strengthen_le])
(simp add: tls.until.mono boolean_implication.shunt1)
then show ?thesis2
by (simp add: inf_commute)
neg: ―‹🍋‹‹(173)› in "WarfordVegaStaley:2020"››
shows "-(P U Q) = (-Q) W (-P ⊓ -Q)"
tls.unless_def
(simp flip: tls.until.eq_unless_inf_eventually tls.unless.neg tls.eventually.neg
boolean_algebra.de_Morgan_conj)
‹ Leads-to and leads-to-via \label{sec:TLS_leads-to} ›
‹
-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.
leads_to_leads_to_via:
shows "P \⟶\◻ Q U R ≤ P \↝ R"
(simp add: boolean_implication.mono tls.always.mono tls.until.eventually_le)
leads_to_trans:
shows "P \↝ Q ⊓ Q \↝ R ≤ P \↝ R" (is "?lhs ≤ ?rhs")
-
have "?lhs ≤ P \↝ Q ⊓◻(Q \↝ R)"
by (simp add: tls.always.simps)
also have "…≤ P \↝ Q ⊓♢Q \↝ R"
by (meson order.refl inf_mono tls.always.mono tls.always_imp_eventually_generalization)
also have "…≤ ?rhs"
by (simp add: boolean_implication.trans tls.always.mono flip: tls.always.inf)
finally show ?thesis .
leads_to_via_weakenR:
shows "Q \⟶\◻ Q' ⊓ P \⟶\◻ I U Q ≤ P \⟶\◻ I U Q'"
transfer
(clarsimp simp: raw.always_alt_def raw.until_def boolean_implication.set_alt_def;
metis behavior.dropn.dropn Option.bind.bind_lunit)
leads_to_via_supL: ―‹ useful for case distinctions ›
shows "P \⟶\◻ I U Q ⊓ P' \⟶\◻ I' U Q ≤ P ⊔ P' \⟶\◻ (I ⊔ I') U Q"
(simp add: boolean_implication.conv_sup ac_simps le_infI2 le_supI2
monoD[OF tls.always.monotone] tls.until.mono)
leads_to_via_trans:
shows "(P \⟶\◻ I U Q) ⊓ (Q \⟶\◻ I' U R) ≤ P \⟶\◻ (I ⊔ I') U R" (is "?lhs ≤ ?rhs")
-
have "?lhs ≤◻(P \⟶B I U (I' U R))"
by (subst inf.commute) (rule tls.leads_to_via_weakenR)
also have "…≤ ?rhs"
by (strengthen ord_to_strengthen(1)[OF tls.until.supL_ordering_le]) (rule order.refl)
finally show ?thesis .
leads_to_via_disj: ―‹ more like a chaining rule ›
shows "(P \⟶\◻ I U Q) ⊓ (Q \⟶\◻ I' U R) ≤ (P ⊔ Q \⟶\◻ (I ⊔ I') U R)"
(simp add: boolean_implication_def inf.coboundedI2 le_supI2 tls.always.mono tls.until.mono)
‹ Fairness\label{sec:tls-fairness} ›
‹
few renderings of weak fairness. 🍋‹"vanGlabbeekHofner:2019"› call this
`response to insistence'' as a generalisation of weak fairness.
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')"
assms by (cases F) (auto simp: tls.weakly_fair.mono)
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')"
assms by (cases F) (auto simp: tls.strongly_fair.mono)
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)"
(simp add: boolean_implication.conv_sup sup_inf_distrib2 tls.always.inf tls.always_eventually_sup
tls.strongly_fair_def)
now carve the safety properties out of the 🍋‹('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 🍋‹('a, 's, 'v) spec›.
: ▪ our safety closure for 🍋‹('a, 's, 'v) tls› introduces infinite sequences to stand for the
prefixes in 🍋‹('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
›
‹Sign.mandatory_path "raw"›
to_spec :: "('a, 's, 'v) behavior.t set ==> ('a, 's, 'v) trace.t set" where
"to_spec T = {behavior.take i ψ |ψ i. ψ ∈ T}"
from_spec :: "('a, 's, 'v) trace.t set ==> ('a, 's, 'v) behavior.t set" where
"from_spec S = {ψ . ∀i. behavior.take i ψ ∈ S}"
safety: galois.powerset raw.to_spec raw.from_spec
standard (fastforce simp: raw.to_spec_def raw.from_spec_def)
cl_altI:
assumes "∧i. ∃ψ' ∈ P. behavior.take i ψ = behavior.take i ψ'"
shows "ψ ∈ raw.safety.cl P"
assms by (fastforce simp: raw.safety.cl_def raw.from_spec_def raw.to_spec_def)
cl_altE:
assumes "ψ ∈ raw.safety.cl P"
obtains ψ' where "ψ' ∈ P" and "behavior.take i ψ = behavior.take i ψ'"
(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)
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)
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")
(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"
then show "∃ψ'∈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
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)}"
raw.safety.closed_def raw.safety.cl_alt_def by fast
closed_alt_def2: ―‹ Contraposition gives the customary prefix-closure definition ›
shows "raw.safety.closed = {P. ∀ψ. (∀i. ∃β. behavior.take i ψ @-B β ∈ P) ⟶ ψ ∈ P}"
raw.safety.closed_alt_def by fast
closedI2:
assumes "∧ψ. (∧i. ∃β. behavior.take i ψ @-B β ∈ P) ==> ψ ∈ P"
shows "P ∈ raw.safety.closed"
assms unfolding raw.safety.closed_alt_def2 by fast
closedE2:
assumes "P ∈ raw.safety.closed"
assumes "∧i. ψ ∉ P ==>∃β. behavior.take i ψ @-B β ∈ P"
shows "ψ ∈ P"
assms unfolding raw.safety.closed_alt_def2 by blast
terminated_iff:
assumes "ψ ∈ raw.terminated"
shows "ψ ∈ raw.safety.cl P ⟷ ψ ∈ P" (is "?lhs ⟷ ?rhs")
(rule iffI)
from assms obtain i where "tlength (behavior.rest ψ) = enat i"
by (clarsimp simp: raw.terminated_def tfinite_tlength_conv)
then show "?lhs ==> ?rhs"
by (metis raw.safety.cl_altE[where i="Suc i"]
behavior.continue.take_drop_id behavior.take.continue_id enat_ord_simps(2) lessI)
(simp add: raw.safety.expansive')
terminated:
shows "raw.safety.cl raw.terminated = raw.idle ∪ raw.terminated" (is "?lhs = ?rhs")
(rule antisym[OF subsetI subsetI])
fix ψ
assume "ψ ∈ ?lhs"
then have "snd (tnth (behavior.rest ψ) i) = behavior.init ψ"
if "enat i < tlength (behavior.rest ψ)"
for i
using that
by (clarsimp simp: raw.terminated_def behavior.take_def behavior.split_all behavior.sset.simps
split_def
simp del: ttake.simps
elim!: raw.safety.cl_altE[where i="Suc i"])
(metis (no_types, lifting) Suc_ile_eq in_tset_conv_tnth nth_ttake
doubleton_eq_iff insert_image insert_absorb2 lessI subset_singletonD ttake_eq_None_conv(1))
then have "behavior.sset ψ ⊆ {behavior.init ψ}"
by (cases ψ) (clarsimp simp: behavior.sset.simps tset_conv_tnth)
then show "ψ ∈ ?rhs"
by (simp add: raw.idle_alt_def raw.terminated_def)
show "ψ ∈ ?lhs" if "ψ ∈ ?rhs" for ψ
using that
proof(cases rule: UnE[consumes 1, case_names idle terminated])
case idle show ?thesis
proof(rule raw.safety.cl_altI)
fix i
let ?ψ' = "behavior.take i ψ @-B TNil undefined"
from idle have "?ψ' ∈ raw.terminated"
by (auto simp: raw.idle_alt_def raw.terminated_def behavior.sset.continue
dest: subsetD[OF behavior.sset.take_le]
split: option.split)
moreover
from idle have "behavior.take i ψ = behavior.take i ?ψ'"
by (simp add: raw.idle_alt_def behavior.take.continue trace.take.behavior.take
length_ttake tfinite_tlength_conv)
ultimately show "∃ψ'∈raw.terminated. behavior.take i ψ = behavior.take i ψ'"
by blast
qed
qed (auto intro: raw.safety.expansive')
le_terminated_bot:
assumes "P ∈ behavior.stuttering.closed"
assumes "raw.safety.cl P ⊆ raw.terminated"
shows "P = {}"
(rule ccontr)
assume ‹P ≠ {}› then obtain ψ where "ψ ∈ P" by blast
let ?ψ' = "behavior.B (behavior.init ψ) (trepeat (undefined, behavior.init ψ))"
from ‹ψ ∈ P› have "?ψ' ∈ raw.safety.cl P"
by (fastforce intro: exI[where x="behavior.rest ψ"]
behavior.stuttering.f_closedI[OF ‹P ∈ behavior.stuttering.closed›]
simp: raw.safety.cl_alt_def behavior.take.trepeat behavior.continue.simps
behavior.natural.tshift collapse.tshift trace.natural'.replicate
trace.final'.replicate
behavior.stuttering.f_closed[OF ‹P ∈ behavior.stuttering.closed›]
simp flip: behavior.natural_def)
moreover have "?ψ' ∉ raw.terminated"
by (simp add: raw.terminated_def)
moreover note ‹raw.safety.cl P ⊆ raw.terminated›
ultimately show False by blast
always_le:
shows "raw.safety.cl (raw.always P) ⊆ raw.always (raw.safety.cl P)"
raw.always_alt_def raw.safety.cl_alt_def subset_iff mem_Collect_eq
(intro allI impI)
fix ψ i ψ' j
assume *: "∀i. ∃β. ∀k ψ'. behavior.dropn k (behavior.take i ψ @-B β) = Some ψ' ⟶ ψ' ∈P"
and **: "behavior.dropn i ψ = Some ψ'"
from spec[where x="i + j", OF *] ** behavior.take.dropn[OF **, where j=j]
show "∃β. behavior.take j ψ' @-B β ∈ P"
by (clarsimp dest!: spec[where x=i])
(subst (asm) behavior.dropn.continue_shorter;
force simp: length_ttake trace.dropn.behavior.take
dest: behavior.dropn.eq_Some_tlengthD
split: enat.split)
eventually:
assumes "P ≠⊥"
shows "raw.safety.cl (raw.eventually P)
= -raw.eventually raw.terminated ∪ raw.eventually P" (is "?lhs = ?rhs")
(rule antisym[OF subsetI iffD2[OF Un_subset_iff, simplified conj_explode, rule_format, OF subsetI]])
show "ψ ∈ ?rhs" if "ψ ∈ ?lhs" for ψ
proof(cases "tlength (behavior.rest ψ)")
case (enat i) with that show ?thesis
by (fastforce dest: spec[where x="Suc i"]
simp: raw.safety.cl_alt_def raw.terminated_def behavior.take.continue_id)
qed (simp add: raw.eventually.terminated tfinite_tlength_conv)
from assms obtain ψP where "ψP∈ P" by blast
show "ψ ∈ ?lhs" if "ψ ∈ -raw.eventually raw.terminated" for ψ
proof(intro raw.safety.cl_altI exI bexI)
fix i
let ?ψ' = "behavior.take i ψ @-B TCons (undefined, behavior.init ψP) (behavior.rest ψP)"
from ‹ψP∈ P›‹ψ ∈ -raw.eventually raw.terminated› show "?ψ' ∈ raw.eventually P"
unfolding raw.eventually.terminated
by (auto intro!: exI[where x="Suc i"]
simp: raw.eventually_alt_def tfinite_tlength_conv behavior.dropn.continue
length_ttake ttake_eq_None_conv)
from ‹ψ ∈ -raw.eventually raw.terminated› show "behavior.take i ψ = behavior.take i ?ψ'"
by (simp add: raw.eventually.terminated behavior.take.continue trace.take.behavior.take
length_ttake tfinite_tlength_conv
split: enat.split)
qed
show "raw.eventually P ⊆ ?lhs"
by (fast intro!: order.trans[OF _ raw.safety.expansive])
‹Sign.parent_path›
‹Sign.mandatory_path "closed"›
always_eventually:
assumes "P ∈ raw.safety.closed"
assumes "∀i. ∃j≥i. ∃β. behavior.take j ψ @-B β ∈ P"
shows "ψ ∈ P"
assms(1)
(rule raw.safety.closedE2)
fix i
from spec[OF assms(2), where x=i] obtain j β where "i ≤ j" and "behavior.take j ψ @-B β ∈ P"
by blast
then show "∃β. behavior.take i ψ @-B β ∈ P" if "ψ ∉ P"
using that
by (clarsimp simp: tdropn_tshift2 behavior.continue.tshift2 behavior.continue.take_drop_shorter length_ttake
behavior.continue.term_Some behavior.take.term_Some_conv ttake_eq_Some_conv
split: enat.split split_min
intro!: exI[where x="tdropn i (behavior.rest (behavior.take j ψ @-B β))"])
unless: ―‹🍋‹‹\S3.1› in "Sistla:1994"› -- minimality is irrelevant ›
assumes "P ∈ raw.safety.closed"
assumes "Q ∈ raw.safety.closed"
shows "raw.unless P Q ∈ raw.safety.closed"
(rule raw.safety.closedI2)
fix ψ assume *: "∃β. behavior.take i ψ @-B β ∈ raw.unless P Q" for i
show "ψ ∈ raw.unless P Q"
proof(cases "∀i j ψ'. ∃β. behavior.dropn i ψ = Some ψ' ⟶ behavior.take j ψ' @-B β ∈ P")
case True
with ‹P ∈ raw.safety.closed› have "behavior.dropn i ψ = Some ψ' ⟶ ψ' ∈ P" for i ψ'
by (blast intro: raw.safety.closedE2)
then show ?thesis
by (simp add: raw.always_alt_def)
next
case False
then obtain ψ' k l
where **: "behavior.dropn k ψ = Some ψ'" "∀β. behavior.take l ψ' @-B β ∉ P"
by clarsimp
{
fix i β
assume kli: "k + l ≤ i"
moreover
note **
moreover
from kli have "∃j. i - k = l + j" by presburger
moreover
from ‹behavior.dropn k ψ = Some ψ'› kli
have ***: "k ≤ length (trace.rest (behavior.take i ψ))"
by (fastforce simp: length_ttake split: enat.splits
dest: behavior.dropn.eq_Some_tlengthD)
ultimately have ****: "∀ψ''. behavior.dropn k (behavior.take i ψ @-B β) = Some ψ'' ⟶ ψ'' ∉ P"
by (force simp: behavior.dropn.continue_shorter trace.dropn.behavior.take behavior.take.add
simp flip: behavior.continue.tshift2)
{
assume PQ: "behavior.take i ψ @-B β ∈ raw.unless P Q"
from **** PQ obtain m
where "m ≤ k"
and "∀ψ'. behavior.dropn m (behavior.take i ψ @-B β) = Some ψ' ⟶ ψ' ∈ Q"
and "∀p<m. (∀ψ'. behavior.dropn p (behavior.take i ψ @-B β) = Some ψ' ⟶ ψ' ∈ P)"
by (auto 6 0 simp: raw.until_def raw.always_alt_def)
(metis behavior.dropn.shorterD leI nle_le option.sel)
with kli ***
have "(∃m≤k. (∀ψ'. behavior.dropn m ψ = Some ψ' ⟶ behavior.take (i - m) ψ' @-B β ∈ Q) ∧ (∀p<m. (∀ψ'. behavior.dropn p ψ = Some ψ' ⟶ behavior.take (i - p) ψ' @-B β ∈ P)))"
by (clarsimp simp: exI[where x=m] behavior.dropn.continue_shorter trace.dropn.behavior.take)
}
}
then have "∀i. ∃n≥i. ∃m≤k. ∃β. (∀ψ'. behavior.dropn m ψ = Some ψ' ⟶ behavior.take (n - m) ψ' @-B β ∈ Q) ∧ (∀p<m. ∀ψ'. behavior.dropn p ψ = Some ψ' ⟶ behavior.take (n - p) ψ' @-B β ∈ P)"
using * by (metis nle_le)
then obtain m
where "m ≤ k" "∀i. ∃n≥i. ∃β. (∀ψ'. behavior.dropn m ψ = Some ψ' ⟶ behavior.take (n - m) ψ' @-B β ∈ Q) ∧ (∀p<m. ∀ψ'. behavior.dropn p ψ = Some ψ' ⟶ behavior.take (n - p) ψ' @-B β ∈ P)"
by (clarsimp simp: always_eventually_pigeonhole)
with behavior.dropn.shorterD[OF ‹behavior.dropn k ψ = Some ψ'›‹m ≤ k›]
raw.safety.closed.always_eventually[OF ‹P ∈ raw.safety.closed›]
raw.safety.closed.always_eventually[OF ‹Q ∈ raw.safety.closed›]
show "ψ ∈ raw.unless P Q"
apply -
apply clarsimp
apply (rule raw.untilI, assumption)
apply (meson add_le_imp_le_diff)
apply (metis add_le_imp_le_diff option.sel behavior.dropn.shorterD[OF _ less_imp_le])
done
qed
from_spec:
shows "raw.from_spec ` trace.stuttering.closed ⊆ (behavior.stuttering.closed :: ('a, 's, 'v) behavior.t set set)"
-
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 *)
safety_cl:
assumes "P ∈ behavior.stuttering.closed"
shows "raw.safety.cl P ∈ behavior.stuttering.closed"
raw.safety.cl_def using assms
(blast intro: subsetD[OF behavior.stuttering.closed.from_spec]
subsetD[OF trace.stuttering.closed.to_spec])
‹Sign.parent_path›
‹Sign.mandatory_path "tls"›
to_spec :: "('a, 's, 'v) tls ==> ('a, 's, 'v) spec" is raw.to_spec
raw.spec.closed.to_spec by blast
eventually: ―‹ all the infinite traces and any finite ones that satisfy ‹♢P››
assumes "P ≠⊥"
shows "tls.safety.cl (♢P) = -♢tls.terminated ⊔♢P"
assms by transfer (rule raw.safety.cl.eventually)
not_terminated:
shows "tls.safety.cl (- tls.terminated) = - tls.terminated" (is "?lhs = ?rhs")
-
have "?lhs = tls.safety.cl (♢(- tls.terminated))"
by (simp flip: tls.always.neg tls.terminated.eq_always_terminated)
also have "… = - ♢tls.terminated ⊔♢(- tls.terminated)"
by (metis tls.safety.cl.eventually tls.terminated.not_top
boolean_algebra.compl_zero boolean_algebra_class.boolean_algebra.double_compl)
also have "… = ?rhs"
by (simp add: sup.absorb2 tls.eventually.expansive
flip: tls.always.neg tls.terminated.eq_always_terminated)
finally show ?thesis .
le_terminated_conv:
shows "tls.safety.cl P ≤ tls.terminated ⟷ P = ⊥" (is "?lhs ⟷ ?rhs")
(rule iffI)
show "?lhs ==> ?rhs"
by transfer (rule raw.safety.cl.le_terminated_bot)
show "?rhs ==> ?lhs"
by simp
‹Sign.parent_path›
‹Sign.mandatory_path "closed"›
transfer[transfer_rule]:
shows "rel_set (pcr_tls (=) (=) (=))
(behavior.stuttering.closed ∩ raw.safety.closed)
tls.safety.closed" (is "rel_set _ ?lhs ?rhs")
(rule rel_setI)
fix X assume "X ∈ ?lhs" then show "∃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)
fix Y assume "Y ∈ ?rhs" then show "∃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)
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 ψ)"
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)
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)"
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)
safety_cl_le_conv[tls.singleton.le_conv]:
shows "(•ψ•)T≤ tls.safety.cl P ⟷ (∀i. ∃ψ'. (•ψ'•)T≤ P ∧ behavior.take i ψ = behavior.take i ψ')"
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)
‹Sign.parent_path›
‹Sign.parent_path›
‹ Maps\label{sec:tls-maps} ›
‹Sign.mandatory_path "tls"›
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})"
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})"
amap ::"('a ==> 'b) ==> ('a, 's, 'v) tls ==> ('b, 's, 'v) tls" where
"amap af ≡ tls.map af id id"
ainvmap ::"('a ==> 'b) ==> ('b, 's, 'v) tls ==> ('a, 's, 'v) tls" where
"ainvmap af ≡ tls.invmap af id id"
smap ::"('s ==> 't) ==> ('a, 's, 'v) tls ==> ('a, 't, 'v) tls" where
"smap sf ≡ tls.map id sf id"
sinvmap ::"('s ==> 't) ==> ('a, 't, 'v) tls ==> ('a, 's, 'v) tls" where
"sinvmap sf ≡ tls.invmap id sf id"
vmap ::"('v ==> 'w) ==> ('a, 's, 'v) tls ==> ('a, 's, 'w) tls" where ―‹ aka ‹liftM››
"vmap vf ≡ tls.map id id vf"
vinvmap ::"('v ==> 'w) ==> ('a, 's, 'w) tls ==> ('a, 's, 'v) tls" where
"vinvmap vf ≡ tls.invmap id id vf"
map_invmap: galois.complete_lattice_distributive_class
"tls.map af sf vf"
"tls.invmap af sf vf" for af sf vf
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)
‹Sign.mandatory_path "singleton"›
map_le_conv[tls.singleton.le_conv]:
shows "(•ψ•)T≤ tls.map af sf vf P ⟷ (∃ψ'. (•ψ'•)T≤ P ∧(•ψ•)T≤(•behavior.map af sf vf ψ'•)T)"
(simp add: tls.map_def)
invmap_le_conv[tls.singleton.le_conv]:
shows "(•ψ•)T≤ tls.invmap af sf vf P ⟷(•behavior.map af sf vf ψ•)T≤ P"
(simp add: tls.invmap_def tls.singleton_le_conv)
(metis behavior.natural.map_natural tls.singleton_eq_conv)
singleton:
shows "tls.map af sf vf (•ψ•)T = (•behavior.map af sf vf ψ•)T"
(auto simp: tls.map_def order.eq_iff tls.singleton_le_conv intro: behavior.stuttering.equiv.map)
id:
shows "tls.map id id id P = P"
and "tls.map (λx. x) (λx. x) (λx. x) P = P"
(simp_all add: tls.map_def flip: id_def)
comp:
shows "tls.map af sf vf ∘ tls.map ag sg vg = tls.map (af ∘ ag) (sf ∘ sg) (vf ∘ vg)" (is "?lhs = ?rhs")
and "tls.map af sf vf (tls.map ag sg vg P) = tls.map (λa. af (ag a)) (λs. sf (sg s)) (λv. vf (vg v)) P" (is ?thesis1)
-
have "?lhs P = ?rhs P" for P
by (rule tls.singleton.exhaust[where x=P])
(simp add: tls.map.Sup tls.map.singleton map_prod.comp image_image comp_def)
then show "?lhs = ?rhs" and ?thesis1 by (simp_all add: comp_def)
map = tls.map.comp
‹Sign.parent_path›
‹Sign.mandatory_path "invmap"›
bot = tls.map_invmap.upper_bot
top = tls.map_invmap.upper_top
singleton:
shows "tls.invmap af sf vf (•ψ•)T = ⊔(tls.singleton ` {ψ'. (•behavior.map af sf vf ψ'•)T≤(•ψ•)T})"
(simp add: tls.invmap_def)
id:
shows "tls.invmap id id id P = P"
and "tls.invmap (λx. x) (λx. x) (λx. x) P = P"
id_def[symmetric] by (metis tls.map.id(1) tls.map_invmap.lower_upper_lower(2))+
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)
-
show "?lhs P = ?rhs P" for P
by (auto intro: tls.singleton.antisym tls.singleton_le_extI simp: tls.singleton.le_conv)
then show ?thesis1
by (simp add: fun_eq_iff comp_def)
invmap = tls.invmap.comp
‹Sign.parent_path›
‹Sign.mandatory_path "to_spec"›
map:
shows "tls.to_spec (tls.map af sf vf P) = spec.map af sf vf (tls.to_spec P)"
(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)
‹Sign.parent_path›
‹Sign.parent_path›
‹ Abadi's axioms for TLA\label{sec:tls-abadi_axioms} ›
‹
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
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 \⟶B Q) ⊔◻(◻Q \⟶B P)"
-
have "⊨ (-◻P) W◻Q ⊔ (-◻Q) W◻P" by (rule tls.unless.ordering)
also have "…≤◻((-◻P) W◻Q) ⊔◻((-◻Q) W◻P)"
by (metis sup_mono tls.always.idempotent tls.unless.alwaysR_le)
also have "…≤◻(-◻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)
also have "… = ◻(◻P \⟶B Q) ⊔◻(◻Q \⟶B P)"
by (simp add: boolean_implication.conv_sup)
finally show ?thesis .
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 \⟶B◻P) \⟶B P) \⟶B♢◻P \⟶B P" (is "⊨ ?goal")
-
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"
(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)
then obtain 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
then obtain 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])
then have "◻(♢(P ⊓♢(- P)) ⊔ P) ⊓♢◻P ≤ P"
by (simp add: boolean_implication.conv_sup tls.always.neg)
then show "⊤≤ ?goal"
by - (intro iffD1[OF boolean_implication.shunt1];
simp add: boolean_implication.conv_sup tls.always.neg)
qed
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.