# Theory Three_Step_MRU

```section ‹Three-step Optimized MRU Model›
theory Three_Step_MRU
imports "../MRU_Vote_Opt" Three_Steps
begin

text ‹To make the coming proofs of concrete algorithms easier, in this model we split
the @{term opt_mru_round} into three steps›

subsection ‹Model definition›
(******************************************************************************)
record three_step_mru_state = opt_mru_state +
candidates :: "val set"

context mono_quorum
begin

definition opt_mru_step0 :: "round ⇒ val set ⇒  (three_step_mru_state × three_step_mru_state) set" where
"opt_mru_step0 r C = {(s, s').
― ‹guards›
r = next_round s ∧ three_step r = 0
∧ (∀cand ∈ C. ∃Q. opt_mru_guard (mru_vote s) Q cand)
∧ ― ‹actions›
s' = s⦇
candidates := C
, next_round := Suc r
⦈
}"

definition opt_mru_step1 :: "round ⇒ process set ⇒ val ⇒
(three_step_mru_state × three_step_mru_state) set" where
"opt_mru_step1 r S v = {(s, s').
― ‹guards›
r = next_round s ∧ three_step r = 1
∧ (S ≠ {} ⟶ v ∈ candidates s)
∧ ― ‹actions›
s' = s⦇
mru_vote := mru_vote s ++ const_map (three_phase r, v) S
, next_round := Suc r
⦈
}"

definition step2_d_guard :: "(process, val)map ⇒ (process, val)map ⇒ bool" where
"step2_d_guard r_decisions r_votes ≡ ∀p v. r_decisions p = Some v ⟶

definition r_votes :: "three_step_mru_state ⇒ round ⇒ (process, val)map" where
"r_votes s r ≡ λp. if (∃v. mru_vote s p = Some (three_phase r, v))
then map_option snd (mru_vote s p)
else None"

definition opt_mru_step2 :: "round ⇒ (process, val)map ⇒ (three_step_mru_state × three_step_mru_state) set" where
"opt_mru_step2 r r_decisions = {(s, s').
― ‹guards›
r = next_round s ∧ three_step r = 2
∧ step2_d_guard r_decisions  (r_votes s r)
∧ ― ‹actions›
s' = s⦇
next_round := Suc r
, decisions := decisions s ++ r_decisions
⦈
}"

lemmas ts_mru_evt_defs = opt_mru_step0_def opt_mru_step1_def opt_mru_guard_def

definition ts_mru_trans :: "(three_step_mru_state × three_step_mru_state) set" where
"ts_mru_trans = (⋃r C. opt_mru_step0 r C)
∪ (⋃r S v. opt_mru_step1 r S v)
∪ (⋃r dec_f. opt_mru_step2 r dec_f) ∪ Id"

definition ts_mru_init where
"ts_mru_init = { ⦇ next_round = 0, mru_vote = Map.empty, decisions = Map.empty, candidates = {} ⦈ }"

definition ts_mru_TS :: "three_step_mru_state TS" where
"ts_mru_TS = ⦇ init = ts_mru_init, trans = ts_mru_trans ⦈"

lemmas ts_mru_TS_defs = ts_mru_TS_def ts_mru_init_def ts_mru_trans_def

subsection ‹Refinement›
(******************************************************************************)

definition basic_rel where
"basic_rel ≡ {(sa, sc).
decisions sc = decisions sa
∧ next_round sa = three_phase (next_round sc)
}"

definition three_step0_rel :: "(opt_mru_state × three_step_mru_state)set" where
"three_step0_rel ≡ basic_rel ∩ {(sa, sc).
three_step (next_round sc) = 0
∧ mru_vote sc = mru_vote sa
}"

definition three_step1_rel :: "(opt_mru_state × three_step_mru_state)set"  where
"three_step1_rel ≡ basic_rel ∩ {(sa, sc).
(∃sc' r C. (sa, sc') ∈ three_step0_rel ∧ (sc', sc) ∈ opt_mru_step0 r C)
∧ mru_vote sc = mru_vote sa
}"

definition three_step2_rel :: "(opt_mru_state × three_step_mru_state)set"  where
"three_step2_rel ≡ basic_rel ∩ {(sa, sc).
(∃sc' r S v. (sa, sc') ∈ three_step1_rel ∧ (sc', sc) ∈ opt_mru_step1 r S v)
}"

definition ts_ref_rel where
"ts_ref_rel = {(sa, sc).
(three_step (next_round sc) = 0 ⟶ (sa, sc) ∈ three_step0_rel)
∧ (three_step (next_round sc) = 1 ⟶ (sa, sc) ∈ three_step1_rel)
∧ (three_step (next_round sc) = 2 ⟶ (sa, sc) ∈ three_step2_rel)
}"

lemmas ts_ref_rel_defs =
basic_rel_def
ts_ref_rel_def
three_step0_rel_def
three_step1_rel_def
three_step2_rel_def

lemma step0_ref:
"{ts_ref_rel} Id, opt_mru_step0 r C {> ts_ref_rel}"
proof(simp only: PO_rhoare_defs, safe)
fix sa sc sc'
assume R: "(sa, sc) ∈ ts_ref_rel" and step: "(sc, sc') ∈ opt_mru_step0 r C"
hence r_step: "three_step (next_round sc) = 0" "three_step (next_round sc') = 1"
by(auto simp add: ts_ref_rel_def opt_mru_step0_def three_step_Suc)
hence "(sa, sc') ∈ ts_ref_rel" using R step
apply(auto simp add: ts_ref_rel_def  three_step_phase_Suc three_step1_rel_def
three_step2_rel_def intro!: exI[where x=sc] step R)
apply(auto simp add: three_step0_rel_def basic_rel_def three_step_phase_Suc
opt_mru_step0_def)
done
thus "∃sa'. (sa, sa') ∈ Id ∧ (sa', sc') ∈ ts_ref_rel"
by blast
qed

lemma step1_ref:
"{ts_ref_rel} Id, opt_mru_step1 r S v {> ts_ref_rel}"
proof(simp only: PO_rhoare_defs, safe)
fix sa sc sc'
assume R: "(sa, sc) ∈ ts_ref_rel" and step: "(sc, sc') ∈ opt_mru_step1 r S v"
hence r_step: "three_step (next_round sc) = 1" "three_step (next_round sc') = 2"
by(auto simp add: ts_ref_rel_def opt_mru_step1_def three_step_Suc)
hence "(sa, sc') ∈ ts_ref_rel" using R step
apply(auto simp add: ts_ref_rel_def  three_step_phase_Suc three_step0_rel_def
three_step2_rel_def intro!: exI[where x=sc] step R)
apply(auto simp add: three_step1_rel_def basic_rel_def three_step_phase_Suc
opt_mru_step1_def)
done
thus "∃sa'. (sa, sa') ∈ Id ∧ (sa', sc') ∈ ts_ref_rel"
by blast
qed

lemma step2_ref:
"{ts_ref_rel ∩ OMRU_inv1 × UNIV}
⋃r' Q S' v dec_f'. opt_mru_round r' Q S' v dec_f',
opt_mru_step2 r dec_f {> ts_ref_rel}"
proof(auto simp only: PO_rhoare_defs)
fix sa sc2 sc3
assume
ainv: "sa ∈ OMRU_inv1"
and R: "(sa, sc2) ∈ ts_ref_rel"
and step2: "(sc2, sc3) ∈ opt_mru_step2 r dec_f"

from R step2 obtain sc0 r0 C sc1 r1 S v where
R0: "(sa, sc0) ∈ three_step0_rel" and step0: "(sc0, sc1) ∈ opt_mru_step0 r0 C"
and R1: "(sa, sc1) ∈ three_step1_rel" and step1: "(sc1, sc2) ∈ opt_mru_step1 r1 S v"
by(fastforce simp add: ts_ref_rel_def three_step2_rel_def opt_mru_step2_def
three_step1_rel_def)

have R2: "(sa, sc2) ∈ three_step2_rel"
and r2_step: "three_step (next_round sc2) = Suc (Suc 0)"
and r3_step: "three_step (next_round sc3) = 0"
using R step2
by(auto simp add: ts_ref_rel_def opt_mru_step2_def three_step_phase_Suc three_step_Suc)

have r: "r = Suc r1" and r1: "r1 = Suc r0" "r1 = next_round sc1" and
r0: "r0 = next_round sc0" and r0_step: "three_step r0 = 0" and
r2: "r = next_round sc2"
using step0 step1 step2
by(auto simp add: opt_mru_step0_def opt_mru_step1_def opt_mru_step2_def)

have abs_round2: "next_round sa = three_phase r" using R2 r2
have abs_round1: "next_round sa = three_phase r1" using R1 r1
have abs_round0: "next_round sa = three_phase r0" using R0 r0 r
by(auto simp add: three_step0_rel_def basic_rel_def three_step_phase_Suc)

proof(rule ext)
fix p
show "r_votes sc2 r p = const_map v S p"
case None
thus ?thesis using step0 step1 abs_round0 abs_round1 abs_round2
next
case (Some w)
hence in_S: "mru_vote sc1 p ≠ mru_vote sc2 p" using R0 step0 ainv r1 r abs_round0
three_step_phase_Suc opt_mru_step0_def dest: OMRU_inv1D[where p=p])
hence "p ∈ S"  using step1
split: option.split_asm)
moreover have "w=v" using R0 R1 step1 ainv r abs_round1 Some
three_step_phase_Suc opt_mru_step1_def dest: OMRU_inv1D[where p=p])
ultimately show ?thesis using Some
qed
qed

from step0 step1 obtain Q where Q: "S ≠ {} ⟶ opt_mru_guard (mru_vote sc0) Q v"

define sa' where "sa' = sa⦇
mru_vote := mru_vote sa ++ const_map (three_phase r, v) S
, next_round := Suc (three_phase r)
, decisions := decisions sa ++ dec_f
⦈"

have guard_strengthening:
"step2_d_guard dec_f (r_votes sc2 r) ⟶ d_guard dec_f (const_map v S)"
quorum_for_def const_map_is_Some dom_const_map)
have "(sa, sa') ∈ opt_mru_round (three_phase r) Q S v dec_f ∧ (sa', sc3) ∈ ts_ref_rel"
proof
show "(sa', sc3) ∈ ts_ref_rel" using r3_step R0 R1 R2 step0 step1 step2
by(auto simp add: ts_ref_rel_def three_step0_rel_def basic_rel_def opt_mru_step0_def
opt_mru_step1_def opt_mru_step2_def  sa'_def three_step_phase_Suc)
next
show "(sa, sa') ∈ opt_mru_round (three_phase r) Q S v dec_f"
using R0 r0_step step0 step1 step2 r0 r1 r2 r r_votes Q guard_strengthening
by(auto simp add: ts_ref_rel_defs opt_mru_round_def three_step_phase_Suc
opt_mru_step0_def opt_mru_step1_def opt_mru_step2_def sa'_def)
qed
thus "∃y. (sa, y) ∈ (⋃r' Q S' v D'. opt_mru_round r' Q S' v D') ∧ (y, sc3) ∈ ts_ref_rel"
by simp blast
qed

lemma ThreeStep_Coordinated_Refines:
"PO_refines (ts_ref_rel ∩ OMRU_inv1 × UNIV)
mru_opt_TS ts_mru_TS"
proof(rule refine_using_invariants)
show "init ts_mru_TS ⊆ ts_ref_rel `` init mru_opt_TS"
by(auto simp add: ts_mru_TS_defs mru_opt_TS_defs ts_ref_rel_def three_step0_rel_def
three_step1_rel_def three_step2_rel_def basic_rel_def)
next
show
"{ts_ref_rel ∩ OMRU_inv1 × UNIV} TS.trans mru_opt_TS,
TS.trans (ts_mru_TS) {> ts_ref_rel}"