Theory OneThirdRuleProof
theory OneThirdRuleProof
imports OneThirdRuleDefs "../Reduction" "../Majorities"
begin
text ‹
We prove that \emph{One-Third Rule} solves the Consensus problem
under the communication predicate defined above. The proof is
split into proofs of the Integrity, Agreement, and Termination
properties.
›
subsection ‹Proof of Integrity›
text ‹
Showing integrity of the algorithm is a simple, if slightly tedious
exercise in invariant reasoning. The following inductive invariant
asserts that the values of the ‹x› and ‹decide› fields
of the process states are limited to the ‹x› values present
in the initial states since the algorithm does not introduce any
new values.
›
definition VInv where
"VInv rho n ≡
let xinit = (range (x ∘ (rho 0)))
in range (x ∘ (rho n)) ⊆ xinit
∧ range (decide ∘ (rho n)) ⊆ {None} ∪ (Some ` xinit)"
lemma vinv_invariant:
assumes run:"HORun OTR_M rho HOs"
shows "VInv rho n"
proof (induct n)
from run show "VInv rho 0"
by (simp add: HORun_eq HOinitConfig_eq OTR_HOMachine_def initState_def
OTR_initState_def VInv_def image_def)
next
fix m
assume ih: "VInv rho m"
let ?xinit = "range (x ∘ (rho 0))"
have "range (x ∘ (rho (Suc m))) ⊆ ?xinit"
proof (clarsimp cong del: image_cong_simp)
fix p
from run
have nxt: "OTR_nextState m p (rho m p)
(HOrcvdMsgs OTR_M m p (HOs m p) (rho m))
(rho (Suc m) p)"
(is "OTR_nextState _ _ ?st ?msgs ?st'")
by (simp add: HORun_eq HOnextConfig_eq OTR_HOMachine_def nextState_def)
show "x ?st' ∈ ?xinit"
proof (cases "(2*N) div 3 < card (HOs m p)")
case True
hence HO: "HOs m p ≠ {}" by auto
let ?MFRs = "{v. MFR ?msgs v}"
have "Min ?MFRs ∈ ?MFRs"
proof (rule Min_in)
from HO have "?MFRs ⊆ (the ∘ ?msgs)`(HOs m p)"
by (auto simp: image_def intro: MFR_in_msgs)
thus "finite ?MFRs" by (auto elim: finite_subset)
next
from MFR_exists show "?MFRs ≠ {}" by auto
qed
with HO have "∃q ∈ HOs m p. Min ?MFRs = the (?msgs q)"
by (intro MFR_in_msgs) auto
hence "∃q ∈ HOs m p. Min ?MFRs = x (rho m q)"
by (auto simp: HOrcvdMsgs_def OTR_HOMachine_def OTR_sendMsg_def)
moreover
from True nxt have "x ?st' = Min ?MFRs"
by (simp add: OTR_nextState_def HOrcvdMsgs_def)
ultimately
show ?thesis using ih by (auto simp: VInv_def image_def)
next
case False
with nxt ih show ?thesis
by (auto simp: OTR_nextState_def VInv_def HOrcvdMsgs_def Let_def)
qed
qed
moreover
have "∀p. decide ((rho (Suc m)) p) ∈ {None} ∪ (Some ` ?xinit)"
proof
fix p
from run
have nxt: "OTR_nextState m p (rho m p)
(HOrcvdMsgs OTR_M m p (HOs m p) (rho m))
(rho (Suc m) p)"
(is "OTR_nextState _ _ ?st ?msgs ?st'")
by (simp add: HORun_eq HOnextConfig_eq OTR_HOMachine_def nextState_def)
show "decide ?st' ∈ {None} ∪ (Some ` ?xinit)"
proof (cases "(2*N) div 3 < card {q. ?msgs q ≠ None}")
assume HO: "(2*N) div 3 < card {q. ?msgs q ≠ None}"
show ?thesis
proof (cases "∃v. TwoThirds ?msgs v")
case True
let ?dec = "ϵv. TwoThirds ?msgs v"
from True have "TwoThirds ?msgs ?dec" by (rule someI_ex)
hence "HOV ?msgs ?dec ≠ {}" by (auto simp add: TwoThirds_def)
then obtain q where "x (rho m q) = ?dec"
by (auto simp: HOV_def HOrcvdMsgs_def OTR_HOMachine_def
OTR_sendMsg_def)
from sym[OF this] nxt ih show ?thesis
by (auto simp: OTR_nextState_def VInv_def image_def)
next
case False
with HO nxt ih show ?thesis
by (auto simp: OTR_nextState_def VInv_def HOrcvdMsgs_def image_def)
qed
next
case False
with nxt ih show ?thesis
by (auto simp: OTR_nextState_def VInv_def image_def)
qed
qed
hence "range (decide ∘ (rho (Suc m))) ⊆ {None} ∪ (Some ` ?xinit)" by auto
ultimately
show "VInv rho (Suc m)" by (auto simp: VInv_def image_def)
qed
text ‹
Integrity is an immediate consequence.
›
theorem OTR_integrity:
assumes run:"HORun OTR_M rho HOs" and dec: "decide (rho n p) = Some v"
shows "∃q. v = x (rho 0 q)"
proof -
let ?xinit = "range (x ∘ (rho 0))"
from run have "VInv rho n" by (rule vinv_invariant)
hence "range (decide ∘ (rho n)) ⊆ {None} ∪ (Some ` ?xinit)"
by (auto simp: VInv_def Let_def)
hence "decide ((rho n) p) ∈ {None} ∪ (Some ` ?xinit)"
by (auto simp: image_def)
with dec show ?thesis by auto
qed
subsection ‹Proof of Agreement›
text ‹
The following lemma ‹A1› asserts that if process ‹p›
decides in a round on a value ‹v› then more than $2/3$ of
all processes have ‹v› as their ‹x› value in their
local state.
We show a few simple lemmas in preparation.
›
lemma nextState_change:
assumes "HORun OTR_M rho HOs"
and "¬ ((2*N) div 3
< card {q. (HOrcvdMsgs OTR_M n p (HOs n p) (rho n)) q ≠ None})"
shows "rho (Suc n) p = rho n p"
using assms
by (auto simp: HORun_eq HOnextConfig_eq OTR_HOMachine_def
nextState_def OTR_nextState_def)
lemma nextState_decide:
assumes run:"HORun OTR_M rho HOs"
and chg: "decide (rho (Suc n) p) ≠ decide (rho n p)"
shows "TwoThirds (HOrcvdMsgs OTR_M n p (HOs n p) (rho n))
(the (decide (rho (Suc n) p)))"
proof -
from run
have "OTR_nextState n p (rho n p)
(HOrcvdMsgs OTR_M n p (HOs n p) (rho n)) (rho (Suc n) p)"
by (simp add: HORun_eq HOnextConfig_eq OTR_HOMachine_def nextState_def)
with chg show ?thesis by (auto simp: OTR_nextState_def elim: someI)
qed
lemma A1:
assumes run:"HORun OTR_M rho HOs"
and dec: "decide (rho (Suc n) p) = Some v"
and chg: "decide (rho (Suc n) p) ≠ decide (rho n p)" (is "decide ?st' ≠ decide ?st")
shows "(2*N) div 3 < card { q . x (rho n q) = v }"
proof -
from run chg
have "TwoThirds (HOrcvdMsgs OTR_M n p (HOs n p) (rho n))
(the (decide ?st'))"
(is "TwoThirds ?msgs _")
by (rule nextState_decide)
with dec have "TwoThirds ?msgs v" by simp
hence "(2*N) div 3 < card { q . ?msgs q = Some v }"
by (simp add: TwoThirds_def HOV_def)
moreover
have "{ q . ?msgs q = Some v } ⊆ { q . x (rho n q) = v }"
by (auto simp: OTR_HOMachine_def OTR_sendMsg_def HOrcvdMsgs_def)
hence "card { q . ?msgs q = Some v } ≤ card { q . x (rho n q) = v }"
by (simp add: card_mono)
ultimately
show ?thesis by simp
qed
text ‹
The following lemma ‹A2› contains the crucial correctness argument:
if more than $2/3$ of all processes send ‹v› and process ‹p›
hears from more than $2/3$ of all processes then the ‹x› field of
‹p› will be updated to ‹v›.
›
lemma A2:
assumes run: "HORun OTR_M rho HOs"
and HO: "(2*N) div 3
< card { q . HOrcvdMsgs OTR_M n p (HOs n p) (rho n) q ≠ None }"
and maj: "(2*N) div 3 < card { q . x (rho n q) = v }"
shows "x (rho (Suc n) p) = v"
proof -
from run
have nxt: "OTR_nextState n p (rho n p)
(HOrcvdMsgs OTR_M n p (HOs n p) (rho n))
(rho (Suc n) p)"
(is "OTR_nextState _ _ ?st ?msgs ?st'")
by (simp add: HORun_eq HOnextConfig_eq OTR_HOMachine_def nextState_def)
let ?HOVothers = "⋃ { HOV ?msgs w | w . w ≠ v}"
have w: "card ?HOVothers ≤ N div 3"
proof -
have "card ?HOVothers ≤ card (UNIV - { q . x (rho n q) = v })"
by (auto simp: HOV_def HOrcvdMsgs_def OTR_HOMachine_def OTR_sendMsg_def
intro: card_mono)
also have "… = N - card { q . x (rho n q) = v }"
by (auto simp: card_Diff_subset)
also from maj have "… ≤ N div 3" by auto
finally show ?thesis .
qed
have hov: "HOV ?msgs v = { q . ?msgs q ≠ None } - ?HOVothers"
by (auto simp: HOV_def) blast
have othHO: "?HOVothers ⊆ { q . ?msgs q ≠ None }"
by (auto simp: HOV_def)
txt ‹Show that ‹v› has been received from more than $N/3$ processes.›
from HO have "N div 3 < card { q . ?msgs q ≠ None } - (N div 3)"
by auto
also from w HO have "… ≤ card { q . ?msgs q ≠ None } - card ?HOVothers"
by auto
also from hov othHO have "… = card (HOV ?msgs v)"
by (auto simp: card_Diff_subset)
finally have HOV: "N div 3 < card (HOV ?msgs v)" .
txt ‹All other values are received from at most $N/3$ processes.›
have "∀w. w ≠ v ⟶ card (HOV ?msgs w) ≤ card ?HOVothers"
by (force intro: card_mono)
with w have cardw: "∀w. w ≠ v ⟶ card (HOV ?msgs w) ≤ N div 3" by auto
txt ‹In particular, ‹v› is the single most frequently received value.›
with HOV have "MFR ?msgs v" by (auto simp: MFR_def)
moreover
have "∀w. w ≠ v ⟶ ¬(MFR ?msgs w)"
proof (auto simp: MFR_def not_le)
fix w
assume "w ≠ v"
with cardw HOV have "card (HOV ?msgs w) < card (HOV ?msgs v)" by auto
thus "∃v. card (HOV ?msgs w) < card (HOV ?msgs v)" ..
qed
ultimately
have mfrv: "{ w . MFR ?msgs w } = {v}" by auto
have "card { q . ?msgs q = Some v } ≤ card { q . ?msgs q ≠ None }"
by (auto intro: card_mono)
with HO mfrv nxt show ?thesis by (auto simp: OTR_nextState_def)
qed
text ‹
Therefore, once more than two thirds of the processes hold ‹v›
in their ‹x› field, this will remain true forever.
›
lemma A3:
assumes run:"HORun OTR_M rho HOs"
and n: "(2*N) div 3 < card { q . x (rho n q) = v }" (is "?twothird n")
shows "?twothird (n+k)"
proof (induct k)
from n show "?twothird (n+0)" by simp
next
fix m
assume m: "?twothird (n+m)"
have "∀q. x (rho (n+m) q) = v ⟶ x (rho (n + Suc m) q) = v"
proof (rule+)
fix q
assume q: "x ((rho (n+m)) q) = v"
let ?msgs = "HOrcvdMsgs OTR_M (n+m) q (HOs (n+m) q) (rho (n+m))"
show "x (rho (n + Suc m) q) = v"
proof (cases "(2*N) div 3 < card { q . ?msgs q ≠ None }")
case True
from m have "(2*N) div 3 < card { q . x (rho (n+m) q) = v }" by simp
with True run show ?thesis by (auto elim: A2)
next
case False
with run q show ?thesis by (auto dest: nextState_change)
qed
qed
hence "card {q. x (rho (n+m) q) = v} ≤ card {q. x (rho (n + Suc m) q) = v}"
by (auto intro: card_mono)
with m show "?twothird (n + Suc m)" by simp
qed
text ‹
It now follows that once a process has decided on some value ‹v›,
more than two thirds of all processes continue to hold ‹v› in
their ‹x› field.
›
lemma A4:
assumes run: "HORun OTR_M rho HOs"
and dec: "decide (rho n p) = Some v" (is "?dec n")
shows "∀k. (2*N) div 3 < card { q . x (rho (n+k) q) = v }"
(is "∀k. ?twothird (n+k)")
using dec proof (induct n)
assume "?dec 0" with run show "∀k. ?twothird (0+k)"
by (simp add: HORun_eq HOinitConfig_eq OTR_HOMachine_def
initState_def OTR_initState_def)
next
fix m
assume ih: "?dec m ⟹ ∀k. ?twothird (m+k)" and m: "?dec (Suc m)"
show "∀k. ?twothird ((Suc m) + k)"
proof
fix k
have "?twothird (m + Suc k)"
txt ‹
There are two cases to consider: if ‹p› had already decided on ‹v›
before, the assertion follows from the induction hypothesis. Otherwise, the
assertion follows from lemmas ‹A1› and ‹A3›.
›
proof (cases "?dec m")
case True with ih show ?thesis by blast
next
case False
with run m have "?twothird m" by (auto elim: A1)
with run show ?thesis by (blast dest: A3)
qed
thus "?twothird ((Suc m) + k)" by simp
qed
qed
text ‹
The Agreement property follows easily from lemma ‹A4›: if processes
‹p› and ‹q› decide values ‹v› and ‹w›,
respectively, then more than two thirds of the processes must propose
‹v› and more than two thirds must propose ‹w›.
Because these two majorities must have an intersection, we must have
‹v=w›.
We first prove an ``asymmetric'' version of the agreement property before
deriving the general agreement theorem.
›
lemma A5:
assumes run:"HORun OTR_M rho HOs"
and p: "decide (rho n p) = Some v"
and p': "decide (rho (n+k) p') = Some w"
shows "v = w"
proof -
from run p
have "(2*N) div 3 < card {q. x (rho (n+k) q) = v}" (is "_ < card ?V")
by (blast dest: A4)
moreover
from run p'
have "(2*N) div 3 < card {q. x (rho ((n+k)+0) q) = w}" (is "_ < card ?W")
by (blast dest: A4)
ultimately
have "N < card ?V + card ?W" by auto
then obtain proc where "proc ∈ ?V ∩ ?W" by (auto dest: majorities_intersect)
thus ?thesis by auto
qed
theorem OTR_agreement:
assumes run:"HORun OTR_M rho HOs"
and p: "decide (rho n p) = Some v"
and p': "decide (rho m p') = Some w"
shows "v = w"
proof (cases "n ≤ m")
case True
then obtain k where "m = n+k" by (auto simp add: le_iff_add)
with run p p' show ?thesis by (auto elim: A5)
next
case False
hence "m ≤ n" by auto
then obtain k where "n = m+k" by (auto simp add: le_iff_add)
with run p p' have "w = v" by (auto elim: A5)
thus ?thesis ..
qed
subsection ‹Proof of Termination›
text ‹
We now show that every process must eventually decide.
The idea of the proof is to observe that the communication predicate
guarantees the existence of two uniform rounds where every process hears
from the same two-thirds majority of processes. The first such round
serves to ensure that all ‹x› fields hold the same value, the
second round copies that value into all decision fields.
Lemma ‹A2› is instrumental in this proof.
›
theorem OTR_termination:
assumes run: "HORun OTR_M rho HOs"
and commG: "HOcommGlobal OTR_M HOs"
shows "∃r v. decide (rho r p) = Some v"
proof -
from commG obtain r0 Π where
pi: "∀q. HOs r0 q = Π" and pic: "card Π > (2*N) div 3"
by (auto simp: OTR_HOMachine_def OTR_commGlobal_def)
let "?msgs q r" = "HOrcvdMsgs OTR_M r q (HOs r q) (rho r)"
from run pi have "∀p q. ?msgs q r0 = ?msgs p r0"
by (auto simp: HORun_eq OTR_HOMachine_def HOrcvdMsgs_def OTR_sendMsg_def)
then obtain μ where "∀q. ?msgs q r0 = μ" by auto
moreover
from pi pic have "∀p. (2*N) div 3 < card {q. ?msgs p r0 q ≠ None}"
by (auto simp: HORun_eq HOnextConfig_eq HOrcvdMsgs_def)
with run have "∀q. x (rho (Suc r0) q) = Min {v . MFR (?msgs q r0) v}"
by (auto simp: HORun_eq HOnextConfig_eq OTR_HOMachine_def
nextState_def OTR_nextState_def)
ultimately
have "∀q. x (rho (Suc r0) q) = Min {v . MFR μ v}" by auto
then obtain v where v:"∀q. x (rho (Suc r0) q) = v" by auto
have P:"∀k. ∀q. x (rho (Suc r0+k) q) = v"
proof
fix k
show "∀q. x (rho (Suc r0+k) q) = v"
proof (induct k)
from v show "∀q. x (rho (Suc r0+0) q) = v" by simp
next
fix k
assume ih:"∀q. x (rho (Suc r0 + k) q) = v"
show "∀q. x (rho (Suc r0 + Suc k) q) = v"
proof
fix q
show "x (rho (Suc r0 + Suc k) q) = v"
proof (cases "(2*N) div 3 < card { p . ?msgs q (Suc r0 + k) p ≠ None }")
case True
have "N > 0" by (rule finite_UNIV_card_ge_0) simp
with ih
have "(2*N) div 3 < card { p . x (rho (Suc r0 + k) p) = v }" by auto
with True run show ?thesis by (auto elim: A2)
next
case False
with run ih show ?thesis by (auto dest: nextState_change)
qed
qed
qed
qed
from commG obtain r0' Π'
where r0': "r0' ≥ Suc r0"
and pi': "∀q. HOs r0' q = Π'"
and pic': "card Π' > (2*N) div 3"
by (force simp: OTR_HOMachine_def OTR_commGlobal_def)
from r0' P have v':"∀q. x (rho r0' q) = v" by (auto simp: le_iff_add)
from run
have "OTR_nextState r0' p (rho r0' p) (?msgs p r0') (rho (Suc r0') p)"
by (simp add: HORun_eq HOnextConfig_eq OTR_HOMachine_def nextState_def)
moreover
from pi' pic' have "(2*N) div 3 < card {q. (?msgs p r0') q ≠ None}"
by (auto simp: HOrcvdMsgs_def OTR_sendMsg_def)
moreover
from pi' pic' v' have "TwoThirds (?msgs p r0') v"
by (simp add: TwoThirds_def HOrcvdMsgs_def OTR_HOMachine_def
OTR_sendMsg_def HOV_def)
ultimately
have "decide (rho (Suc r0') p) = Some (ϵv. TwoThirds (?msgs p r0') v)"
by (auto simp: OTR_nextState_def)
thus ?thesis by blast
qed
subsection ‹\emph{One-Third Rule} Solves Consensus›
text ‹
Summing up, all (coarse-grained) runs of \emph{One-Third Rule} for
HO collections that satisfy the communication predicate satisfy
the Consensus property.
›
theorem OTR_consensus:
assumes run: "HORun OTR_M rho HOs" and commG: "HOcommGlobal OTR_M HOs"
shows "consensus (x ∘ (rho 0)) decide rho"
using OTR_integrity[OF run] OTR_agreement[OF run] OTR_termination[OF run commG]
by (auto simp: consensus_def image_def)
text ‹
By the reduction theorem, the correctness of the algorithm also follows
for fine-grained runs of the algorithm. It would be much more tedious
to establish this theorem directly.
›
theorem OTR_consensus_fg:
assumes run: "fg_run OTR_M rho HOs HOs (λr q. undefined)"
and commG: "HOcommGlobal OTR_M HOs"
shows "consensus (λp. x (state (rho 0) p)) decide (state ∘ rho)"
(is "consensus ?inits _ _")
proof (rule local_property_reduction[OF run consensus_is_local])
fix crun
assume crun: "CSHORun OTR_M crun HOs HOs (λr q. undefined)"
and init: "crun 0 = state (rho 0)"
from crun have "HORun OTR_M crun HOs" by (unfold HORun_def SHORun_def)
from this commG have "consensus (x ∘ (crun 0)) decide crun" by (rule OTR_consensus)
with init show "consensus ?inits decide crun" by (simp add: o_def)
qed
end