Skip to content

Commit

Permalink
Wei-jupiter-tla: code formatting, see Issue #49; TypeOK models fixed …
Browse files Browse the repository at this point in the history
…for CONSTANT Msg
  • Loading branch information
hengxin committed Jan 3, 2019
1 parent 6ebfd3a commit 47a7bb8
Show file tree
Hide file tree
Showing 97 changed files with 2,467 additions and 1,722 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<intAttribute key="dfidDepth" value="100"/>
<booleanAttribute key="dfidMode" value="false"/>
<intAttribute key="distributedFPSetCount" value="0"/>
<stringAttribute key="distributedNetworkInterface" value="192.168.1.103"/>
<stringAttribute key="distributedNetworkInterface" value="114.212.83.69"/>
<intAttribute key="distributedNodesCount" value="1"/>
<stringAttribute key="distributedTLC" value="off"/>
<stringAttribute key="distributedTLCVMArgs" value=""/>
Expand All @@ -19,7 +19,7 @@
<stringAttribute key="modelBehaviorNext" value=""/>
<stringAttribute key="modelBehaviorSpec" value="Spec"/>
<intAttribute key="modelBehaviorSpecType" value="1"/>
<stringAttribute key="modelBehaviorVars" value="crec, chins, cbuf, sincoming, state, cincoming, srec, sbuf"/>
<stringAttribute key="modelBehaviorVars" value="crec, chins, cbuf, sincoming, state, cincoming, srec, aop, sbuf"/>
<stringAttribute key="modelComments" value=""/>
<booleanAttribute key="modelCorrectnessCheckDeadlock" value="false"/>
<listAttribute key="modelCorrectnessInvariants">
Expand All @@ -33,6 +33,7 @@
<listEntry value="Char;;{a, b};1;1"/>
<listEntry value="InitState;;&lt;&lt;&gt;&gt;;0;0"/>
<listEntry value="Server;;Server;1;0"/>
<listEntry value="Msg;;Msg;0;0"/>
</listAttribute>
<stringAttribute key="modelParameterContraint" value=""/>
<listAttribute key="modelParameterDefinitions">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,119 +1,91 @@
------------------------------ MODULE AJupiter ------------------------------
(*
Specification of the Jupiter protocol presented by Hagit Attiya and others.
Specification of the Jupiter protocol presented by Attiya et al.
*)
EXTENDS JupiterInterface
-----------------------------------------------------------------------------
(*
Messages between the Server and the Clients.
*)
Msg == [c: Client, ack: Int, op: Op \cup {Nop}] \cup \* messages sent to the Server from a client c \in Client
[ack: Int, op: Op \cup {Nop}] \* messages broadcast to Clients from the Server
-----------------------------------------------------------------------------
VARIABLES
cbuf, \* cbuf[c]: buffer (of operations) at the client c \in Client
crec, \* crec[c]: the number of new messages have been received by the client c \in Client
\* since the last time a message was sent
sbuf, \* sbuf[c]: buffer (of operations) at the Server, one per client c \in Client
srec \* srec[c]: the number of new messages have been ..., one per client c \in Client
cbuf, \* cbuf[c]: buffer for locally generated operations at client c \in Client
crec, \* crec[c]: number of remote operations received by client c \in Client
\* since the last time a local operation was generated
sbuf, \* sbuf[c]: buffer for transformed remote operations w.r.t client c \in Client
srec \* srec[c]: number of locally generated operations by client c \in Client
\* since the last time a remote operation was transformed at the Server

vars == <<intVars, cbuf, crec, sbuf, srec>>

AJMsg ==
[c: Client, ack: Nat, op: Op \cup {Nop}] \cup \* messages sent to the Server from client c \in Client
[ack: Nat, op: Op \cup {Nop}] \* messages broadcast to Clients from the Server
-----------------------------------------------------------------------------
TypeOK ==
/\ TypeOKInt
/\ Comm(Msg)!TypeOK
/\ cbuf \in [Client -> Seq(Op \cup {Nop})]
/\ crec \in [Client -> Int]
/\ crec \in [Client -> Nat]
/\ sbuf \in [Client -> Seq(Op \cup {Nop})]
/\ srec \in [Client -> Int]
/\ srec \in [Client -> Nat]
-----------------------------------------------------------------------------
Init ==
/\ InitInt
/\ Comm(Msg)!Init
/\ cbuf = [c \in Client |-> <<>>]
/\ crec = [c \in Client |-> 0]
/\ sbuf = [c \in Client |-> <<>>]
/\ srec = [c \in Client |-> 0]
-----------------------------------------------------------------------------
(*
Client c \in Client issues an operation op.
*)
ClientPerform(c, m) ==
LET cBuf == cbuf[c]
cShiftedBuf == SubSeq(cBuf, m.ack + 1, Len(cBuf))
xop == XformOpOps(Xform, m.op, cShiftedBuf)
xcBuf == XformOpsOp(Xform, cShiftedBuf, m.op)
IN /\ cbuf' = [cbuf EXCEPT ![c] = xcBuf]
/\ crec' = [crec EXCEPT ![c] = @ + 1]
/\ SetNewAop(c, xop)

ServerPerform(m) ==
LET c == m.c
cBuf == sbuf[c]
cShiftedBuf == SubSeq(cBuf, m.ack + 1, Len(cBuf))
xop == XformOpOps(Xform, m.op, cShiftedBuf)
xcBuf == XformOpsOp(Xform, cShiftedBuf, m.op)
IN /\ srec' = [cl \in Client |->
IF cl = c THEN srec[cl] + 1 ELSE 0]
/\ sbuf' = [cl \in Client |->
IF cl = c THEN xcBuf ELSE Append(sbuf[cl], xop)]
/\ SetNewAop(Server, xop)
/\ Comm!SSend(c, [cl \in Client |-> [ack |-> srec[cl], op |-> xop]])
-----------------------------------------------------------------------------
DoOp(c, op) ==
/\ state' = [state EXCEPT ![c] = Apply(op, @)]
/\ SetNewAop(c, op)
/\ cbuf' = [cbuf EXCEPT ![c] = Append(@, op)]
/\ crec' = [crec EXCEPT ![c] = 0]
/\ Comm(Msg)!CSend([c |-> c, ack |-> crec[c], op |-> op])

DoIns(c) ==
\E ins \in {op \in Ins: op.pos \in 1 .. (Len(state[c]) + 1) /\ op.ch \in chins /\ op.pr = Priority[c]}:
/\ DoOp(c, ins)
/\ chins' = chins \ {ins.ch} \* We assume that all inserted elements are unique.

DoDel(c) ==
\E del \in {op \in Del: op.pos \in 1 .. Len(state[c])}:
/\ DoOp(c, del)
/\ UNCHANGED chins
/\ Comm!CSend([c |-> c, ack |-> crec[c], op |-> op])

Do(c) ==
/\ \/ DoIns(c)
\/ DoDel(c)
/\ DoInt(DoOp, c)
/\ UNCHANGED <<sbuf, srec>>
(*
Client c \in Client receives a message from the Server.
*)

Rev(c) ==
/\ Comm(Msg)!CRev(c)
/\ crec' = [crec EXCEPT ![c] = @ + 1]
/\ LET m == Head(cincoming[c])
cBuf == cbuf[c] \* the buffer at client c \in Client
cShiftedBuf == SubSeq(cBuf, m.ack + 1, Len(cBuf)) \* buffer shifted
xop == XformOpOps(Xform, m.op, cShiftedBuf) \* transform op vs. shifted buffer
xcBuf == XformOpsOp(Xform, cShiftedBuf, m.op) \* transform shifted buffer vs. op
IN /\ cbuf' = [cbuf EXCEPT ![c] = xcBuf]
/\ state' = [state EXCEPT ![c] = Apply(xop, @)] \* apply the transformed operation xop
/\ UNCHANGED <<chins, sbuf, srec>>
(*
The Server receives a message.
*)
/\ RevInt(ClientPerform, c)
/\ UNCHANGED <<sbuf, srec>>

SRev ==
/\ Comm(Msg)!SRev
/\ LET m == Head(sincoming) \* the message to handle with
c == m.c \* the client c \in Client that sends this message
cBuf == sbuf[c] \* the buffer at the Server for client c \in Client
cShiftedBuf == SubSeq(cBuf, m.ack + 1, Len(cBuf)) \* buffer shifted
xop == XformOpOps(Xform, m.op, cShiftedBuf) \* transform op vs. shifted buffer
xcBuf == XformOpsOp(Xform, cShiftedBuf, m.op) \* transform shifted buffer vs. op
IN /\ srec' = [cl \in Client |->
IF cl = c
THEN srec[cl] + 1 \* receive one more operation from client c \in Client
ELSE 0] \* reset srec for other clients than c \in Client
/\ sbuf' = [cl \in Client |->
IF cl = c
THEN xcBuf \* transformed buffer for client c \in Client
ELSE Append(sbuf[cl], xop)] \* store transformed xop into other clients' bufs
/\ state' = [state EXCEPT ![Server] = Apply(xop, @)] \* apply the transformed operation
/\ Comm(Msg)!SSend(c, [cl \in Client |-> [ack |-> srec[cl], op |-> xop]])
/\ UNCHANGED <<chins, cbuf, crec>>
/\ SRevInt(ServerPerform)
/\ UNCHANGED <<cbuf, crec>>
-----------------------------------------------------------------------------
Next ==
\/ \E c \in Client: Do(c) \/ Rev(c)
\/ SRev
(*
Fairness: There is no requirement that the clients ever generate operations.
*)

Fairness ==
WF_vars(SRev \/ \E c \in Client: Rev(c))

Spec == Init /\ [][Next]_vars \* /\ Fairness
-----------------------------------------------------------------------------
(*
Quiescent Consistency (QC)
*)
QC ==
Comm(Msg)!EmptyChannel => Cardinality(Range(state)) = 1
QC == \* Quiescent Consistency
Comm!EmptyChannel => Cardinality(Range(state)) = 1

THEOREM Spec => []QC
=============================================================================
\* Modification History
\* Last modified Fri Dec 28 18:06:40 CST 2018 by hengxin
\* Created Sat Jun 23 17:14:18 CST 2018 by hengxin
\* Last modified Wed Jan 02 21:37:02 CST 2019 by hengxin
\* Created Satchins, Jun 23 17:14:18 CST 2018 by hengxin
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
------------------------------- MODULE CSComm -------------------------------
(*
Specification of communication in a Client-Server system model.
*)
EXTENDS SequenceUtils
-----------------------------------------------------------------------------
CONSTANTS
Client, \* the set of clients
Server, \* the (unique) server
Msg \* the set of possible messages
Client, \* the set of clients
Server, \* the (unique) server
Msg \* the set of messages
-----------------------------------------------------------------------------
VARIABLES
cincoming, \* cincoming[c]: incoming channel at client c \in Client
Expand All @@ -16,51 +13,34 @@ VARIABLES
TypeOK ==
/\ cincoming \in [Client -> Seq(Msg)]
/\ sincoming \in Seq(Msg)
-----------------------------------------------------------------------------

Init ==
/\ cincoming = [c \in Client |-> <<>>]
/\ sincoming = <<>>

EmptyChannel == Init
-----------------------------------------------------------------------------
(*
A client sends a message msg to the Server.
*)
CSend(msg) ==
CSend(msg) == \* A client sends a message msg to the Server.
/\ sincoming' = Append(sincoming, msg)
/\ UNCHANGED cincoming
(*
Client c receives a message from the Server.
*)
CRev(c) ==

CRev(c) == \* Client c receives and consumes a message from the Server.
/\ cincoming[c] # <<>>
/\ cincoming' = [cincoming EXCEPT ![c] = Tail(@)] \* consume a message
/\ cincoming' = [cincoming EXCEPT ![c] = Tail(@)]
/\ UNCHANGED sincoming
-----------------------------------------------------------------------------
(*
SRev/SSend below is often used as a subaction.
No UNCHANGED in their definitions.
*)
(*
The Server receives a message.
*)
SRev ==
SRev == \* The Server receives and consumes a message.
/\ sincoming # <<>>
/\ sincoming' = Tail(sincoming) \* consume a message
(*
The Server sents a message cmsg to each client other than c \in Client.
*)
SSend(c, cmsg) ==
/\ cincoming' = [cl \in Client |->
IF cl = c
THEN cincoming[cl]
ELSE Append(cincoming[cl], cmsg[cl])]
(*
The Server broadcasts the same message msg to all Clients other than c \in Client.
*)
SSendSame(c, msg) ==
/\ sincoming' = Tail(sincoming)

SSend(c, cmsg) == \* The Server sents a message cmsg to each client other than c \in Client.
/\ cincoming' = [cl \in Client |-> IF cl = c
THEN cincoming[cl]
ELSE Append(cincoming[cl], cmsg[cl])]

SSendSame(c, msg) == \* The Server broadcasts the message msg to all clients other than c \in Client.
/\ SSend(c, [cl \in Client |-> msg])
=============================================================================
\* Modification History
\* Last modified Tue Dec 04 20:49:02 CST 2018 by hengxin
\* Last modified Thu Jan 03 13:27:34 CST 2019 by hengxin
\* Created Sun Jun 24 10:25:34 CST 2018 by hengxin
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,28 @@
This module declares the parameters and defines the operators that describe
the interface of a family of Jupiter specs.
*)
EXTENDS Integers, SequenceUtils, OT
EXTENDS SequenceUtils, OT
-----------------------------------------------------------------------------
CONSTANTS
Client, \* the set of client replicas
Server, \* the (unique) server replica
Char, \* the set of characters allowed to be inserted
Msg, \* the set of messages
Char, \* the set of characters
InitState \* the initial state of each replica

ASSUME \* We assume that all inserted elements are unique.
/\ Range(InitState) \cap Char = {} \* due to the uniqueness requirement
----------------------------------------------------------------------
VARIABLES
aop, \* op[r]: the actual operation applied at replica r \in Replica
state, \* state[r]: state (the list content) of replica r \in Replica
cincoming, \* cincoming[c]: incoming channel at the client c \in Client
sincoming, \* incoming channel at the Server
chins \* a set of chars allowed to insert; this is for model checking

intVars == <<state, cincoming, sincoming, chins>>
Comm == INSTANCE CSComm
intVars == <<aop, state, cincoming, sincoming, chins>>
----------------------------------------------------------------------
Comm(Msg) == INSTANCE CSComm

Replica == Client \cup {Server}

List == Seq(Char \cup Range(InitState)) \* all possible lists
Expand All @@ -32,23 +33,61 @@ MaxLen == Cardinality(Char) + Len(InitState) \* the max length of lists in any s
ClientNum == Cardinality(Client)
Priority == CHOOSE f \in [Client -> 1 .. ClientNum] : Injective(f)
-----------------------------------------------------------------------------
Rd == [type: {"Rd"}]
Del == [type: {"Del"}, pos: 1 .. MaxLen] \* The positions (pos) are indexed from 1.
Ins == [type: {"Ins"}, pos: 1 .. (MaxLen + 1), ch: Char, pr: 1 .. ClientNum] \* pr: priority

Op == Ins \cup Del \* The set of all operations (now we don't consider Rd operations).

SetNewAop(r, aopr) ==
aop' = [aop EXCEPT ![r] = aopr]

ApplyNewAop(r) ==
state' = [state EXCEPT ![r] = Apply(aop'[r], @)]
-----------------------------------------------------------------------------
TypeOKInt ==
/\ aop \in [Replica -> Op \cup {Nop}]
/\ state \in [Replica -> List]
/\ Comm!TypeOK
/\ chins \subseteq Char

InitInt ==
/\ aop = [r \in Replica |-> Nop]
/\ state = [r \in Replica |-> InitState]
/\ Comm!Init
/\ chins = Char
-----------------------------------------------------------------------------
(*
The set of all operations. Note: The positions are indexed from 1.
*)
Rd == [type: {"Rd"}]
Del == [type: {"Del"}, pos: 1 .. MaxLen]
Ins == [type: {"Ins"}, pos: 1 .. (MaxLen + 1), ch: Char, pr: 1 .. ClientNum] \* pr: priority

DoIns(DoOp(_, _), c) == \* Client c \in Client generates and processes an "Ins" operation.
\E ins \in Ins:
/\ ins.pos \in 1 .. (Len(state[c]) + 1)
/\ ins.ch \in chins
/\ ins.pr = Priority[c]
/\ DoOp(c, ins)
/\ chins' = chins \ {ins.ch} \* We assume that all inserted elements are unique.

DoDel(DoOp(_, _), c) == \* Client c \in Client generates and processes a "Del" operation.
\E del \in Del:
/\ del.pos \in 1 .. Len(state[c])
/\ DoOp(c, del)
/\ UNCHANGED chins

DoInt(DoOp(_, _), c) == \* Client c \in Client issues an operation.
/\ \/ DoIns(DoOp, c)\* DoOp(c \in Client, op \in Op)
\/ DoDel(DoOp, c)
/\ ApplyNewAop(c)

RevInt(ClientPerformInt(_, _), c) == \* Client c \in Client receives and processes a message.
/\ Comm!CRev(c)
/\ ClientPerformInt(c, Head(cincoming[c])) \* ClientPerformInt(c \in Client, m \in Msg)
/\ ApplyNewAop(c)
/\ UNCHANGED chins

Op == Ins \cup Del \* Now we don't consider Rd operations
SRevInt(ServerPerformInt(_)) == \* The Server receives and processes a message.
/\ Comm!SRev
/\ ServerPerformInt(Head(sincoming)) \* ServerPerformInt(m \in Msg)
/\ ApplyNewAop(Server)
/\ UNCHANGED chins
=============================================================================
\* Modification History
\* Last modified Wed Dec 12 20:20:43 CST 2018 by hengxin
\* Last modified Thu Jan 03 13:39:06 CST 2019 by hengxin
\* Created Tue Dec 04 19:01:01 CST 2018 by hengxin
Loading

0 comments on commit 47a7bb8

Please sign in to comment.