-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path03_GoChannel.tla
112 lines (89 loc) · 3.01 KB
/
03_GoChannel.tla
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
----- MODULE 03_GoChannel -----
INSTANCE TLC
CONSTANTS NULL, Message
(*--algorithm GoChannel
variables
ch = [open |-> TRUE, sent |-> FALSE, rcvd |-> FALSE, val |-> NULL],
result = NULL;
define
Success == <>[](result = Message)
Ordered == pc.sender = "Done" ~> pc.receiver = "Done"
end define;
fair process Sender = "sender"
begin
Send:
assert ch.open;
await ~ch.sent;
ch.val := Message || ch.sent := TRUE;
WaitSent:
await ch.sent /\ ch.rcvd;
ch.sent := FALSE || ch.rcvd := FALSE;
Close:
assert ch.open;
ch.open := FALSE;
end process;
fair process Receiver = "receiver"
begin Receive:
while TRUE do
either
await ch.sent /\ ~ch.rcvd;
result := ch.val || ch.val := NULL || ch.rcvd := TRUE;
or
await ~ch.open;
goto Done;
end either;
end while;
end process;
end algorithm; *)
\* BEGIN TRANSLATION
VARIABLES ch, result, pc
(* define statement *)
Success == <>[](result = Message)
Ordered == pc.sender = "Done" ~> pc.receiver = "Done"
vars == << ch, result, pc >>
ProcSet == {"sender"} \cup {"receiver"}
Init == (* Global variables *)
/\ ch = [open |-> TRUE, sent |-> FALSE, rcvd |-> FALSE, val |-> NULL]
/\ result = NULL
/\ pc = [self \in ProcSet |-> CASE self = "sender" -> "Send"
[] self = "receiver" -> "Receive"]
Send == /\ pc["sender"] = "Send"
/\ Assert(ch.open, "Failure of assertion at line 18, column 5.")
/\ ~ch.sent
/\ ch' = [ch EXCEPT !.val = Message,
!.sent = TRUE]
/\ pc' = [pc EXCEPT !["sender"] = "WaitSent"]
/\ UNCHANGED result
WaitSent == /\ pc["sender"] = "WaitSent"
/\ ch.sent /\ ch.rcvd
/\ ch' = [ch EXCEPT !.sent = FALSE,
!.rcvd = FALSE]
/\ pc' = [pc EXCEPT !["sender"] = "Close"]
/\ UNCHANGED result
Close == /\ pc["sender"] = "Close"
/\ Assert(ch.open, "Failure of assertion at line 25, column 5.")
/\ ch' = [ch EXCEPT !.open = FALSE]
/\ pc' = [pc EXCEPT !["sender"] = "Done"]
/\ UNCHANGED result
Sender == Send \/ WaitSent \/ Close
Receive == /\ pc["receiver"] = "Receive"
/\ \/ /\ ch.sent /\ ~ch.rcvd
/\ /\ ch' = [ch EXCEPT !.val = NULL,
!.rcvd = TRUE]
/\ result' = ch.val
/\ pc' = [pc EXCEPT !["receiver"] = "Receive"]
\/ /\ ~ch.open
/\ pc' = [pc EXCEPT !["receiver"] = "Done"]
/\ UNCHANGED <<ch, result>>
Receiver == Receive
(* Allow infinite stuttering to prevent deadlock on termination. *)
Terminating == /\ \A self \in ProcSet: pc[self] = "Done"
/\ UNCHANGED vars
Next == Sender \/ Receiver
\/ Terminating
Spec == /\ Init /\ [][Next]_vars
/\ WF_vars(Sender)
/\ WF_vars(Receiver)
Termination == <>(\A self \in ProcSet: pc[self] = "Done")
\* END TRANSLATION
===============================