-- the current value of Sum(X) is the sum of all values of X up to now node sum (X: int) returns (S: int); let S = X -> X + (pre S); tel (* 0 1 2 3 4 5 ... ------------------------------- X = 5, 3, -1, 2, 7, 8, ... S = 5, 8, 7, 9, 16, 24, ... *) -- the current value of even(N) is true iff -- the current value of N is even node even(N: int) returns (B:bool); let B = (N mod 2 = 0); tel -- EvensFrom(X) contains, in increasing order, -- all even numbers greater than the first value of X node even1 (X: int) returns (E: int); let E = (if even(X) then X + 2 else X + 1) -> (pre E) + 2; tel -- s(_) = 1,2,3,3,3,3,... -- note: input is irrelevant node s (_: bool) returns (X: int); let X = 1 -> if (pre X) < 3 then (pre X) + 1 else 3 ; tel -- more compact version of s node s1 (_: bool) returns (X: int); let X = 1 -> pre (2 -> 3); tel -- (2 -> 3) = 2, 3, 3, 3, ... -- pre (2 -> 3) = //, 2, 3, 3, ... -- X = 1, 2, 3, 3, ... -- observer node that returns true iff s(B) is the same as s1(B) node obs_s(B: bool) returns (OK: bool); let OK = (s(B) = s1(B)); tel -- Y = 2, 3, 3, 3, 3, 3, 3, ... -- pre Y = //, 2, 3, 3, ... -- X = 1, 2, 3, 3, 3, 3, ... -- switch(On,Off) is initially false and -- raises (false to true) if On is true, and -- falls (true to false) if Off is true node switch( On,Off: bool) returns (S: bool); let -- very verbose definition -- S = false -> if On=true then true else if Off=true then false else pre S; -- less verbose definition -- S = false -> if (pre S) = false then On else not Off; -- better definition S = S = false -> if (pre S) then not Off else On; tel -- At each cycle n >= 0, fact(_) = n! -- where 0! = 1 -- n! = n * (n-1)! node fact(_: bool) returns (F: int); var N: int; let N = 0 -> (pre N) + 1; -- counts the cycles F = 1 -> N * (pre F); tel node First(X:int) returns (FX:int); let FX = X -> pre FX; tel -- counter(X, Reset) starts at X and keeps increasing by 1 -- until Reset is true, in which case it goes to the initial value -- of X and restarts node counter( X: int; Reset: bool) returns (C: int); let C = if Reset then First(X) else (X -> (pre C) + 1); tel node N(I, X: int) returns (Z: int); let Z = if I > 0 then I + 2 else I + X; tel -- prove that the node N above ignores its second input X -- if I is alway positive node ReqN(I, X1, X2: int) returns (P: bool); let -- constrain I to be always positive -- but let X1 and X2 be arbitrary (and arbitrarily different) assert I > 0; -- P holds iff for arbitrarily different second inputs N still returns -- the same output P = N(I,X1) = N(I,X2); -- %MAIN -- %PROPERTY P; tel -- What happens if you remove the assert statement? ------------------------------------------------------------------ -- Sofar(X) is true at any point iff X has been true from -- the beginning until that point node Sofar( X : bool ) returns ( Y : bool ); let Y = X -> (X and (pre Y)); tel --------------------------------------------------------- -- Since(X,Y) is true precisely when X has been true -- at some point, and Y has been continuously true -- afterwards node Since( X, Y : bool ) returns ( SinceXY : bool ); let SinceXY = X or (Y and (false -> pre SinceXY)); tel -- SinceXY = X or (Y and (false -> pre SinceXY)); ------------------------------------------------------------------ -- SinceIncl(X,Y) is true iff X has been true at some point, -- and Y has been continuously true from then on. -- node SinceIncl( X, Y : bool ) returns ( SinceXY : bool ); --let --tel -- SinceXY = Y and (X or (false -> pre SinceXY)); ----------------------------------------------------------------- -- Boolean Switch -- -- Model a switch with two buttons, Set and Reset. -- Pressing Set turns the switch on. -- Pressing Reset turns the switch off -- If Set and Reset are initially both unpressed, -- the initial position of the switch is determined by -- a third signal, Init 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 node Switch3( Set, Reset, Init : bool ) returns ( X : bool ); let X = Set or (not Reset and (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 turns the switch on R1 = Set => X; -- resetting turns the switch off R2 = Reset => not X; -- doing nothing maintains the previous value R3 = true -> (not Set and not Reset) => X = pre X; -- %MAIN -- %PROPERTY R1; -- %PROPERTY R2; -- %PROPERTY R3; tel -- R1 = (Set => X); -- not Set or X; -- R2 = (not Set and Reset) => not X; -- R3 = true -> ((not Set and not Reset) => X = pre X); ----------------------------------------------------------------- -- 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" -- 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 = Sofar(not (Set and Reset)) => (X = X2); --%MAIN --%PROPERTY OK; tel (* (* -- OK = not (Set and Reset) => X = X2; OK = Sofar(not (Set and Reset)) => X = X2; tel *) ----------------------------------------------------------------- -- 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, Reset, Reset2, Init : bool ) returns ( OK : bool ); let OK = true; -- OK = Set => Switch(Set, Reset, Init) = -- Switch(Set, Reset2, Init); tel ----------------------------------------------------------------- -- Now, we would like to prove that: -- -- R1 - "if the switch is on, -- it stays so until the next reset" -- -- R2 - "if the switch is off, it stays so until the next set" -- -- Equivalently: -- -- R1 - "if we did not reset since the last time we set, -- X is true" -- R2 - "if we did not set since the last time we reset, -- X is false" (* node ReqSwitchSetIgnoresReset( Set, Reset, Init : bool ) returns ( R1, R2 : bool ); var X : bool; let X = Switch( Set, Reset, Init ); -- "if we did not reset since the last time we set, -- X is true" R1 = -- "if we did not set since the last time we reset, -- X is false" -- R2 = tel *) -- R1 = Since( Set, not Reset ) => X; -- R2 = Since( Reset and not Set, not Set ) => not X; -- ooo -- ------------------==------------------- -- == -- == -- ------------------==------------------- -- ooo node TrafficLight( Button : bool ) returns ( Red, Yellow, Green, Walk, DontWalk : bool ); var Phase, prePhase : int; let prePhase = 0 -> pre Phase; Phase = if Button then 1 else if 0 < prePhase and prePhase < 10 then prePhase + 1 else 0; Green = Phase = 0; Yellow = Phase = 1; Red = Phase > 1; Walk = 2 < Phase and Phase < 10; DontWalk = not Walk; tel (* node ReqTrafficLight( Button : bool ) returns (R1, R2, R3, R4, R5, R6, R7, R8, R9, R10: bool); var CarsAllowed, Red, Yellow, Green, Walk, DontWalk : bool; let (Red, Yellow, Green, Walk, DontWalk) = TrafficLight(Button); -- R1: Walk is never on when cars are allowed -- R2: Red and Green are never on at the same time -- R3: at all times one of the tree colored lights is on -- R4: Walk is on only if Red is -- R5: Walk if on iff DontWalk is off -- R6: Red cannot immediately follow Green -- R7: Walk is off if cars were allowed in the previous step -- R8: Cars are not allowed if Walk was on in the previous step -- R9: Yellow is on for at most one step -- R10: Red changes directly to green -- R11: If the button was never pressed the light is Green -- R12: Red is on whenever Walk is -- R13: Yellow can only follow Green -- R14: Pushing the button when Walk is on has immediate effect -- R15: Red is on for at most 9 cycles -- R16: When Red turn on, Walk is still off tel *) (* CarsAllowed = Green or Yellow; R1 = not (CarsAllowed and Walk); R2 = not (Red and Green); R3 = Red or Yellow or Green; R4 = Walk => Red; R5 = Walk xor DontWalk; R6 = true -> not (Red and pre Green); R7 = true -> not (Walk and pre CarsAllowed); R8 = true -> not (CarsAllowed and pre Walk); R9 = true -> not (Yellow and pre Yellow); R10 = true -> (pre Red and not Red) => Green; tel Phase = if Button and (false -> pre DontWalk) then Phase = if Button and (false -> pre DontWalk) and prePhase = 0 node ParallelCounters (a, b, c: bool) returns (x, y: int); var n1,n2: int; let n1 = 10; n2 = 5; x = 0 -> if (b or c) then 0 else if a and (pre x) < n1 then (pre x) + 1 else pre x; y = 0 -> if c then 0 else if a and (pre y) < n2 then (pre y) + 1 else pre y; -- Properties -- 1) Whenever x reaches n1, y reaches n2 tel ----------------------------------------------------------------- --node IgnoresFirstInput(X, Y, V: int) return(R1: bool); --let -- R1 = N(X, Y) = N(X, V); --tel ----------------------------------------------------------------- -- an integer switch -- -- Model an integer switch with a button and an -- integer input X. -- When the button is pressed the switch takes the value of X -- and maintains it until the next time the button is pressed -- again. -- Before the button is pressed for the first time, the value of -- X is 0. node SwitchInt( Set : bool; X : int ) returns ( Y : int ); let Y = if Set then X else (0 -> pre Y); tel ----------------------------------------------------------------- -- Prove that: -- -- "the SwitchInt node ignores its integer input X -- when the input Set is false" node SwitchIgnoresX( Set : bool; X1, X2: int ) returns ( OK : bool ); var Env : bool; let Env = not Set; OK = Env => SwitchInt(Set, X1) = SwitchInt(Set, X2); -- Env = Sofar(Set => X1 = X2); -- OK = Env => SwitchInt(Set,X1) = SwitchInt(Set,X2); tel ----------------------------------------------------------------- -- Prove that: -- -- "Y always has the latest set value of X" -- -- Let us first do a simple version of this: -- -- "If we have not set the switch again since the last time -- the switch was set to 3, then Y must be 3" node ReqSwitchInt_Simple( Set : bool; X : int ) returns ( OK : bool ); var Y : int; let Y = SwitchInt( Set, X ); OK = Since(Set and X = 3, not Set) => Y = 3; tel ----------------------------------------------------------------- -- To prove that: -- -- "Y always has the latest set value of X" -- -- Equivalently, -- -- "For all values a, -- if we have not set the switch again since the last time -- the switch was set to a, then Y must be a" -- node ReqSwitchInt( Set : bool; X : int; A : int ) returns ( OK : bool ); var Y : int; a : int; let a = First( A ); Y = SwitchInt( Set, X ); OK = Since( Set and X = a, not Set ) => Y = a; tel -- HasHappened(X) is true precisely when X has been true -- at least once since the first instant node HasHappened(X : bool) returns (Y : bool); let Y = X or (false -> pre Y); tel ---------------------------------------------------- -- Write an observer that checks the following -- for an integer input stream Y: -- Whenever Y has the positive value x, -- its opposite -x has occurred in Y before -- x is the first value of an additional -- input stream X node NegBefore(Y: int; X : int) returns (OK : bool); var x : int; let x = First(X); OK = (Y = x and x > 0) => HasHappened(Y = -x); tel -- write a simulator for NegBefore, -- a node that feeds to NegBefore a suitable streams -- for Y and X -- We write a node G whose output Y cycles through [-3..3] -- if its integer input X is initially even, and -- cycles through [0..3] otherwise. node Even(X: int) returns (Y: bool); let Y = 2*(X div 2) = X; tel node G(X: int) returns(Y : int); var preY, lb : int; let lb = if Even(First(X)) then -4 else -1; preY = lb -> pre Y; Y = if preY < 3 then preY + 1 else lb + 1; tel node Simul(X: int) returns (OK: bool); var Y: int; let Y = G(X); OK = NegBefore(Y, X); tel *) ----------------------------------------------------------------- -- Show that -- P1 - (Sofar(X) and Sofar(Y)) is equivalent to -- Sofar(X and Y) for all Boolean streams X and Y. -- -- P2 - (Sofar(X) or Sofar(Y)) is equivalent to -- Sofar(X or Y) for all Boolean streams X and Y. node SofarObs (X, Y: bool) returns (P2: bool); let P2 = (Sofar(X) or Sofar(Y)) = Sofar(X or Y); tel *)