<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../../../unit.xsl"?>
<KIVSPEC name="CINV"><SPECBODY>enrich <a href="../../../specs/CASM/export/unit.xml">CASM</a> with comment: This specification defines the invariant CINV and the local invariant LOCALINV for one purse.
The main lemmas proved here are: LOCALINV is invariant for an operation of the same purse
(LOCALINV-receiver-lem) as well as for an operation of a different purse (LOCALINV-not-receiver-lem).
These two lemmas can be easily lifted to show that CINV is invariant (CINV-lem).;
   
   predicates 
      CINV : (name → nat) × (name → PayDetailsSet) × (name → status) × (name → nat) × (name → PayDetails) × messageset;
      LOCALINV : name × status × (name → nat) × (name → nat) × (name → PayDetailsSet) × (name → PayDetailsSet) × (name → status) × (name → status) × 
                 (name → nat) × (name → nat) × (name → PayDetails) × (name → PayDetails) × messageset × messageset;
      localok : name × (name → nat) × (name → nat) × (name → PayDetailsSet) × (name → PayDetailsSet) × (name → nat) × (name → nat) × 
                (name → PayDetails) × (name → PayDetails);
      pastether : messageset × (name → nat);
      pastexlog : name × PayDetailsSet × nat × (name → nat);
   variables 
      ether1 : messageset; 
      nextSeqNo0, nextSeqNo1 : name → nat; 
      exLog0, exLog1 : name → PayDetailsSet; 
      Ppd : PayDetails → bool; 
      balance0, balance1 : name → nat; 
      state0, state1 : name → status; 
      pdAuth0, pdAuth1 : name → PayDetails; 
      outmsg0, outmsg1 : message; 
      Pmsg : message → bool; 
      localether, localether0, localether1 : messageset; 
      from, to : name; 
   
   axioms 
      pastexlog-def
      : ⊦ 
          pastexlog(na, pds, n, nextSeqNo)
        ↔ (∀ pd. 
            pd ∈ pds → (pd .from = na → pd .fromno &lt; n ∧ pd .tono &lt; nextSeqNo(pd .to)) ∧ (pd .to = na → pd .tono &lt; n ∧ pd .tono &lt; nextSeqNo(pd .to)))
      ;
      pastether-def
      : ⊦ 
          pastether(ether, nextSeqNo)
        ↔   (∀ pd. 
                (Req(pd) ∈ ether ∨ Val(pd) ∈ ether ∨ Ack(pd) ∈ ether → authentic(pd .from) ∧ pd .fromno &lt; nextSeqNo(pd .from))
              ∧ (Req(pd) ∈ ether ∨ Val(pd) ∈ ether ∨ Ack(pd) ∈ ether → authentic(pd .to) ∧ pd .tono &lt; nextSeqNo(pd .to)))
          ∧ (∀ na, n, value. startTo(na, value, n) ∈ ether → authentic(na) ∧ n &lt; nextSeqNo(na))
      ;
      CINV-def
      : ⊦ 
          CINV(balance, exLog, state, nextSeqNo, pdAuth, ether)
        ↔   pastether(ether, nextSeqNo)
          ∧ (∀ na. 
                authentic(na)
              → (∃ balance1, exLog1, state1, nextSeqNo1, pdAuth1, ether1. 
                    LOCALINV(na, state(na), balance1, balance, exLog1, exLog, state1, state, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth, ether1, ether)
                  ∧ state1(na) = idle ∧ pastexlog(na, exLog(na), nextSeqNo1(na), nextSeqNo)))
      ;
      LOCALINV-idle
      : ⊦ 
          LOCALINV(na, idle, balance1, balance, exLog1, exLog, state1, state, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth, ether1, ether)
        ↔ localok(na, balance1, balance, exLog1, exLog, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth)
      ;
      localok-def
      : ⊦ 
          localok(na, balance1, balance, exLog1, exLog, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth)
        ↔ balance1(na) = balance(na) ∧ exLog1(na) = exLog(na) ∧ nextSeqNo1(na) = nextSeqNo(na) ∧ pdAuth1(na) = pdAuth(na)
      ;
      LOCALINV-epr
      : ⊦ 
          LOCALINV(na, epr, balance1, balance, exLog1, exLog, state1, state, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth, ether1, ether)
        ↔ (∃ to, value, m0. 
              authentic(to) ∧ na ≠ to ∧ value ≤ balance1(na)
            ∧ 〈STARTFROM#(na, startFrom(to, value, m0); state1, nextSeqNo1, pdAuth1, ether1)〉 
                  (  localok(na, balance1, balance, exLog1, exLog, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth)
                   ∧ (  Req(pdAuth(na)) ∈ ether
                      → state(pdAuth(na) .to) = epv ∧ pdAuth(na) = pdAuth(pdAuth(na) .to) ∨ pdAuth(na) ∈ exLog(pdAuth(na) .to))
                   ∧ ¬ Val(pdAuth(na)) ∈ ether ∧ ¬ Ack(pdAuth(na)) ∈ ether))
      ;
      LOCALINV-epv
      : ⊦ 
          LOCALINV(na, epv, balance1, balance, exLog1, exLog, state1, state, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth, ether1, ether)
        ↔ (∃ from, value, m0. 
              authentic(from) ∧ na ≠ from
            ∧ 〈STARTTO#(na, startTo(from, value, m0); state1, nextSeqNo1, pdAuth1, ether1)〉 
                  (  localok(na, balance1, balance, exLog1, exLog, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth)
                   ∧ (  Val(pdAuth(na)) ∈ ether
                      → state(pdAuth(na) .from) = epa ∧ pdAuth(na) = pdAuth(pdAuth(na) .from) ∨ pdAuth(na) ∈ exLog(pdAuth(na) .from))
                   ∧ ¬ Ack(pdAuth(na)) ∈ ether))
      ;
      LOCALINV-epa
      : ⊦ 
          LOCALINV(na, epa, balance1, balance, exLog1, exLog, state1, state, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth, ether1, ether)
        ↔ (∃ to, value, m0. 
              authentic(to) ∧ na ≠ to ∧ value ≤ balance1(na)
            ∧ 〈begin 
                  STARTFROM#(na, startFrom(to, value, m0); state1, nextSeqNo1, pdAuth1, ether1) ; REQ#(na, pdAuth1; balance1, state1, ether1)
               end〉 
                  (  localok(na, balance1, balance, exLog1, exLog, nextSeqNo1, nextSeqNo, pdAuth1, pdAuth)
                   ∧ pdAuth(na) .tono &lt; nextSeqNo(pdAuth(na) .to)
                   ∧ (  Ack(pdAuth(na)) ∈ ether
                      → ¬ pdAuth(na) ∈ exLog(pdAuth(na) .to) ∧ (state(pdAuth(na) .to) = idle ∨ pdAuth(na) ≠ pdAuth(pdAuth(na) .to)))))
      ;
   
end enrich</SPECBODY></KIVSPEC>
