1
|
|
2
|
--==================
|
3
|
-- Simple Elevator
|
4
|
--==================
|
5
|
|
6
|
(*
|
7
|
Acknowledgements: This example is inspired by a similar one first made
|
8
|
by Prover Technology AB, then adapted at Chalmers University
|
9
|
by Carl Johan Lillieroth, K.V.S. Prasad, Mary Sheeran, Angela Wallenburg,
|
10
|
and Jan-Willem Roorda.
|
11
|
|
12
|
-------
|
13
|
Setting
|
14
|
-------
|
15
|
|
16
|
It models a simple elevator, moving people between two floors.
|
17
|
In the elevator, there are three buttons:
|
18
|
- a button 1 to go to the first floor,
|
19
|
- a button 2 to go to the first floor, and
|
20
|
- a stop switch to stop the elevator.
|
21
|
On each floor, there is a button to call the elevator.
|
22
|
|
23
|
The elevator has three sensors,
|
24
|
- the first indicating if the elevator is on the first floor or not,
|
25
|
- the second doing the same for the second floor, and
|
26
|
- the third indicating if the elevator's door is closed or not.
|
27
|
|
28
|
The stop switch is located within the elevator and can be pressed to
|
29
|
block the elevator. While the switch is on the elevator stops immediately
|
30
|
if it was moving and ignores any other input. Turning the switch back off
|
31
|
makes the elevator to be responsive again to other inputs.
|
32
|
|
33
|
The elevator is moved up and down by a motor that is on the roof of the
|
34
|
building. The motor is controlled by two signals,
|
35
|
- one for moving the elevator up and
|
36
|
- one for moving it down.
|
37
|
|
38
|
The control system looks at the buttons that are being pressed and the sensors
|
39
|
that say where the elevator is and if the door is open, and then decides if
|
40
|
the motor should move the elevator up or down, or do nothing.
|
41
|
|
42
|
For simplicity, we do not distinguish between the case of someone on floor 1
|
43
|
(resp., 2) pressing the call button and someone in the elevator pressing
|
44
|
the button 1 (resp., 2).
|
45
|
|
46
|
-------------------
|
47
|
Safety Requirements
|
48
|
-------------------
|
49
|
|
50
|
The controller is supposed to satisfy the following safety requirements:
|
51
|
|
52
|
R1 The elevator moves only when the door is closed and the stop switch
|
53
|
is not on.
|
54
|
R2 The elevator may not pass the end positions, that is, go through
|
55
|
the roof or the floor.
|
56
|
R3 A moving elevator halts only if the stop switch is on, or the door
|
57
|
is opened, or the elevator has arrived at the destination floor.
|
58
|
R4 The elevator halts before changing direction.
|
59
|
R5 The signals sent to the motor are not contradictory.
|
60
|
R6 The elevator starts moving when it should.
|
61
|
R7 The elevator stays on a floor indefinitely as long as
|
62
|
there is no call the other floor
|
63
|
*)
|
64
|
|
65
|
-------------------------
|
66
|
-- Auxiliary operators --
|
67
|
-------------------------
|
68
|
|
69
|
node Happened(X : bool) returns (Y : bool);
|
70
|
let
|
71
|
Y = X or (false -> pre Y) ;
|
72
|
tel
|
73
|
|
74
|
node Since( X, Y : bool ) returns ( Z : bool );
|
75
|
let
|
76
|
Z = X or (Y and (false -> pre Z));
|
77
|
tel
|
78
|
|
79
|
node SinceIncl( X, Y : bool ) returns ( Z : bool );
|
80
|
let
|
81
|
Z = Y and (X or (false -> pre Z));
|
82
|
tel
|
83
|
|
84
|
node ToInt(X: bool) returns (N: int);
|
85
|
let
|
86
|
N = if X then 1 else 0;
|
87
|
tel
|
88
|
|
89
|
node MutuallyExcl_4(X1, X2, X3, X4: bool) returns (Y: bool);
|
90
|
let
|
91
|
Y = ToInt(X1) + ToInt(X2) + ToInt(X3) + ToInt(X4) < 2 ;
|
92
|
tel
|
93
|
|
94
|
|
95
|
---------------------------------
|
96
|
-- Controller high-level specs --
|
97
|
---------------------------------
|
98
|
|
99
|
(*@
|
100
|
contract ControlReq( Floor_1, Floor_2, DoorOpen, Call_1, Call_2, Stop : bool )
|
101
|
returns ( MotorUp, MotorDown : bool);
|
102
|
let
|
103
|
|
104
|
-------------------------------
|
105
|
-- Environmental assumptions --
|
106
|
-------------------------------
|
107
|
-- the elevator starts on the first floor
|
108
|
assume Floor_1 -> true;
|
109
|
|
110
|
-- if the elevator was on the first (second) floor and did not move up (down)
|
111
|
-- then it is still on that floor
|
112
|
assume true -> pre (Floor_1 and not MotorUp and not MotorDown) => Floor_1 ;
|
113
|
assume true -> pre (Floor_2 and not MotorUp and not MotorDown) => Floor_2 ;
|
114
|
(*
|
115
|
-- if the elevator was on the first (second) floor and moved up (down)
|
116
|
-- then it has left that floor
|
117
|
assume true -> pre (Floor_1 and MotorUp) => not Floor_1 ;
|
118
|
assume true -> pre (Floor_2 and MotorDown) => not Floor_2 ;
|
119
|
*)
|
120
|
|
121
|
-----------
|
122
|
-- Modes --
|
123
|
-----------
|
124
|
mode blocked (
|
125
|
require Stop or DoorOpen ;
|
126
|
ensure not MotorUp ;
|
127
|
ensure not MotorDown ;
|
128
|
);
|
129
|
|
130
|
mode servicing1 (
|
131
|
require SinceIncl(Call_1, not ::blocked and not Floor_1
|
132
|
and not (false -> pre MotorUp)
|
133
|
) ;
|
134
|
ensure MotorDown ;
|
135
|
ensure not MotorUp ;
|
136
|
) ;
|
137
|
|
138
|
mode servicing2 (
|
139
|
require SinceIncl(Call_2, not ::servicing1
|
140
|
and not ::blocked and not Floor_2
|
141
|
and not (false -> pre MotorDown)
|
142
|
) ;
|
143
|
ensure MotorUp ;
|
144
|
ensure not MotorDown ;
|
145
|
) ;
|
146
|
|
147
|
mode waiting (
|
148
|
require not ::blocked ;
|
149
|
require not ::servicing1 ;
|
150
|
require not ::servicing2 ;
|
151
|
ensure not MotorUp ;
|
152
|
ensure not MotorDown ;
|
153
|
) ;
|
154
|
|
155
|
|
156
|
-------------------------
|
157
|
-- Auxiliary variables --
|
158
|
-------------------------
|
159
|
|
160
|
-- Moving is true iff the elevator is moving now
|
161
|
var Moving: bool = MotorUp or MotorDown ;
|
162
|
|
163
|
-- Halts is true iff the elevator has come to a stop
|
164
|
var Halts: bool = not Moving and (false -> pre Moving);
|
165
|
|
166
|
-- The elevator can move now iff
|
167
|
-- the Stop button is not pressed and
|
168
|
-- the door is not closed
|
169
|
var CanMove: bool = not Stop and not DoorOpen;
|
170
|
|
171
|
-- The elevator should start moving iff
|
172
|
-- it was not moving before
|
173
|
-- it can move,
|
174
|
-- there is a call to go to a floor, and
|
175
|
-- the elevator is not a that floor
|
176
|
var ShouldMove: bool = (true -> not pre Moving)
|
177
|
and CanMove
|
178
|
and ((Call_1 and not Floor_1) or
|
179
|
(Call_2 and not Floor_2)) ;
|
180
|
|
181
|
----------------
|
182
|
-- Guarantees --
|
183
|
----------------
|
184
|
-- the execution modes are mutually exclusive
|
185
|
guarantee MutuallyExcl_4(::blocked, ::servicing1, ::servicing2, ::waiting) ;
|
186
|
|
187
|
-- R1: The elevator moves only when the door is closed and
|
188
|
-- the Stop button is not pressed
|
189
|
guarantee Moving => not DoorOpen and not Stop;
|
190
|
|
191
|
-- R2: The elevator will not pass the end positions, that is,
|
192
|
-- go through the roof or the floor.
|
193
|
guarantee (Floor_1 => not MotorDown) ;
|
194
|
guarantee (Floor_2 => not MotorUp) ;
|
195
|
|
196
|
-- R3: A moving elevator halts only if
|
197
|
-- the Stop button is pressed, or the door is open, or
|
198
|
-- the elevator has arrived at the destination floor
|
199
|
guarantee Halts => ( Stop
|
200
|
or DoorOpen
|
201
|
or ((true -> pre MotorDown) and Floor_1)
|
202
|
or ((true -> pre MotorUp) and Floor_2)
|
203
|
) ;
|
204
|
|
205
|
-- R4: he elevator halts before changing direction
|
206
|
guarantee true -> ( not (pre MotorDown and MotorUp)
|
207
|
and not (pre MotorUp and MotorDown)
|
208
|
) ;
|
209
|
|
210
|
-- R5: The signals sent to the motor are not contradictory
|
211
|
guarantee not (MotorUp and MotorDown) ;
|
212
|
|
213
|
-- R6: The elevator starts moving when it should
|
214
|
guarantee ShouldMove => Moving ;
|
215
|
|
216
|
-- R7: The elevator stays on a floor indefinitely as long as
|
217
|
-- there is no call the other floor
|
218
|
guarantee Since(Floor_1, not Happened(Call_2)) => Floor_1 ;
|
219
|
guarantee Since(Floor_2, not Happened(Call_1)) => Floor_2 ;
|
220
|
|
221
|
tel
|
222
|
*)
|
223
|
|
224
|
--------------------------------
|
225
|
-- Controller low-level specs --
|
226
|
--------------------------------
|
227
|
|
228
|
node Control( Floor_1, Floor_2, DoorOpen, Call_1, Call_2, Stop : bool )
|
229
|
returns ( MotorUp, MotorDown : bool) ;
|
230
|
(*@ contract import
|
231
|
ControlReq( Floor_1, Floor_2, DoorOpen, Call_1, Call_2, Stop )
|
232
|
returns ( MotorUp, MotorDown ) ;
|
233
|
*)
|
234
|
var CanMove : bool ;
|
235
|
let
|
236
|
CanMove = not Stop and not DoorOpen ;
|
237
|
|
238
|
(*
|
239
|
The elevator goes down iff all the following hold:
|
240
|
1) there is a call to the first floor or it was already going down
|
241
|
2) it can move
|
242
|
3) it is not on the first floor already
|
243
|
4) it was not going up
|
244
|
*)
|
245
|
MotorDown = (Call_1 or (false -> pre MotorDown))
|
246
|
and CanMove
|
247
|
and not Floor_1
|
248
|
and not (false -> pre MotorUp) ;
|
249
|
|
250
|
(*
|
251
|
The elevator goes up iff all the following hold:
|
252
|
0) it is not going down (i.e., going down takes precedence over going up)
|
253
|
1) there is a call to the second floor or it was already going up
|
254
|
2) it can move
|
255
|
3) it is not on the second floor already
|
256
|
4) it was not going down
|
257
|
*)
|
258
|
MotorUp = not MotorDown
|
259
|
and (Call_2 or (false -> pre MotorUp))
|
260
|
and CanMove
|
261
|
and not Floor_2
|
262
|
and not (false -> pre MotorDown) ;
|
263
|
|
264
|
--%MAIN;
|
265
|
tel
|
266
|
|
267
|
|
268
|
|
269
|
-- To simulate the elevator system make this the main file first
|
270
|
|
271
|
-- The simulator assumes (for brevity) that it takes 5 execution steps
|
272
|
-- to go from one floor to the other, each corresponding to an intermediate
|
273
|
-- "level". Level 0 corresponds to the first floor, level 4 to the second
|
274
|
node Simulator( Call_1, Call_2, Stop, DoorOpen : bool )
|
275
|
returns ( Floor_1, Floor_2 : bool ) ;
|
276
|
var MotorUp, MotorDown: bool ;
|
277
|
L: int ;
|
278
|
let
|
279
|
L = 0 -> if pre MotorUp then pre L + 1
|
280
|
else if pre MotorDown then pre L - 1
|
281
|
else pre L ;
|
282
|
Floor_1 = L = 0 ;
|
283
|
Floor_2 = L = 4 ;
|
284
|
|
285
|
(MotorUp, MotorDown) = Control(Floor_1, Floor_2, DoorOpen, Call_1, Call_2, Stop) ;
|
286
|
-- %MAIN;
|
287
|
tel
|
288
|
|
289
|
|
290
|
|
291
|
|