----------------------------------------------------------------- -- 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. -- -- Verify these using "luke switch.lus --node ReqSwitch --verify" 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 ------------------------------------------------------------------ -- Temporal help nodes ------------------------------------------------------------------ -- Sofar(X) indicates if X has been true from the beginning of -- time or not node Sofar( X : bool ) returns ( Y : bool ); let Y = X and (true -> pre Y); tel ------------------------------------------------------------------ -- First(X) is a constant stream which has the value that X had -- in the first point in time. node First( X : int ) returns ( a : int ); let a = X -> pre a; tel ------------------------------------------------------------------ -- Since(X,Y) is true precisely when X has been true at some -- previous time point, and Y has been true since that time point. node Since( X, Y : bool ) returns ( SinceXY : bool ); let SinceXY = X or (Y and (false -> pre SinceXY)); tel ------------------------------------------------------------------ -- SinceIncl(X,Y) is true precisely when X has been true at some -- previous time point, and Y has been true since that time point, -- _including_ that time point. node SinceIncl( X, Y : bool ) returns ( SinceXY : bool ); let SinceXY = Y and (X or (false -> pre SinceXY)); tel