Skip to content

Commit c77859c

Browse files
split into specification and proof module
1 parent fd5382a commit c77859c

File tree

4 files changed

+553
-116
lines changed

4 files changed

+553
-116
lines changed

specifications/ewd840/EWD840.tla

+38-114
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
(* Derivation of a termination detection algorithm for distributed *)
66
(* computations (with W.H.J.Feijen and A.J.M. van Gasteren). *)
77
(***************************************************************************)
8-
EXTENDS Naturals, TLAPS
8+
EXTENDS Naturals
99

1010
CONSTANT N
1111
ASSUME NAssumption == N \in Nat \ {0}
@@ -21,17 +21,21 @@ TypeOK ==
2121
/\ tpos \in Nodes \* token position
2222
/\ tcolor \in Color \* token color
2323

24-
(* Initially the token is black. The other variables may take
25-
any "type-correct" values. *)
24+
(***************************************************************************)
25+
(* Initially the token is black. The other variables may take any *)
26+
(* "type-correct" values. *)
27+
(***************************************************************************)
2628
Init ==
2729
/\ active \in [Nodes -> BOOLEAN]
2830
/\ color \in [Nodes -> Color]
2931
/\ tpos \in Nodes
3032
/\ tcolor = "black"
3133

32-
(* Node 0 may initiate a probe when it has the token and
33-
when either it is black or the token is black. It passes
34-
a white token to node N-1 and paints itself white. *)
34+
(***************************************************************************)
35+
(* Node 0 may initiate a probe when it has the token and when either it is *)
36+
(* black or the token is black. It passes a white token to node N-1 and *)
37+
(* paints itself white. *)
38+
(***************************************************************************)
3539
InitiateProbe ==
3640
/\ tpos = 0
3741
/\ tcolor = "black" \/ color[0] = "black"
@@ -40,15 +44,16 @@ InitiateProbe ==
4044
/\ active' = active
4145
/\ color' = [color EXCEPT ![0] = "white"]
4246

43-
(* A node i different from 0 that possesses the token may pass
44-
it to node i-1 under the following circumstances:
45-
- node i is inactive or
46-
- node i is colored black or
47-
- the token is black.
48-
Note that the last two conditions will result in an
49-
inconclusive round, since the token will be black.
50-
The token will be stained if node i is black, otherwise
51-
its color is unchanged. Node i will be made white. *)
47+
(***************************************************************************)
48+
(* A node i different from 0 that possesses the token may pass it to node *)
49+
(* i-1 under the following circumstances: *)
50+
(* - node i is inactive or *)
51+
(* - node i is colored black or *)
52+
(* - the token is black. *)
53+
(* Note that the last two conditions will result in an inconclusive round, *)
54+
(* since the token will be black. The token will be stained if node i is *)
55+
(* black, otherwise its color is unchanged. Node i will be made white. *)
56+
(***************************************************************************)
5257
PassToken(i) ==
5358
/\ tpos = i
5459
/\ ~ active[i] \/ color[i] = "black" \/ tcolor = "black"
@@ -57,29 +62,39 @@ PassToken(i) ==
5762
/\ active' = active
5863
/\ color' = [color EXCEPT ![i] = "white"]
5964

65+
(***************************************************************************)
6066
(* token passing actions controlled by the termination detection algorithm *)
67+
(***************************************************************************)
6168
System == InitiateProbe \/ \E i \in Nodes \ {0} : PassToken(i)
6269

63-
(* An active node i may activate another node j by sending it
64-
a message. If j>i (hence activation goes against the direction
65-
of the token being passed), then node i becomes black. *)
70+
(***************************************************************************)
71+
(* An active node i may activate another node j by sending it a message. *)
72+
(* If j>i (hence activation goes against the direction of the token being *)
73+
(* passed), then node i becomes black. *)
74+
(***************************************************************************)
6675
SendMsg(i) ==
6776
/\ active[i]
6877
/\ \E j \in Nodes \ {i} :
6978
/\ active' = [active EXCEPT ![j] = TRUE]
7079
/\ color' = [color EXCEPT ![i] = IF j>i THEN "black" ELSE @]
7180
/\ UNCHANGED <<tpos, tcolor>>
7281

73-
(* Any active node may become inactive at any moment. *)
82+
(***************************************************************************)
83+
(* Any active node may become inactive at any moment. *)
84+
(***************************************************************************)
7485
Deactivate(i) ==
7586
/\ active[i]
7687
/\ active' = [active EXCEPT ![i] = FALSE]
7788
/\ UNCHANGED <<color, tpos, tcolor>>
7889

79-
(* actions performed by the underlying algorithm *)
90+
(***************************************************************************)
91+
(* actions performed by the underlying algorithm *)
92+
(***************************************************************************)
8093
Environment == \E i \in Nodes : SendMsg(i) \/ Deactivate(i)
8194

82-
(* next-state relation: disjunction of above actions *)
95+
(***************************************************************************)
96+
(* next-state relation: disjunction of above actions *)
97+
(***************************************************************************)
8398
Next == System \/ Environment
8499

85100
vars == <<active, color, tpos, tcolor>>
@@ -141,104 +156,13 @@ Inv ==
141156
\/ P2:: tcolor = "black"
142157

143158
(***************************************************************************)
144-
(* Use the following specification to check that the predicate *)
159+
(* Use the following specification to let TLC check that the predicate *)
145160
(* TypeOK /\ Inv is inductive for EWD 840: verify that it is an *)
146161
(* (ordinary) invariant of a specification obtained by replacing the *)
147162
(* initial condition by that conjunction. *)
148163
(***************************************************************************)
149164
CheckInductiveSpec == TypeOK /\ Inv /\ [][Next]_vars
150-
-----------------------------------------------------------------------------
151-
(***************************************************************************)
152-
(* Interactive proof of safety using TLAPS. *)
153-
(***************************************************************************)
154-
155-
(***************************************************************************)
156-
(* The algorithm is type-correct: TypeOK is an inductive invariant. *)
157-
(***************************************************************************)
158-
LEMMA TypeCorrect == Spec => []TypeOK
159-
<1>1. Init => TypeOK
160-
BY DEF Init, TypeOK, Color
161-
<1>2. TypeOK /\ [Next]_vars => TypeOK'
162-
BY NAssumption DEF TypeOK, Color, Nodes, vars, Next, System, Environment,
163-
InitiateProbe, PassToken, SendMsg, Deactivate
164-
<1>. QED BY <1>1, <1>2, PTL DEF Spec
165-
166-
167-
(***************************************************************************)
168-
(* Follows a more detailed proof of the same lemma. It illustrates how *)
169-
(* proofs can be decomposed hierarchically. Use the "Decompose Proof" *)
170-
(* command (C-G C-D) to prepare the skeleton of the level-2 steps. *)
171-
(***************************************************************************)
172-
LEMMA Spec => []TypeOK
173-
<1>1. Init => TypeOK
174-
BY DEF Init, TypeOK, Color
175-
<1>2. TypeOK /\ [Next]_vars => TypeOK'
176-
<2> SUFFICES ASSUME TypeOK,
177-
[Next]_vars
178-
PROVE TypeOK'
179-
OBVIOUS
180-
<2>. USE NAssumption DEF TypeOK, Nodes, Color
181-
<2>1. CASE InitiateProbe
182-
BY <2>1 DEF InitiateProbe
183-
<2>2. ASSUME NEW i \in Nodes \ {0},
184-
PassToken(i)
185-
PROVE TypeOK'
186-
BY <2>2 DEF PassToken
187-
<2>3. ASSUME NEW i \in Nodes,
188-
SendMsg(i)
189-
PROVE TypeOK'
190-
BY <2>3 DEF SendMsg
191-
<2>4. ASSUME NEW i \in Nodes,
192-
Deactivate(i)
193-
PROVE TypeOK'
194-
BY <2>4 DEF Deactivate
195-
<2>5. CASE UNCHANGED vars
196-
BY <2>5 DEF vars
197-
<2>. QED
198-
BY <2>1, <2>2, <2>3, <2>4, <2>5 DEF Environment, Next, System
199-
<1>. QED BY <1>1, <1>2, PTL DEF Spec
200-
201-
(***************************************************************************)
202-
(* Prove the main soundness property of the algorithm by (1) proving that *)
203-
(* Inv is an inductive invariant and (2) that it implies correctness. *)
204-
(***************************************************************************)
205-
THEOREM Safety == Spec => []TerminationDetection
206-
<1>1. Init => Inv
207-
BY NAssumption DEF Init, Inv, Nodes
208-
<1>2. TypeOK /\ Inv /\ [Next]_vars => Inv'
209-
BY NAssumption
210-
DEF TypeOK, Inv, Next, vars, Nodes, Color,
211-
System, Environment, InitiateProbe, PassToken, SendMsg, Deactivate
212-
<1>3. Inv => TerminationDetection
213-
BY NAssumption DEF Inv, TerminationDetection, terminationDetected, Nodes
214-
<1>. QED
215-
BY <1>1, <1>2, <1>3, TypeCorrect, PTL DEF Spec
216-
217-
218-
(***************************************************************************)
219-
(* Step <1>3 of the above proof shows that Dijkstra's invariant implies *)
220-
(* TerminationDetection. If you find that one-line proof too obscure, here *)
221-
(* is a more detailed, hierarchical proof of that same implication. *)
222-
(***************************************************************************)
223-
LEMMA Inv => TerminationDetection
224-
<1>1. SUFFICES ASSUME tpos = 0, tcolor = "white",
225-
color[0] = "white", ~ active[0],
226-
Inv
227-
PROVE \A i \in Nodes : ~ active[i]
228-
BY <1>1 DEF TerminationDetection, terminationDetected
229-
<1>2. ~ Inv!P2 BY tcolor = "white" DEF Inv
230-
<1>3. ~ Inv!P1 BY <1>1 DEF Inv
231-
<1>. QED
232-
<2>1. Inv!P0 BY Inv, <1>2, <1>3 DEF Inv
233-
<2>. TAKE i \in Nodes
234-
<2>3. CASE i = 0 BY <2>1, <1>1, <2>3
235-
<2>4. CASE i \in 1 .. N-1
236-
<3>1. tpos < i BY tpos=0, <2>4, NAssumption
237-
<3>2. i < N BY NAssumption, <2>4
238-
<3>. QED BY <3>1, <3>2, <2>1
239-
<2>. QED BY <2>3, <2>4 DEF Nodes
240-
241165
=============================================================================
242166
\* Modification History
243-
\* Last modified Mon May 30 20:40:46 CEST 2016 by merz
167+
\* Last modified Tue Jun 28 18:17:45 CEST 2016 by merz
244168
\* Created Mon Sep 09 11:33:10 CEST 2013 by merz
+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---------------------------- MODULE EWD840_proof ----------------------------
2+
(***************************************************************************)
3+
(* This module contains the proof of the safety properties of Dijkstra's *)
4+
(* termination detection algorithm. Checking the proof requires TLAPS to *)
5+
(* be installed. *)
6+
(***************************************************************************)
7+
EXTENDS EWD840, TLAPS
8+
9+
(***************************************************************************)
10+
(* The algorithm is type-correct: TypeOK is an inductive invariant. *)
11+
(***************************************************************************)
12+
LEMMA TypeCorrect == Spec => []TypeOK
13+
<1>1. Init => TypeOK
14+
BY DEF Init, TypeOK, Color
15+
<1>2. TypeOK /\ [Next]_vars => TypeOK'
16+
BY NAssumption DEF TypeOK, Color, Nodes, vars, Next, System, Environment,
17+
InitiateProbe, PassToken, SendMsg, Deactivate
18+
<1>. QED BY <1>1, <1>2, PTL DEF Spec
19+
20+
21+
(***************************************************************************)
22+
(* Follows a more detailed proof of the same lemma. It illustrates how *)
23+
(* proofs can be decomposed hierarchically. Use the "Decompose Proof" *)
24+
(* command (C-G C-D) to prepare the skeleton of the level-2 steps. *)
25+
(***************************************************************************)
26+
LEMMA Spec => []TypeOK
27+
<1>1. Init => TypeOK
28+
BY DEF Init, TypeOK, Color
29+
<1>2. TypeOK /\ [Next]_vars => TypeOK'
30+
<2> SUFFICES ASSUME TypeOK,
31+
[Next]_vars
32+
PROVE TypeOK'
33+
OBVIOUS
34+
<2>. USE NAssumption DEF TypeOK, Nodes, Color
35+
<2>1. CASE InitiateProbe
36+
BY <2>1 DEF InitiateProbe
37+
<2>2. ASSUME NEW i \in Nodes \ {0},
38+
PassToken(i)
39+
PROVE TypeOK'
40+
BY <2>2 DEF PassToken
41+
<2>3. ASSUME NEW i \in Nodes,
42+
SendMsg(i)
43+
PROVE TypeOK'
44+
BY <2>3 DEF SendMsg
45+
<2>4. ASSUME NEW i \in Nodes,
46+
Deactivate(i)
47+
PROVE TypeOK'
48+
BY <2>4 DEF Deactivate
49+
<2>5. CASE UNCHANGED vars
50+
BY <2>5 DEF vars
51+
<2>. QED
52+
BY <2>1, <2>2, <2>3, <2>4, <2>5 DEF Environment, Next, System
53+
<1>. QED BY <1>1, <1>2, PTL DEF Spec
54+
55+
(***************************************************************************)
56+
(* Prove the main soundness property of the algorithm by (1) proving that *)
57+
(* Inv is an inductive invariant and (2) that it implies correctness. *)
58+
(***************************************************************************)
59+
THEOREM Safety == Spec => []TerminationDetection
60+
<1>1. Init => Inv
61+
BY NAssumption DEF Init, Inv, Nodes
62+
<1>2. TypeOK /\ Inv /\ [Next]_vars => Inv'
63+
BY NAssumption
64+
DEF TypeOK, Inv, Next, vars, Nodes, Color,
65+
System, Environment, InitiateProbe, PassToken, SendMsg, Deactivate
66+
<1>3. Inv => TerminationDetection
67+
BY NAssumption DEF Inv, TerminationDetection, terminationDetected, Nodes
68+
<1>. QED
69+
BY <1>1, <1>2, <1>3, TypeCorrect, PTL DEF Spec
70+
71+
72+
(***************************************************************************)
73+
(* Step <1>3 of the above proof shows that Dijkstra's invariant implies *)
74+
(* TerminationDetection. If you find that one-line proof too obscure, here *)
75+
(* is a more detailed, hierarchical proof of that same implication. *)
76+
(***************************************************************************)
77+
LEMMA Inv => TerminationDetection
78+
<1>1. SUFFICES ASSUME tpos = 0, tcolor = "white",
79+
color[0] = "white", ~ active[0],
80+
Inv
81+
PROVE \A i \in Nodes : ~ active[i]
82+
BY <1>1 DEF TerminationDetection, terminationDetected
83+
<1>2. ~ Inv!P2 BY tcolor = "white" DEF Inv
84+
<1>3. ~ Inv!P1 BY <1>1 DEF Inv
85+
<1>. QED
86+
<2>1. Inv!P0 BY Inv, <1>2, <1>3 DEF Inv
87+
<2>. TAKE i \in Nodes
88+
<2>3. CASE i = 0 BY <2>1, <1>1, <2>3
89+
<2>4. CASE i \in 1 .. N-1
90+
<3>1. tpos < i BY tpos=0, <2>4, NAssumption
91+
<3>2. i < N BY NAssumption, <2>4
92+
<3>. QED BY <3>1, <3>2, <2>1
93+
<2>. QED BY <2>3, <2>4 DEF Nodes
94+
95+
=============================================================================
96+
\* Modification History
97+
\* Last modified Tue Jun 28 18:24:01 CEST 2016 by merz
98+
\* Created Mon Sep 09 11:33:10 CEST 2013 by merz

specifications/ewd840/README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@ in a ring. The algorithm was published as
44
Edsger W. Dijkstra: Derivation of a termination detection algorithm for distributed computations. Inf. Proc. Letters 16:217-219 (1983).
55
It appears as [EWD 840](https://www.cs.utexas.edu/users/EWD/ewd08xx/EWD840.PDF).
66

7-
TLC can be used to verify safety and liveness properties. The TLA+ module also
8-
contains a hierarchical proof of the safety property that is checked by TLAPS.
7+
The module EWD840 contains the specification of the algorithm in TLA+, as well
8+
as its correctness properties (and some non-properties) that can be model checked
9+
using TLC. You'll need to instantiate the parameter N by a concrete value, say, 4.
10+
11+
The module EWD840_proofs contains hierarchical proofs of type correctness and of
12+
the main safety property. These proofs can be checked using TLAPS.

0 commit comments

Comments
 (0)