<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../../../unit.xsl"?>
<KIVSPEC name="SASM"><SPECBODY> asm specification 
   comment: specification of the first refined ASM. It implements
            the idea of a req-val-ack scheme together with exception logging;
   SASM#
   using <a href="../../../specs/set-nat/export/unit.xml">set-nat</a> <a href="../../../specs/genname/export/unit.xml">genname</a> 
         <a href="../../../specs/message-sels/export/unit.xml">message-sels</a> <a href="../../../specs/set-message/export/unit.xml">set-message</a> 
         <a href="../../../specs/set-PayDetails/export/unit.xml">set-PayDetails</a>
    target 
         procedures 
            SASM#   : (name → nat) × (name → PayDetailsSet) × (name → message) × (name → nat) × messageset nonfunctional indeterministic;
            SSTEP#   : (name → nat) × (name → PayDetailsSet) × (name → message) × (name → nat) × messageset nonfunctional indeterministic;
            LSSTEP#  name : (name → nat) × (name → PayDetailsSet) × (name → message) × (name → nat) × messageset nonfunctional indeterministic;
            SSTARTFROM#  name × (name → nat) : (name → message) × (name → nat) × messageset nonfunctional indeterministic;
            SSTARTTO#  name : (name → message) × (name → nat) × messageset nonfunctional indeterministic;
            SREQ#  name : (name → nat) × (name → message) × messageset nonfunctional indeterministic;
            SVAL#  name : (name → nat) × (name → message) × messageset nonfunctional indeterministic;
            SACK#  name : (name → message) × messageset nonfunctional indeterministic;
            SABORT#  name : (name → PayDetailsSet) × (name → message) × (name → nat) × messageset nonfunctional indeterministic;
            SLOSEMSG#   : messageset nonfunctional indeterministic;
         variables 
            balance : name → nat; 
            exLog : name → PayDetailsSet; 
            soutbox : name → message; 
            receiver : name; 
            ether, newether : messageset; 
            msg : message; 
            value : nat; 
            nextSeqNo : name → nat; 
   input variables ;
   state variables balance, exLog, soutbox, nextSeqNo, ether;
   initial state (exLog = (λ na. ∅) ∧ soutbox = (λ na. ⊥) ∧ ether ⊆ {⊥}  ∪ {λ msg. isStartFrom(msg)} )
   final state false
   asm rule SSTEP#
   declaration 
      asm : SASM# (balance, exLog, soutbox, nextSeqNo, ether)
              { 
                 while ¬ false do SSTEP#
              };, SSTEP : SSTEP# (balance, exLog, soutbox, nextSeqNo, ether)
                            { 
                               choose  receiver with authentic(receiver) in LSSTEP#
                            };, 
      LSSTEP
      : LSSTEP# (receiver; balance, exLog, soutbox, nextSeqNo, ether)
          { 
             SSTARTFROM# ∨ { 
                SSTARTTO# ∨ { 
                   SREQ# ∨ { 
                      SVAL# ∨ { 
                         SACK# ∨ { 
                            SABORT# ∨ SLOSEMSG#
                         }
                      }
                   }
                }
             }
          };, 
      SSTARTFROM
      : SSTARTFROM# (receiver, balance; soutbox, nextSeqNo, ether)
          { 
             choose  msg, n
             with (msg ∈ ether ∧ nextSeqNo(receiver) &lt; n)
             in if isStartFrom(msg) ∧ authentic(msg .name) ∧ msg .name ≠ receiver ∧ msg .value ≤ balance(receiver) ∧ isNone(soutbox(receiver))
                then { 
                        soutbox(receiver) := startTo(mkpd(receiver, nextSeqNo(receiver), msg .name, msg .nextSeqNo, msg .value)) ; 
                        nextSeqNo(receiver) := n ; 
                        ether := ether ++ soutbox(receiver)
                     }
             ifnone skip
          };, 
      SSTARTTO
      : SSTARTTO# (receiver; soutbox, nextSeqNo, ether)
          { 
             choose  msg, n
             with (msg ∈ ether ∧ nextSeqNo(receiver) &lt; n)
             in if   isStartTo(msg) ∧ authentic(msg .pd .from) ∧ msg .pd .from ≠ receiver ∧ msg .pd .to = receiver
                   ∧ msg .pd .tono = nextSeqNo(receiver) ∧ isNone(soutbox(receiver))
                then soutbox(receiver) := Req(msg .pd), nextSeqNo(receiver) := n, ether := ether ++ Req(msg .pd)
             ifnone skip
          };, 
      SREQ
      : SREQ# (receiver; balance, soutbox, ether)
          { 
             choose  msg
             with msg ∈ ether
             in if isReq(msg) ∧ isStartTo(soutbox(receiver)) ∧ soutbox(receiver) .pd = msg .pd
                then soutbox(receiver) := Val(msg .pd), balance(receiver) := balance(receiver) - msg .value, ether := ether ++ Val(msg .pd)
             ifnone skip
          };, 
      SVAL
      : SVAL# (receiver; balance, soutbox, ether)
          { 
             choose  msg
             with msg ∈ ether
             in if isVal(msg) ∧ isReq(soutbox(receiver)) ∧ soutbox(receiver) .pd = msg .pd
                then soutbox(receiver) := Ack(msg .pd), balance(receiver) := balance(receiver) + msg .value, ether := ether ++ Ack(msg .pd)
             ifnone skip
          };, 
      SACK
      : SACK# (receiver; soutbox, ether)
          { 
             choose  msg
             with msg ∈ ether
             in if isAck(msg) ∧ isVal(soutbox(receiver)) ∧ soutbox(receiver) .pd = msg .pd
                then soutbox(receiver) := ⊥, ether := ether ++ ⊥
             ifnone skip
          };, 
      SABORT
      : SABORT# (receiver; exLog, soutbox, nextSeqNo, ether)
          { 
             choose  n
             with nextSeqNo(receiver) ≤ n
             in { 
                   if isReq(soutbox(receiver)) ∨ isVal(soutbox(receiver))
                   then exLog(receiver) := exLog(receiver) ++ soutbox(receiver) .pd ; 
                   nextSeqNo(receiver) := n, soutbox(receiver) := ⊥, ether := ether ++ ⊥
                }
          };, 
      SLOSEMSG : SLOSEMSG# (ether)
                   { 
                      choose  newether with newether ⊆ ether in ether := newether
                   };
end asm specification</SPECBODY></KIVSPEC>
