1 |
fd5381b7
|
Bourbouh
|
-------------------------
|
2 |
|
|
-- Auxiliary operators --
|
3 |
|
|
-------------------------
|
4 |
|
|
node Even (N: int) returns (B: bool) ;
|
5 |
|
|
let
|
6 |
|
|
B = (N mod 2 = 0) ;
|
7 |
|
|
tel
|
8 |
|
|
|
9 |
|
|
node ToInt (X: bool) returns (N: int) ;
|
10 |
|
|
let
|
11 |
|
|
N = if X then 1 else 0 ;
|
12 |
|
|
tel
|
13 |
|
|
|
14 |
|
|
node Count (X: bool) returns (N: int) ;
|
15 |
|
|
let
|
16 |
|
|
N = ToInt(X) -> ToInt(X) + pre N ;
|
17 |
|
|
tel
|
18 |
|
|
|
19 |
|
|
node Sofar ( X : bool ) returns ( Y : bool ) ;
|
20 |
|
|
let
|
21 |
|
|
Y = X -> (X and (pre Y)) ;
|
22 |
|
|
tel
|
23 |
|
|
|
24 |
|
|
node Since ( X, Y : bool ) returns ( Z : bool ) ;
|
25 |
|
|
let
|
26 |
|
|
Z = X or (Y and (false -> pre Z)) ;
|
27 |
|
|
tel
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
node SinceIncl ( X, Y : bool ) returns ( Z : bool ) ;
|
31 |
|
|
let
|
32 |
|
|
Z = Y and (X or (false -> pre Z)) ;
|
33 |
|
|
tel
|
34 |
|
|
|
35 |
|
|
node Increased (N: int) returns (B: bool) ;
|
36 |
|
|
let
|
37 |
|
|
B = true -> N > pre N ;
|
38 |
|
|
tel
|
39 |
|
|
|
40 |
|
|
node Stable (N: int) returns (B: bool) ;
|
41 |
|
|
let
|
42 |
|
|
B = true -> N = pre N ;
|
43 |
|
|
tel
|
44 |
|
|
|
45 |
|
|
-------------------------------
|
46 |
|
|
-- Stopwatch high-level spec --
|
47 |
|
|
-------------------------------
|
48 |
6c964a9b
|
ploc
|
|
49 |
c3af3032
|
Bourbouh
|
|
50 |
fd5381b7
|
Bourbouh
|
contract stopwatchSpec ( toggle, reset : bool ) returns ( time : int ) ;
|
51 |
|
|
let
|
52 |
|
|
-- the watch is activated initially if the toggle button is pressed
|
53 |
|
|
-- afterwards, it is activated iff
|
54 |
|
|
-- it was activated before and the toggle button is unpressed or
|
55 |
|
|
-- it was not activated before and the toggle button is pressed
|
56 |
|
|
var on: bool = toggle -> (pre on and not toggle)
|
57 |
|
|
or (not pre on and toggle) ;
|
58 |
|
|
|
59 |
|
|
-- we can assume that the two buttons are never pressed together
|
60 |
|
|
assume not (toggle and reset) ;
|
61 |
|
|
|
62 |
|
|
-- the elapsed time starts at 1 or 0 depending
|
63 |
|
|
-- on whether the watch is activated or not
|
64 |
|
|
guarantee (on => time = 1) -> true ;
|
65 |
|
|
guarantee (not on => time = 0) -> true ;
|
66 |
|
|
-- the elapsed time is always non-negative
|
67 |
|
|
guarantee time >= 0 ;
|
68 |
|
|
|
69 |
|
|
-- if there is no reset now and there was an even number of counts since the last reset
|
70 |
|
|
-- then the current elapsed time is the same as the previous one
|
71 |
|
|
guarantee not reset and Since(reset, Even(Count(toggle)))
|
72 |
|
|
=> Stable(time) ;
|
73 |
|
|
-- if there is no reset now and there was an odd number of counts since the last reset
|
74 |
|
|
-- then the current elapsed time is greater than previous one
|
75 |
|
|
guarantee not reset and Since(reset, not Even(Count(toggle)))
|
76 |
|
|
=> Increased(time) ;
|
77 |
|
|
|
78 |
|
|
|
79 |
|
|
-- guarantee true -> not Even(Count(toggle)) and Count(reset) = 0 => time > pre time ;
|
80 |
|
|
|
81 |
|
|
|
82 |
|
|
-- the watch is in resetting mode if the reset button is pressed
|
83 |
|
|
-- while in that mode, the elapsed time is 0
|
84 |
|
|
mode resetting (
|
85 |
|
|
require reset ;
|
86 |
|
|
ensure time = 0 ;
|
87 |
|
|
) ;
|
88 |
|
|
|
89 |
|
|
-- the watch is in running mode if is activated and
|
90 |
|
|
-- the reset button is unpressed.
|
91 |
|
|
-- while in that mode, the elapsed time increases by 1
|
92 |
|
|
mode running (
|
93 |
|
|
require on ;
|
94 |
|
|
require not reset ;
|
95 |
|
|
ensure true -> time = pre time + 1 ;
|
96 |
|
|
) ;
|
97 |
|
|
|
98 |
|
|
-- the watch is in stopped mode if is not activated and
|
99 |
|
|
-- the reset button is unpressed
|
100 |
|
|
-- while in that mode, the elapsed time remains the same
|
101 |
|
|
mode stopped (
|
102 |
|
|
require not reset ;
|
103 |
|
|
require not on ;
|
104 |
|
|
ensure true -> time = pre time ;
|
105 |
|
|
) ;
|
106 |
|
|
tel
|
107 |
c3af3032
|
Bourbouh
|
|
108 |
fd5381b7
|
Bourbouh
|
|
109 |
|
|
------------------------------
|
110 |
|
|
-- Stopwatch low-level spec --
|
111 |
|
|
------------------------------
|
112 |
|
|
|
113 |
|
|
node stopwatch ( toggle, reset : bool ) returns ( count : int );
|
114 |
|
|
(*@contract import stopwatchSpec(toggle, reset ) returns (count) ; *)
|
115 |
|
|
var running : bool;
|
116 |
|
|
let
|
117 |
|
|
running = (false -> pre running) <> toggle ;
|
118 |
|
|
count =
|
119 |
|
|
if reset then 0
|
120 |
|
|
else if running then 1 -> pre count + 1
|
121 |
|
|
else 0 -> pre count ;
|
122 |
|
|
tel
|
123 |
|
|
|
124 |
|
|
|
125 |
|
|
|
126 |
|
|
|