================================================================= 22c:181 Formal Methods in Software Engineering, Spring 2008 Exercise 3 Solutions ================================================================= 1. Let's use The main issues here are that: - the elevator has to continue moving in one direction, even if no button is pressed; - it has to stop moving once a floor is reached, or if Stop is pressed or the door is opened; - it cannot immediately change direction; - the contradictory events Call_1, Call_2 are possible. node Control( Floor_1, Floor_2, Door_Closed, Call_1, Call_2, Stop : bool ) returns ( Motor_Up, Motor_Down : bool); var CanMove : bool; let CanMove = not Stop and not Door_Closed ; Motor_Up = CanMove and not Floor_2 and ((false -> pre Motor_Up) or Call_2) and not (false -> pre Motor_Down) and not Motor_Down; Motor_Down = CanMove and not Floor_1 and ((false -> pre Motor_Down) or Call_1) and not (false -> pre Motor_Up); tel 2. node Environment( Motor_Up, Motor_Down : bool ) returns ( Floor_1, Floor_2 : bool ); var L : int; let L = 0 -> if pre(Motor_Up) then pre(L) + 1 else if pre(Motor_Down) then pre(L) - 1 else pre(L); Floor_1 = L = 0; Floor_2 = L = 6; tel node Simulate( Door_Closed, Call_1, Call_2, Stop : bool ) returns ( Motor_Up, Motor_Down : bool ); var Floor_1, Floor_2 : bool; let (Motor_Up, Motor_Down) = Control(Floor_1, Floor_2, Door_Closed, Call_1, Call_2, Stop); (Floor_1, Floor_2) = Environment(Motor_Up, Motor_Down); tel The apparent circularity of the Simulate node constraint may be a bit baffling: Motor_Up, Motor_Down are defined (also) in terms of Floor_1, Floor_2; in turn, Floor_1, Floor_2 are defined in terms of Motor_Up, Motor_Down. Note however that there is no circularity here. At time 0, the value of Floor_1, Floor_2 computed by Environment is independent from the value of Motor_Up, Motor_Down. At later times, it depends of the *previous* value of Motor_Up, Motor_Down.