<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../../../unit.xsl"?>
<KIVSPEC name="Mondex-COP"><SPECBODY>enrich <a href="../../../specs/CASM/export/unit.xml">CASM</a> , 
       <a href="../../../specs/Mondex-index/export/unit.xml">Mondex-index</a> , 
       <a href="../../../specs/dummyoutput/export/unit.xml">dummyoutput</a> with
   
   functions 
      COP : mindex → message × (name → nat) × (name → PayDetailsSet) × (name → status) × (name → nat) × (name → PayDetails) × messageset × 
                     (name → nat) × (name → PayDetailsSet) × (name → status) × (name → nat) × (name → PayDetails) × messageset × dummyoutput
                     → bool;
   variables 
      balance' : name → nat; 
      exLog' : name → PayDetailsSet; 
      status' : name → status; 
      nextSeqNo' : name → nat; 
      pdAuth' : name → PayDetails; 
      ether' : messageset; 
      cop
      : message × (name → nat) × (name → PayDetailsSet) × (name → status) × (name → nat) × (name → PayDetails) × messageset × (name → nat) × 
        (name → PayDetailsSet) × (name → status) × (name → nat) × (name → PayDetails) × messageset × dummyoutput
        → bool
      ; 
   
   axioms 
      ⊦ 
        COP(abignore-ignore)(msg, balance, exLog, status, nextSeqNo, pdAuth, ether, balance', exLog', status', nextSeqNo', pdAuth', ether', dum)
      ↔ 〈begin 
            IGNORE#(; outmsg) ; LOSEMSG#(outmsg; ether)
         end〉 (balance = balance' ∧ exLog = exLog' ∧ status = status' ∧ nextSeqNo = nextSeqNo' ∧ pdAuth = pdAuth' ∧ ether = ether')
      ;
      ⊦ 
        COP(abignore-abort)(msg, balance, exLog, status, nextSeqNo, pdAuth, ether, balance', exLog', status', nextSeqNo', pdAuth', ether', dum)
      ↔ 〈begin 
            var  receiver with authentic(receiver) in ABORT#(receiver, pdAuth; exLog, status, nextSeqNo, outmsg) ; LOSEMSG#(outmsg; ether)
         end〉 (balance = balance' ∧ exLog = exLog' ∧ status = status' ∧ nextSeqNo = nextSeqNo' ∧ pdAuth = pdAuth' ∧ ether = ether')
      ;
      ⊦ 
        COP(abignore-increase)(msg, balance, exLog, status, nextSeqNo, pdAuth, ether, balance', exLog', status', nextSeqNo', pdAuth', ether', dum)
      ↔ 〈begin 
            var  receiver with authentic(receiver) in INCREASE#(receiver; nextSeqNo, outmsg) ; LOSEMSG#(outmsg; ether)
         end〉 (balance = balance' ∧ exLog = exLog' ∧ status = status' ∧ nextSeqNo = nextSeqNo' ∧ pdAuth = pdAuth' ∧ ether = ether')
      ;
      ⊦ 
        COP(abignore-startfrom)(msg, balance, exLog, status, nextSeqNo, pdAuth, ether, balance', exLog', status', nextSeqNo', pdAuth', ether', dum)
      ↔ 〈begin 
            IGNORE#(; outmsg) ∨ 
            var  receiver
            with authentic(receiver)
            in begin 
                  ABORT#(receiver, pdAuth; exLog, status, nextSeqNo, outmsg) ∨ 
                  if isStartFrom(msg) ∧ msg ∈ ether
                  then begin 
                          ABORT#(receiver, pdAuth; exLog, status, nextSeqNo, outmsg) ; 
                          STARTFROM#(msg, receiver, balance, ether; exLog, status, nextSeqNo, pdAuth, outmsg)
                       end
                  else abort
               end ; 
            LOSEMSG#(outmsg; ether)
         end〉 (balance = balance' ∧ exLog = exLog' ∧ status = status' ∧ nextSeqNo = nextSeqNo' ∧ pdAuth = pdAuth' ∧ ether = ether')
      ;
      ⊦ 
        COP(abignore-startto)(msg, balance, exLog, status, nextSeqNo, pdAuth, ether, balance', exLog', status', nextSeqNo', pdAuth', ether', dum)
      ↔ 〈begin 
            IGNORE#(; outmsg) ∨ 
            var  receiver
            with authentic(receiver)
            in begin 
                  ABORT#(receiver, pdAuth; exLog, status, nextSeqNo, outmsg) ∨ 
                  if isStartTo(msg) ∧ status(receiver) = idle ∧ msg ∈ ether
                  then begin 
                          ABORT#(receiver, pdAuth; exLog, status, nextSeqNo, outmsg) ; 
                          STARTTO#(msg, receiver, ether; exLog, status, nextSeqNo, pdAuth, outmsg)
                       end
                  else abort
               end ; 
            LOSEMSG#(outmsg; ether)
         end〉 (balance = balance' ∧ exLog = exLog' ∧ status = status' ∧ nextSeqNo = nextSeqNo' ∧ pdAuth = pdAuth' ∧ ether = ether')
      ;
      ⊦ 
        COP(transfer-req)(msg, balance, exLog, status, nextSeqNo, pdAuth, ether, balance', exLog', status', nextSeqNo', pdAuth', ether', dum)
      ↔ 〈begin 
            IGNORE#(; outmsg) ∨ 
            var  receiver
            with authentic(receiver)
            in if isreq(msg) ∧ msg .pd = pdAuth(receiver) ∧ status(receiver) = epr ∧ msg ∈ ether
               then REQ#(msg, receiver, pdAuth', ether; balance, status, outmsg)
               else abort ; 
            LOSEMSG#(outmsg; ether)
         end〉 (balance = balance' ∧ exLog = exLog' ∧ status = status' ∧ nextSeqNo = nextSeqNo' ∧ pdAuth = pdAuth' ∧ ether = ether')
      ;
      ⊦ 
        COP(abignore-val)(msg, balance, exLog, status, nextSeqNo, pdAuth, ether, balance', exLog', status', nextSeqNo', pdAuth', ether', dum)
      ↔ 〈begin 
            IGNORE#(; outmsg) ∨ 
            var  receiver
            with authentic(receiver)
            in if isval(msg) ∧ msg .pd = pdAuth(receiver) ∧ status(receiver) = epv ∧ msg ∈ ether
               then VAL#(msg, receiver, pdAuth', ether; balance, status, outmsg)
               else abort ; 
            LOSEMSG#(outmsg; ether)
         end〉 (balance = balance' ∧ exLog = exLog' ∧ status = status' ∧ nextSeqNo = nextSeqNo' ∧ pdAuth = pdAuth' ∧ ether = ether')
      ;
      ⊦ 
        COP(abignore-ack)(msg, balance, exLog, status, nextSeqNo, pdAuth, ether, balance', exLog', status', nextSeqNo', pdAuth', ether', dum)
      ↔ 〈begin 
            IGNORE#(; outmsg) ∨ 
            var  receiver
            with authentic(receiver)
            in if isack(msg) ∧ msg .pd = pdAuth(receiver) ∧ status(receiver) = epa ∧ msg ∈ ether
               then ACK#(msg, receiver, pdAuth', ether; status, outmsg)
               else abort ; 
            LOSEMSG#(outmsg; ether)
         end〉 (balance = balance' ∧ exLog = exLog' ∧ status = status' ∧ nextSeqNo = nextSeqNo' ∧ pdAuth = pdAuth' ∧ ether = ether')
      ; comment: Specification of the concrete operations of the Mondex refinement.
Instead of defining relations COP(cs,cs') directly we use Dynamic
Logic formulas 〈COP#(cs)〉 cs = cs' (meaning: started in cs, ASM rule COP# 
terminates and yields cs'). This allows to automate proofs using 
symbolic execution of COP#.  Note that using individual operations 
instead of one ASM rule produces  quite some overhead, since each 
COP must call IGNORE#, ABORT# and LOSEMSG# individually.;
   
end enrich</SPECBODY></KIVSPEC>
