```------------------------------------------------------------------
-- Auxiliary Temporal operators
------------------------------------------------------------------

node Sofar( X : bool )
returns ( Y : bool );
let
Y = X and (true -> pre Y);
tel

node First( X : int )
returns ( a : int );
let
a = X -> pre a;
tel

node Since( X, Y : bool )
returns ( SinceXY : bool );
let
SinceXY = X or (Y and (false -> pre SinceXY));
tel

node SinceIncl( X, Y : bool )
returns ( SinceXY : bool );
let
SinceXY = Y and (X or (false -> pre SinceXY));
tel

-----------------------------------------------------------------
-- two Boolean switch implementations

node Switch( Set, Reset, Init : bool )
returns ( X : bool );
let
X = if Set then true else
if Reset then false else
(Init -> pre(X));
tel

node Switch2( Set, Reset, Init : bool )
returns ( X : bool );
let
X = if Reset then false else
if Set then true else
(Init -> pre(X));
tel

------------------------------------------------------------------
-- The following observer expresses 3 safety requirements
-- for the first switch.
--
node ReqSwitch( Set, Reset, Init : bool )
returns ( R1, R2, R3 : bool );
var X : bool;
let
X = Switch( Set, Reset, Init );

-- setting makes true
R1 = Set => X;  -- not Set or X;

-- resetting makes false
R2 = not Set and Reset => not X;

-- doing nothing keeps
R3 = true -> ((not Set and not Reset) => X = pre X);
tel

-- Note that the condition in R2 included "not Set".
-- Check what happens when you take it away!

-----------------------------------------------------------------
-- We would like to prove that:
--
--   "if Set and Reset are never true at the same time,
--    then Switch and Switch2 behave in the same way"
--
-- Try to verify it and see what happens!

node ReqSwitches( Set, Reset, Init : bool )
returns ( OK : bool );
var X, X2 : bool;
let
X  = Switch ( Set, Reset, Init );
X2 = Switch2( Set, Reset, Init );

OK = not (Set and Reset) => X = X2;  -- wrong!
tel

-- We need to make a stronger assumption, namely that Set and Reset
-- never have been true at the same time *up to this point*. We can
-- do this using the temporal combinator Sofar:
--
--  OK = Sofar(not (Set and Reset)) => X = X2;
--

-----------------------------------------------------------------
-- By adding an extra input to the observer, we can show that
--
--  "the Switch node ignores its input Reset when the
--   input Set is true"
--
-- ("Ignoring" means that the behavior of Switch is exactly the
--  same, independent of the value of Reset when Set is true.)
--

node SwitchIgnoresReset( Set, Reset1, Reset2, Init : bool )
returns ( OK : bool );
var Env : bool;
let

Env = Set;
-- another option would be:
--   Env = Sofar(not Set => Reset1 = Reset2);

OK  = Env =>
Switch(Set,Reset1,Init) = Switch(Set,Reset2,Init);
tel

-----------------------------------------------------------------
-- Now, we would like to prove that:
--
--   "if since the last time we set, we have not reset,
--   X is true"
--
-- and
--
--   "if since the last time we reset, we have not set,
--   X is false"
--
-- We can do this using the temporal combinator Since.

node ReqSwitchSetIgnoresReset( Set, Reset, Init : bool )
returns ( R1, R2 : bool );
var X : bool;
let
X = Switch( Set, Reset, Init );

-- "if since the last time we set, we have not reset,
-- X is true"
R1 = Since( Set, not Reset ) => X;

-- "if since the last time we reset, we have not set,
-- X is false"
R2 = Since( Reset and not Set, not Set ) => not X;
tel

```