1
|
-------------------------
|
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
|
|
49
|
-- integrated in the node
|
50
|
|
51
|
------------------------------
|
52
|
-- Stopwatch low-level spec --
|
53
|
------------------------------
|
54
|
|
55
|
node stopwatch ( toggle, reset : bool ) returns ( time : int );
|
56
|
(*@contract
|
57
|
-- the watch is activated initially if the toggle button is pressed
|
58
|
-- afterwards, it is activated iff
|
59
|
-- it was activated before and the toggle button is unpressed or
|
60
|
-- it was not activated before and the toggle button is pressed
|
61
|
var on: bool = toggle -> (pre on and not toggle)
|
62
|
or (not pre on and toggle) ;
|
63
|
|
64
|
-- we can assume that the two buttons are never pressed together
|
65
|
assume not (toggle and reset) ;
|
66
|
|
67
|
-- the elapsed time starts at 1 or 0 depending
|
68
|
-- on whether the watch is activated or not
|
69
|
guarantee (on => time = 1) -> true ;
|
70
|
guarantee (not on => time = 0) -> true ;
|
71
|
-- the elapsed time is always non-negative
|
72
|
guarantee time >= 0 ;
|
73
|
|
74
|
-- if there is no reset now and there was an even number of counts since the last reset
|
75
|
-- then the current elapsed time is the same as the previous one
|
76
|
var even_count:bool = Even(Count(toggle));
|
77
|
guarantee not reset and Since(reset, even_count)
|
78
|
=> Stable(time) ;
|
79
|
-- if there is no reset now and there was an odd number of counts since the last reset
|
80
|
-- then the current elapsed time is greater than previous one
|
81
|
guarantee (not reset) and Since(reset, not even_count) => Increased(time) ;
|
82
|
|
83
|
|
84
|
-- guarantee true -> not Even(Count(toggle)) and Count(reset) = 0 => time > pre time ;
|
85
|
|
86
|
|
87
|
-- the watch is in resetting mode if the reset button is pressed
|
88
|
-- while in that mode, the elapsed time is 0
|
89
|
mode resetting (
|
90
|
require reset ;
|
91
|
ensure time = 0 ;
|
92
|
) ;
|
93
|
|
94
|
-- the watch is in running mode if is activated and
|
95
|
-- the reset button is unpressed.
|
96
|
-- while in that mode, the elapsed time increases by 1
|
97
|
mode running (
|
98
|
require on ;
|
99
|
require not reset ;
|
100
|
ensure true -> time = pre time + 1 ;
|
101
|
) ;
|
102
|
|
103
|
-- the watch is in stopped mode if is not activated and
|
104
|
-- the reset button is unpressed
|
105
|
-- while in that mode, the elapsed time remains the same
|
106
|
mode stopped (
|
107
|
require not reset ;
|
108
|
require not on ;
|
109
|
ensure true -> time = pre time ;
|
110
|
) ;
|
111
|
|
112
|
|
113
|
|
114
|
*)
|
115
|
var running : bool;
|
116
|
let
|
117
|
running = (false -> pre running) <> toggle ;
|
118
|
time =
|
119
|
if reset then 0
|
120
|
else if running then 1 -> pre time + 1
|
121
|
else 0 -> pre time ;
|
122
|
tel
|
123
|
|
124
|
|
125
|
|
126
|
|
127
|
|