text‹ \file{AsynchronousSystem} defines a message datatype and a transition system locale to
model asynchronous distributed computation. It establishes a diamond property for a
special reachability relation within such transition systems. ›
theory AsynchronousSystem imports Multiset begin
text‹
The formalization is type-parameterized over \begin{description} \item[\var{'p} process identifiers.] Corresponds to the set $P$ in Völzer.
Finiteness is not yet demanded, but will be in \file{FLPSystem}. \item[\var{'s} process states.] Corresponds to $S$, countability is not
imposed. \item[\var{'v} message payloads.] Corresponds to the interprocess
communication part of $M$ from Völzer. The whole of $M$ is captured by \isb{messageValue}. \end{description} ›
subsection‹Messages›
text‹
A \isb{message} is either an initial input message telling a process
which value it should introduce to the consensus negotiation, a message
to the environment communicating the consensus outcome, or a message
passed from one process to some other. ›
lemma UniqueReceiverOf: fixes
msg :: "('p, 'v) message"and
p q :: 'p assumes "isReceiverOf q msg" "p ≠ q" shows "¬ isReceiverOf p msg" using assms by (cases msg, auto)
subsection‹Configurations›
text‹
Here we formalize a configuration as detailed in section 2 of Völzer's paper.
Note that Völzer imposes the finiteness of the message multiset by
definition while we do not do so. In \isb{FiniteMessages}
We prove the finiteness to follow from the assumption that only
finitely many messages can be sent at once. ›
record ('p, 'v, 's) configuration = states :: "'p ==> 's"
msgs :: "(('p, 'v) message) multiset"
text‹
C.f. Völzer: \textquote{A step is identified with a message $(p, m)$. A step $(p, m)$ is enabled
in a configuration c if $\var{msgs}_c$ contains the message $(p, m)$.} ›
text‹
The locale describing a system is derived by slight refactoring from the
following passage of Völzer: \begin{displayquote}
A process $p$ consists of an initial state $s_p \in S$ and a step transition
function, which assigns to each pair $(m, s)$ of a message value $m$ and
a process state $s$ a follower state and a finite set of messages (the
messages to be sent by $p$ in a step). \end{displayquote} ›
text‹
The step relation is defined analogously to Völzer: \begin{displayquote}
{[}If enabled, a step may{]} occur, resulting in a follower
configuration $c^\prime$, where $c^\prime$ is obtained from $c$ by removing
$(p, m)$ from $\var{msgs}_c$, changing $p$'s state and adding the set of
messages to $\var{msgs}_c$ according to the step transition function
associated with $p$. We denote this by $c \xrightarrow{p,m} c^\prime$. \end{displayquote}
There are no steps consuming output messages. ›
primrec steps :: "('p, 'v, 's) configuration ==> ('p, 'v) message ==> ('p, 'v, 's) configuration ==> bool"
(‹_ ⊨ _ ↦ _› [70,70,70]) where
StepInMsg: "cfg1 ⊨ <p, inM v> ↦ cfg2 = ( (∀ s. ((s = p) ⟶ states cfg2 p = trans p (states cfg1 p) (Bool v)) ∧ ((s ≠ p) ⟶ states cfg2 s = states cfg1 s)) ∧ enabled cfg1 <p, inM v> ∧ msgs cfg2 = (sends p (states cfg1 p) (Bool v) ∪# (msgs cfg1 -# <p, inM v>)))"
| StepMsg: "cfg1 ⊨ <p, v> ↦ cfg2 = ( (∀ s. ((s = p) ⟶ states cfg2 p = trans p (states cfg1 p) (Value v)) ∧ ((s ≠ p) ⟶ states cfg2 s = states cfg1 s)) ∧ enabled cfg1 <p, v> ∧ msgs cfg2 = (sends p (states cfg1 p) (Value v) ∪# (msgs cfg1 -# <p, v>)))"
| StepOutMsg: "cfg1 ⊨ <⊥,outM v> ↦ cfg2 = False"
text‹
The system is distributed and asynchronous in the sense that the processing
of messages only affects the process the message is directed to while the
rest stays unchanged. › lemma NoReceivingNoChange: fixes
cfg1 cfg2 :: "('p,'v,'s) configuration"and
m :: "('p,'v) message"and
p :: 'p assumes
Step: "cfg1 ⊨ m ↦ cfg2"and
Rec: "¬ isReceiverOf p m" shows "states cfg1 p = states cfg2 p " proof(cases m) case (OutMsg b') thus ?thesis using Step by auto next case (InMsg q b') assume CaseM: "m = <q, inM b'>" with assms have"p ≠ q"by simp with Step CaseM show ?thesis by simp next case (Msg q v') assume CaseM: "m = <q, v'>" with assms have"p ≠ q"by simp with Step CaseM show ?thesis by simp qed
lemma ExistsMsg: fixes
cfg1 cfg2 :: "('p,'v,'s) configuration"and
m :: "('p,'v) message" assumes
Step: "cfg1 ⊨ m ↦ cfg2" shows "m ∈# (msgs cfg1)" using assms enabled_def by (cases m, auto)
lemma NoMessageLossStep: fixes
cfg1 :: "('p,'v,'s) configuration"and
cfg2 :: "('p,'v,'s) configuration"and
p :: 'p and
m :: "('p,'v) message"and
m' :: "('p,'v) message" assumes
Step: "cfg1 ⊨ m ↦ cfg2"and
Rec1: "isReceiverOf p m"and
Rec2: "¬isReceiverOf p m'" shows "msgs cfg1 m' ≤ msgs cfg2 m'" using assms by (induct m, simp_all, auto)
lemma OutOnlyGrowing: fixes
cfg1 cfg2 :: "('p,'v,'s) configuration"and
b::bool and
m::"('p, 'v) message"and
p::'p assumes "cfg1 ⊨ m ↦ cfg2" "isReceiverOf p m" shows "msgs cfg2 <⊥, outM b> = (msgs cfg1 <⊥, outM b>) + sends p (states cfg1 p) (unpackMessage m) <⊥, outM b>" proof(-) have"m = <⊥, outM b> ==> False"using assms proof(auto) qed hence MNotOut: "m ≠ <⊥, outM b>"by auto have MsgFunction: "msgs cfg2 = ((sends p (states cfg1 p) (unpackMessage m)) ∪# ((msgs cfg1) -# m))" proof(cases m) case (InMsg pa bool) thenhave PaIsP: "pa = p""(unpackMessage m) = Bool bool" using isReceiverOf_def assms(2) by (auto simp add: UniqueReceiverOf) hence"cfg1 ⊨ <p, inM bool> ↦ cfg2"using assms(1) InMsg by simp hence"msgs cfg2 = (sends p (states cfg1 p) (Bool bool) ∪# (msgs cfg1 -# <p, inM bool>))" by simp hence"msgs cfg2 = (sends p (states cfg1 p) (Bool bool) ∪# (msgs cfg1 -# m))" using PaIsP(1) InMsg by simp thus ?thesis using StepInMsg assms PaIsP by simp nextcase (OutMsg b) hence False using assms by auto thus ?thesis by simp nextcase (Msg pa va) hence PaIsP: "pa = p""(unpackMessage m) = Value va" using isReceiverOf_def assms(2) by (auto simp add: UniqueReceiverOf) hence"cfg1 ⊨ <p, va> ↦ cfg2"using assms(1) Msg by simp hence"msgs cfg2 = (sends p (states cfg1 p) (Value va) ∪# (msgs cfg1 -# <p, va>))"by simp hence"msgs cfg2 = (sends p (states cfg1 p) (Value va) ∪# (msgs cfg1 -# m))" using PaIsP(1) Msg by simp thus ?thesis using StepInMsg assms PaIsP by simp qed have"((sends p (states cfg1 p) (unpackMessage m)) ∪# ((msgs cfg1) -# m)) <⊥, outM b> = ((sends p (states cfg1 p) (unpackMessage m)) ∪# (msgs cfg1)) <⊥, outM b>" using MNotOut by auto thus"msgs cfg2 <⊥, outM b> = (msgs cfg1 <⊥, outM b>) + sends p (states cfg1 p) (unpackMessage m) <⊥, outM b>" using MsgFunction by simp qed
lemma OtherMessagesOnlyGrowing: fixes
cfg1 :: "('p,'v,'s) configuration"and
cfg2 :: "('p,'v,'s) configuration"and
p :: 'p and
m :: "('p,'v) message"and
m' :: "('p,'v) message" assumes
Step: "cfg1 ⊨ m ↦ cfg2"and "m ≠ m'" shows "msgs cfg1 m' ≤ msgs cfg2 m'" using assms by (cases m, auto)
text‹
Völzer: \textquote{Note that steps are enabled persistently, i.e., an
enabled step remains enabled as long as it does not occur.} › lemma OnlyOccurenceDisables: fixes
cfg1 :: "('p,'v,'s) configuration"and
cfg2 :: "('p,'v,'s) configuration"and
p :: 'p and
m :: "('p,'v) message"and
m' :: "('p,'v) message" assumes
Step: "cfg1 ⊨ m ↦ cfg2"and
En: "enabled cfg1 m'"and
NotEn: "¬ (enabled cfg2 m')" shows "m = m'" using assms proof (cases m) print_cases case (InMsg p bool) with Step have"msgs cfg2 = (sends p (states cfg1 p) (Bool bool) ∪# (msgs cfg1 -# <p, inM bool>))"by auto thus"m = m'"using InMsg En NotEn by (auto simp add: enabled_def, metis less_nat_zero_code) next case (OutMsg bool) with Step show"m = m'"by auto next case (Msg p v) with Step have"msgs cfg2 = (sends p (states cfg1 p) (Value v) ∪# (msgs cfg1 -# <p, v>))"by auto thus"m = m'"using Msg En NotEn by (auto simp add: enabled_def, metis less_nat_zero_code) qed
subsection‹Reachability with special process activity›
text‹
We say that \isb{qReachable cfg1 Q cfg2} iff cfg2 is reachable from cfg1
only by activity of processes from Q. › inductive qReachable :: "('p,'v,'s) configuration ==> 'p set ==> ('p,'v,'s) configuration ==> bool" where
InitQ: "qReachable cfg1 Q cfg1"
| StepQ: "[ qReachable cfg1 Q cfg2; (cfg2 ⊨ msg ↦ cfg3) ; ∃ p ∈ Q . isReceiverOf p msg ] ==> qReachable cfg1 Q cfg3"
text‹
We say that \isb{withoutQReachable cfg1 Q cfg2} iff cfg2 is reachable from cfg1
with no activity of processes from Q. › abbreviation withoutQReachable :: "('p,'v,'s) configuration ==> 'p set ==> ('p,'v,'s) configuration ==> bool" where "withoutQReachable cfg1 Q cfg2 ≡ qReachable cfg1 ((UNIV :: 'p set ) - Q) cfg2"
text‹
Obviously q-reachability (and thus also without-q-reachability) implies
reachability. › lemma QReachImplReach: fixes
cfg1 cfg2:: "('p, 'v, 's ) configuration"and
Q :: " 'p set" assumes "qReachable cfg1 Q cfg2" shows "reachable cfg1 cfg2" using assms proof (induct rule: qReachable.induct) case InitQ thus ?caseusing reachable.simps by blast next case StepQ thus ?caseusing reachable.step by simp 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.