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)
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.