<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../../../unit.xsl"?>
<KIVSPEC name="IASM"><SPECBODY> asm specification 
   comment: specification of the first refined ASM. It implements
            the idea of a req-val-ack scheme together with exception logging;
   IASM#
   using <a href="../../../specs/imessage-set/export/unit.xml">imessage-set</a> 
         <a href="../../../specs/ipaydetails-set/export/unit.xml">ipaydetails-set</a> 
         <a href="../../../specs/infinite-ids/export/unit.xml">infinite-ids</a>
    target 
         procedures 
            IASM#   : (name → nat) × (name → imessageset) × (name → imessage) × (name → ipaydetailsset) × (name → ipaydetailsset) × tidset nonfunctional indeterministic;
            ISTEP#   : (name → nat) × (name → imessageset) × (name → imessage) × (name → ipaydetailsset) × (name → ipaydetailsset) × tidset nonfunctional indeterministic;
            LISTEP#  name : (name → nat) × (name → imessageset) × (name → imessage) × (name → ipaydetailsset) × (name → ipaydetailsset) × tidset nonfunctional indeterministic;
            ISTARTTO#  name : (name → imessageset) × (name → imessage) × tidset nonfunctional indeterministic;
            IREQ#  name : (name → nat) × (name → imessageset) × (name → imessage) nonfunctional indeterministic;
            IVAL#  name : (name → nat) × (name → imessageset) × (name → imessage) nonfunctional indeterministic;
            IACK#  name : (name → imessageset) × (name → imessage) nonfunctional indeterministic;
            IABORT#  name : (name → imessage) × (name → ipaydetailsset) × (name → ipaydetailsset) nonfunctional;
            ILOSEMSGS#  name : (name → imessageset) nonfunctional indeterministic;
         variables 
            balance : name → nat; 
            exLogto, exLogfrom : name → ipaydetailsset; 
            inbox : name → imessageset; 
            outbox : name → imessage; 
            receiver : name; 
   input variables ;
   state variables balance, inbox, outbox, exLogfrom, exLogto, ts;
   initial state (exLogto = (λ na. ∅) ∧ exLogfrom = (λ na. ∅) ∧ inbox = (λ na. ∅) ∧ outbox = (λ na. none) ∧ ts = ∅)
   final state false
   asm rule ISTEP#
   declaration 
      asm : IASM# (balance, inbox, outbox, exLogfrom, exLogto, ts)
              { 
                 while ¬ false do ISTEP#
              };, ISTEP : ISTEP# (balance, inbox, outbox, exLogfrom, exLogto, ts)
                            { 
                               choose  receiver with authentic(receiver) in LISTEP#
                            };, 
      LISTEP
      : LISTEP# (receiver; balance, inbox, outbox, exLogfrom, exLogto, ts)
          { 
             ISTARTTO# ∨ { 
                IREQ# ∨ { 
                   IVAL# ∨ { 
                      IACK# ∨ { 
                         IABORT# ∨ ILOSEMSGS#
                      }
                   }
                }
             }
          };, 
      ISTARTTO
      : ISTARTTO# (receiver; inbox, outbox, ts)
          { 
             if isNone(outbox(receiver))
             then choose  na, value, tid
                  with (¬ tid ∈ ts ∧ authentic(na) ∧ na ≠ receiver)
                  in inbox(na) := inbox(na) ++ IReq(mkipd(receiver, value, tid)), outbox(receiver) := IReq(mkipd(na, value, tid)), ts := ts ++ tid
                  ifnone skip
          };, 
      IREQ
      : IREQ# (receiver; balance, inbox, outbox)
          { 
             choose  imsg
             with (  imsg ∈ inbox(receiver) ∧ isIReq(imsg) ∧ authentic(imsg .na) ∧ imsg .na ≠ receiver ∧ imsg .value ≤ balance(receiver)
                   ∧ isNone(outbox(receiver)))
             in { 
                   inbox(imsg .na) := inbox(imsg .na) ++ IVal(mkipd(receiver, imsg .value, imsg .tid)), outbox(receiver) := IVal(imsg .pd), 
                   balance(receiver) := balance(receiver) - imsg .value ; 
                   inbox(receiver) := inbox(receiver) -- imsg
                }
             ifnone skip
          };, 
      IVAL
      : IVAL# (receiver; balance, inbox, outbox)
          { 
             choose  imsg
             with (imsg ∈ inbox(receiver) ∧ isIVal(imsg) ∧ isIReq(outbox(receiver)) ∧ imsg .pd = outbox(receiver) .pd)
             in { 
                   inbox(imsg .na) := inbox(imsg .na) ++ IAck(mkipd(receiver, imsg .value, imsg .tid)), outbox(receiver) := IAck(imsg .pd), 
                   balance(receiver) := balance(receiver) + imsg .value ; 
                   inbox(receiver) := inbox(receiver) -- imsg
                }
             ifnone skip
          };, 
      IACK
      : IACK# (receiver; inbox, outbox)
          { 
             choose  imsg
             with (imsg ∈ inbox(receiver) ∧ isIAck(imsg) ∧ isIVal(outbox(receiver)) ∧ imsg .pd = outbox(receiver) .pd)
             in outbox(receiver) := none, inbox(receiver) := inbox(receiver) -- imsg
             ifnone skip
          };, 
      IABORT
      : IABORT# (receiver; outbox, exLogfrom, exLogto)
          { 
             if isIReq(outbox(receiver))
             then exLogto(receiver) := exLogto(receiver) ++ outbox(receiver) .pd ; 
             if isIVal(outbox(receiver))
             then exLogfrom(receiver) := exLogfrom(receiver) ++ outbox(receiver) .pd ; 
             outbox(receiver) := none
          };, 
      ILOSEMSGS : ILOSEMSGS# (receiver; inbox)
                    { 
                       choose  imsgs with imsgs ⊆ inbox(receiver) in inbox(receiver) := imsgs
                    };
end asm specification</SPECBODY></KIVSPEC>
