Theory DiskPaxos

(*  Title:       Proving the Correctness of Disk Paxos

    Author:      Mauro J. Jaskelioff, Stephan Merz, 2005
    Maintainer:  Mauro J. Jaskelioff <mauro at fceia.unr.edu.ar>
*)

theory DiskPaxos imports DiskPaxos_Invariant begin

subsection ‹Inner Module›

record
Istate =
  iinput :: "Proc  InputsOrNi"
  ioutput :: "Proc  InputsOrNi"
  ichosen :: InputsOrNi
  iallInput :: "InputsOrNi set"

definition IInit :: "Istate  bool"
where
  "IInit s =  (range (iinput s)  Inputs
              ioutput s = (λp. NotAnInput)
              ichosen s = NotAnInput
              iallInput s = range (iinput s))"

definition IChoose :: "Istate  Istate  Proc  bool"
where
  "IChoose s s' p = (ioutput s p = NotAnInput
                    (if (ichosen s = NotAnInput)
                        then (ip  iallInput s.  ichosen s' = ip
                                             ioutput s' = (ioutput s) (p := ip))
                        else (  ioutput s' = (ioutput s) (p:= ichosen s)
                                ichosen s' = ichosen s))
                     iinput s' = iinput s  iallInput s'= iallInput s)"

definition IFail :: "Istate  Istate  Proc  bool"
where
  "IFail s s' p =   (ioutput s' = (ioutput s) (p:= NotAnInput)
                   (ip  Inputs.  iinput s' = (iinput s)(p:= ip)
                                    iallInput s' = iallInput s  {ip})
                   ichosen s' = ichosen s)"

definition INext :: "Istate  Istate  bool"
  where "INext s s' = (p. IChoose s s' p  IFail s s' p)"

definition s2is :: "state  Istate"
where
  "s2is s = iinput = inpt s, 
             ioutput = outpt s, 
             ichosen=chosen s,
             iallInput = allInput s"

theorem R1:
  " HInit s; is = s2is s  IInit is"
  by(auto simp add: HInit_def IInit_def s2is_def Init_def)

theorem R2b:
  assumes inv: "HInv s"
  and inv': "HInv s'"
  and nxt: "HNext s s'"
  and srel: "is=s2is s  is'=s2is s'"
  shows "(p. IFail is is' p  IChoose is is' p)  is = is'"
proof(auto)
  assume chg_vars: "isis'"
  with srel
  have s_change: "   inpt s  inpt s'  outpt s  outpt s' 
                   chosen s  chosen s'  allInput s  allInput s'"
    by(auto simp add: s2is_def)
  from inv
  have inv2c5: "p.   inpt s p  allInput s 
                     (chosen s = NotAnInput  outpt s p = NotAnInput)"
    by(auto simp add: HInv_def HInv2_def Inv2c_def Inv2c_inner_def) 
  from nxt s_change inv2c5
  have "inpt s'  inpt s  outpt s'  outpt s"
    by(auto simp add: HNext_def Next_def HNextPart_def)
  with nxt
  have "p. Fail s s' p  EndPhase2 s s' p"
    by(auto simp add: HNext_def Next_def 
      StartBallot_def Phase0Read_def Phase1or2Write_def 
      Phase1or2Read_def Phase1or2ReadThen_def Phase1or2ReadElse_def 
      EndPhase1or2_def EndPhase1_def EndPhase0_def)
  then obtain p where fail_or_endphase2: "Fail s s' p  EndPhase2 s s' p"
    by auto
  from inv
  have inv2c: "Inv2c_inner s p"
    by(auto simp add: HInv_def HInv2_def Inv2c_def)
  from fail_or_endphase2 have "IFail is is' p  IChoose is is' p"
  proof
    assume fail: "Fail s s' p "
    hence phase': "phase s' p = 0"
      and  outpt: "outpt s' = (outpt s) (p:= NotAnInput)"
      by(auto simp add: Fail_def)
    have "IFail is is' p"
    proof -
      from fail srel
      have "ioutput is' = (ioutput is) (p:= NotAnInput)"
        by(auto simp add: Fail_def s2is_def)
      moreover
      from nxt 
      have all_nxt: "allInput s'= allInput s  (range (inpt s'))"
        by(auto simp add: HNext_def HNextPart_def)
      from fail srel
      have "ip  Inputs.  iinput is' = (iinput is)(p:= ip)"
        by(auto simp add: Fail_def s2is_def)
      then obtain ip where ip_Input: "ipInputs" and "iinput is' = (iinput is)(p:= ip)"
        by auto
      with inv2c5 srel all_nxt
      have "  iinput is' = (iinput is)(p:= ip)
         iallInput is' = iallInput is  {ip}"
        by(auto simp add: s2is_def)
      moreover
      from outpt srel nxt inv2c
      have "ichosen is' = ichosen is"
        by(auto simp add: HNext_def HNextPart_def s2is_def Inv2c_inner_def)
      ultimately
      show ?thesis
        using ip_Input
        by(auto simp add: IFail_def)
    qed
    thus ?thesis
      by auto
  next
    assume endphase2: "EndPhase2 s s' p"
    from endphase2
    have "phase s p =2"
      by(auto simp add: EndPhase2_def)
    with inv2c Ballot_nzero
    have bal_dblk_nzero: "bal(dblock s p) 0"
      by(auto simp add: Inv2c_inner_def)
    moreover
    from inv
    have inv2a_dblock: "Inv2a_innermost s p (dblock s p)"
      by(auto simp add: HInv_def HInv2_def Inv2a_def Inv2a_inner_def blocksOf_def)
    ultimately
    have p22: "inp (dblock s p)  allInput s"
      by(auto simp add: Inv2a_innermost_def)
    from inv
    have "allInput s  Inputs"
      by(auto simp add: HInv_def HInv1_def)
    with p22 NotAnInput endphase2
    have outpt_nni: "outpt s' p  NotAnInput"
      by(auto simp add: EndPhase2_def)
    show ?thesis
    proof(cases "chosen s = NotAnInput")
      case True
      with inv2c5
      have p31: "q. outpt s q = NotAnInput"
        by auto
      with endphase2
      have p32: "q  UNIV -{p}. outpt s' q = NotAnInput"
        by(auto simp add: EndPhase2_def)
      hence some_eq: "(x. outpt s' x  NotAnInput  x = p)"
        by auto
      from p32 True nxt some_equality[of "λp. outpt s' p  NotAnInput", OF outpt_nni some_eq]
      have p33: "chosen s' = outpt s' p"
        by(auto simp add: HNext_def HNextPart_def)
      with endphase2
      have "chosen s' = inp(dblock s p)  outpt s' = (outpt s)(p:=inp(dblock s p))"
        by(auto simp add: EndPhase2_def)
      with True p22 
      have "if (chosen s = NotAnInput)
                        then (ip  allInput s.  chosen s' = ip
                                             outpt s' = (outpt s) (p := ip))
                        else (  outpt s' = (outpt s) (p:= chosen s)
                                chosen s' = chosen s)"
        by auto
      moreover
      from endphase2 inv2c5 nxt
      have "inpt s' = inpt s  allInput s'= allInput s"
        by(auto simp add: EndPhase2_def HNext_def HNextPart_def)
      ultimately
      show ?thesis
        using srel p31
        by(auto simp add: IChoose_def s2is_def)
    next
      case False
      with nxt
      have p31: "chosen s' = chosen s"
        by(auto simp add: HNext_def HNextPart_def)
      from inv'
      have inv6: "HInv6 s'"
        by(auto simp add: HInv_def)
      have p32: "outpt s' p = chosen s"
      proof-
        from endphase2
        have "outpt s' p  = inp(dblock s p)"
          by(auto simp add: EndPhase2_def)
        moreover
        from inv6 p31
        have "outpt s' p  {chosen s, NotAnInput}"
          by(auto simp add: HInv6_def)
        ultimately
        show ?thesis
          using outpt_nni
          by auto
      qed
      from srel False
      have "IChoose is is' p"
      proof(clarsimp simp add: IChoose_def s2is_def)
        from endphase2 inv2c
        have "outpt s p = NotAnInput"
          by(auto simp add: EndPhase2_def Inv2c_inner_def)
        moreover
        from endphase2 p31 p32 False
        have "outpt s' = (outpt s) (p:= chosen s)  chosen s' = chosen s"
          by(auto simp add: EndPhase2_def)
        moreover
        from endphase2 nxt inv2c5
        have "inpt s' = inpt s  allInput s'= allInput s"
          by(auto simp add: EndPhase2_def HNext_def HNextPart_def)
        ultimately
        show "  outpt s p = NotAnInput 
               outpt s' = (outpt s)(p := chosen s)  chosen s' = chosen s 
               inpt s' = inpt s  allInput s' = allInput s"
          by auto
      qed
      thus ?thesis
        by auto
    qed
  qed
  thus "p. IFail is is' p  IChoose is is' p"
    by auto
qed

end