-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPeterson.mlw
160 lines (117 loc) · 4.16 KB
/
Peterson.mlw
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
(* Peterson's algorithm, 2 processes
*)
module Peterson
use bool.Bool
use map.Map
use map.Const
use mutexAbstract.MutexAbstract
type state = A1 | A2 | A3 | CS | A4 | Done
let predicate eq (p1: proc) (p2: proc)
ensures { result <-> p1=p2 }
= match p1 with
| Zero -> match p2 with
| Zero -> true
| One -> false
end
| One -> match p2 with
| Zero -> false
| One -> true
end
end
(* System configurations
*)
type world = { pc : map proc state ;
flag : map proc bool ;
turn : proc }
(* Refinement mapping
*)
function mapSt (st:state) : MutexAbstractN.state =
match st with
| A1 -> MutexAbstractN.Init
| A2 -> MutexAbstractN.Init
| A3 -> MutexAbstractN.Init
| CS -> MutexAbstractN.CS
| A4 -> MutexAbstractN.Done
| Done -> MutexAbstractN.Done
end
let ghost function refn (w:world) : MutexAbstract.world
= { pc_a = fun p -> mapSt w.pc[p] }
(* Inductive invariant
*)
predicate inv (w:world) = forall p :proc.
(w.pc[p]<>A1 /\ w.pc[p]<>Done -> w.flag[p])
/\
(w.pc[p]=CS /\ w.pc[other p]=A3 -> w.turn = p)
(* System INIT
*)
predicate initWorld_p (w:world) =
w.pc = const A1 /\ w.flag = const false /\ w.turn = Zero
let ghost predicate initWorld (w:world) = initWorld_p w
(* Action functions
*)
predicate a1_enbld (w:world) (p:proc) =
w.pc[p] = A1
let ghost function a1 (w:world) (p:proc) : world
requires { a1_enbld w p }
ensures { inv w -> inv result }
ensures { inv w -> refn result = refn w \/ step (refn w) (refn result) }
= { pc = w.pc[p<-A2] ; flag = w.flag[p<-true] ; turn = w.turn }
predicate a2_enbld (w:world) (p:proc) =
w.pc[p] = A2
let ghost function a2 (w:world) (p:proc) : world
requires { a2_enbld w p }
ensures { inv w -> inv result }
ensures { inv w -> refn result = refn w \/ step (refn w) (refn result) }
= { pc = w.pc[p<-A3] ; flag = w.flag ; turn = other p }
predicate a3_enbld (w:world) (p:proc) =
w.pc[p] = A3
let ghost function a3 (w:world) (p:proc) : world
requires { a3_enbld w p }
ensures { inv w -> inv result }
ensures { inv w -> refn result = refn w \/ step (refn w) (refn result) }
= let next = if (w.flag[other p] && eq w.turn (other p)) then A3 else CS in
{ pc = w.pc[p<-next] ; flag = w.flag ; turn = w.turn }
predicate cs_enbld (w:world) (p:proc) =
w.pc[p] = CS
let ghost function cs (w:world) (p:proc) : world
requires { cs_enbld w p }
ensures { inv w -> inv result }
ensures { inv w -> refn result = refn w \/ step (refn w) (refn result) }
= { pc = w.pc[p<-A4] ; flag = w.flag ; turn = w.turn }
predicate a4_enbld (w:world) (p:proc) =
w.pc[p] = A4
let ghost function a4 (w:world) (p:proc) : world
requires { a4_enbld w p }
ensures { inv w -> inv result }
ensures { inv w -> refn result = refn w \/ step (refn w) (refn result) }
= { pc = w.pc[p<-Done] ; flag = w.flag[p<-false] ; turn = w.turn }
(* Transition relation
*)
inductive stepind world world =
| a1 : forall w :world, p :proc.
a1_enbld w p -> stepind w (a1 w p)
| a2 : forall w :world, p :proc.
a2_enbld w p -> stepind w (a2 w p)
| a3 : forall w :world, p :proc.
a3_enbld w p -> stepind w (a3 w p)
| cs : forall w :world, p :proc.
cs_enbld w p -> stepind w (cs w p)
| a4 : forall w :world, p :proc.
a4_enbld w p -> stepind w (a4 w p)
let ghost predicate step (w1:world) (w2:world) = stepind w1 w2
(* Proof of refinement
*)
clone export refinement.Refinement with
type worldC=world, type worldA=MutexAbstract.world, val refn,
predicate invC=inv, predicate invA=MutexAbstract.inv,
val initWorldC=initWorld, val initWorldA=MutexAbstract.initWorld,
val stepC=step, val stepA=MutexAbstract.step
(* Safety Property
*)
lemma safety : forall w :world. reachableC w ->
not (w.pc[Zero] = CS /\ w.pc[One] = CS)
function fullrefn (w:world) : MutexAbstractN.world =
MutexAbstract.refn(refn w)
lemma safetyA : forall w :world. reachableC w ->
MutexAbstractN.atMostOneCS (fullrefn w)
end