demonstrate assume/guarantee reasoning by showing the safety of ‹findP›, a classic exercise in
verification. It has been treated by at least:
▪🚫‹‹Example~5.1› in "KarpMiller:1969"› ▪🚫‹‹\S3› in "Rosen:1976"› ▪🚫‹‹\S4 Example~2› in "OwickiGries:1976"› ▪🚫‹‹\S2.4› in "Jones:1983"› ▪🚫‹‹\S3.1› in "XuCauCollette:1994"› ▪🚫‹‹p161› in "Brookes:1996"› (no proof) ▪🚫‹‹Examples~3.57~and~8.26› in "deRoeverEtAl:2001"› (atomic guarded commands) ▪🚫‹‹\S6.2› in "Dingel:2002"› (refinement) ▪🚫‹‹\S10› in "PrensaNieto:2003"› (mechanized, arbitrary number of threads) ▪🚫‹‹\S7.4, \S8.6› in "AptDeBoerOlderog:2009"› ▪🚫‹‹\S4› in "HayesJones:2017"› (refinement)
take the task to be of finding the first element of a given ‹A› that satisfies a given predicate ‹pred›, if it exists, or yielding ‹length A›
it does not. This search is performed with two threads: one
the even indices and the other the odd. There is the
of a thread terminating early if it notices that the other
has found a better candidate than it could.
generalise previous treatments by allowing the predicate to be
modularly and to be a function of the state. It is required
be pure, i.e., it cannot change the observable/shared state, though
could have its own local state.
search loops are defined recursively; one could just as easily use const‹prog.while›. We use a list and not an array for
-- at this level of abstraction there is no difference --
a mix of variables, where the monadic ones are purely local and
state-based are shared between the threads. The lens allows the
to be a value or reside in the (observable/shared) state.
› (* The program and proofs should carry over to TSO directly: the assume is already strong enough. *)
partial_function (lfp) findP_loop_evens :: "nat → ('s state, unit) prog"where "findP_loop_evens i = do { fO ← prog.read get ; prog.whenM (i < fO) (do { v ← prog.read (λs. get' s ! i) ; b ← prog.localize (pred v) ; if b then prog.write (λs. put s i) else findP_loop_evens (i + 2) }) }"
partial_function (lfp) findP_loop_odds :: "nat → ('s state, unit) prog"where "findP_loop_odds i = do { fE ← prog.read get ; prog.whenM (i < fE) (do { v ← prog.read (λs. get' s ! i) ; b ← prog.localize (pred v) ; if b then prog.write (λs. put s i) else findP_loop_odds (i + 2) }) }"
definition findP :: "('s, nat) prog"where "findP = prog.local ( do { N ← prog.read (SIZE get') ; prog.write (λs. put s N) ; prog.write (λs. put s N) ; (findP_loop_evens 0 ∥ findP_loop_odds 1) ; fE ← prog.read (get) ; fO ← prog.read (get) ; prog.return (min fE fO) })"
paragraph‹ Relies and guarantees ›
abbreviation (input) A' :: "'s rel"where"A' ≡ A=∩ ceilr predPre ∩ (∩a. Id a)"
definition AE :: "'s state rel"where "AE = UNIV ×R A' ∩ Id'∩ Id∩\<le>"
definition GE :: "'s state rel"where "GE = Id∩ Id∩\<le>"
definition AO :: "'s state rel"where "AO = UNIV ×R A' ∩ Id'∩ Id∩\<le>"
definition GO :: "'s state rel"where "GO = Id∩ Id∩\<le>"
lemma AG_refl_trans: shows "refl AE" "refl AO" "trans A ==> trans AE" "trans A ==> trans AO" "refl GE" "refl GO" "trans GE" "trans GO" unfolding AE_def AO_def GE_def GO_def by (auto simp: refl_inter_conv refl_relprod_conv
intro!: trans_Int refl_UnionI refl_INTER trans_INTER)
lemma ag_findP_coprime': shows"prog.p2s findP_coprime ≤{⟨True⟩}, Id ⊨ Id, {λrv s. rv = (LEAST i. i < length (getL s) ⟶ coprime (getL s) (getL s ! i))}" unfolding findP_coprime_def apply (rule iag.init) apply (rule ag_findP[where A=Id and array="sndL"and predP="λb s. coprime (getL s) b"andpredPre="⟨True⟩"]) apply (rule iag.init) apply (rule iag.intro)+ apply (rule_tac Q="⟨⟨v⟩= getL⟩"in iag.augment_post_imp) apply (rule iag.stable_augment_frame) apply (rule iag.pre[OF ag.gcd.seq, where A'=Id and P'="⟨True⟩", simplified, OF order.refl]) apply (clarsimp simp: ac_simps coprime_iff_gcd_eq_1 simp flip: One_nat_def; fail) apply (force simp: stable_def monotone_def) apply (rule iag.intro)+ apply (simp; intro conjI INT_greatest ceilr.largest; fastforce simp: stable_def monotone_def)+ done
lemma ag_findP_coprime: ―‹ Shuffle the parameter to the precondition, exploiting purity. › shows"prog.p2s findP_coprime ≤{⟨a⟩= getL}, Id ⊨ Id, {λrv s. rv = (LEAST i. i < length (getL s) ⟶ coprime a (getL s ! i))}" apply (rule ag.pre_pre) apply (rule ag.stable_augment_post[OF ag_findP_coprime']) apply (fastforce simp: stable_def)+ done (*<*)
end (*>*)
Messung V0.5 in Prozent
¤ 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.0.12Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-29)
¤
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.