- Exercises in lecture notes on sets and relations (selected solutions)
- Exercises in lecture notes on an introduction to Alloy 4 - Part I
- Exercises in lecture notes on the academia model in Alloy
- Exercises in lecture notes on dynamic models in Alloy
Acknowledgements: This exercise is inspired by a similar assignment firstmade by Prover Technology AB, then adapted for previous versions of a similar course at Chalmers Universityby Carl Johan Lillieroth, K.V.S. Prasad, Mary Sheeran, Angela Wallenburg, andJan-Willem Roorda. The current version focuses more on simulation than some of the previous versions.
Consider a simple elevator, moving people up and down between two floors. A picture of the situation is shown on the right.
In the elevator, there are three buttons: a button 1 to go to the first floor, a button 2 to go to the first floor, and a stop switch to stop the elevator. On each floor, there is a button to call the elevator. Furthermore, the elevator has three sensors, the first indicating if the elevator is on the first floor or not, the second doing the same for the second floor, and the third indicating if the elevator's door is closed or not.
The stop switch is located within the elevator and can be turned on to block the elevator. While the switch is on the elevator stops immediately if it was moving and ignores any other input. Turning the switch back off makes the elevator to be responsive again to other inputs.
The elevator is moved up and down by a motor that is on the roof of the building. The motor is controlled by two signals, one for moving the elevator up and one for moving it down.
You are to implement the control system for this elevator. The control system looks at the buttons that are being pressed and the sensors that say where the elevator is and if the door is open, and then decides if the motor should move the elevator up or down, or do nothing.
For simplicity, we do not distinguish between the case of someone on floor 2 pressing the call button and someone in the elevator pressing the button 2. Similarly for the call button on floor 1 and button 1 in the elevator.
To understand better what the control system of the elevator is supposed to do, here is a list of safety requirements that any decent control system should satisfy.
|R1||The elevator moves only when the door is closed and the stop switch is not on.|
|R2||The elevator may not pass the end positions, that is, go through the roof or the floor.|
|R3||A moving elevator halts only if the stop switch is on, or the door is opened, or the elevator has arrived at the destination floor.|
|R4||The elevator halts before changing direction.|
|R5||The signals sent to the motor are not contradictory.|
|R6||The elevator starts moving when it should.|
If, during your implementation, you are ever in doubt about any issue not mentioned in the list above, you can make reasonable assumptions yourself.
Implement the control system as a Lustre node with the following interface:
node ElevatorController( Floor_1, Floor_2, DoorOpen, Call_1, Call_2, Stop : bool ) returns ( MotorUp, MotorDown : bool );
The Boolean streams Floor_1 and Floor_2 represent the output of the floor sensors. The value of stream Call_1 is true at time n if and only if someone has pressed the call button on floor 1 or the button 1 in the elevator. Similarly for Call_2. The stream DoorOpen is the output of the door sensor (true iff the elevator door is open). The stream Stop is the output of the stop switch. The output streams MotorUp and MotorDown represent the signals for the motor, to move the elevator up and down, respectively.
We want to simulate the system implemented by the control node. For that, it is helpful to introduce an auxiliary node that produces reasonable values for the sensors Floor_1 and Floor_2.
One possibility is to use a "environment" node like the following:
node Environment( MotorUp, MotorDown : bool ) returns ( Floor_1, Floor_2 : bool); var L: int; let L = 0 -> if pre MotorUp then (pre L) + 1 else if pre MotorDown then (pre L) - 1 else pre L; Floor_1 = L = 0; Floor_2 = L = 5; tel
In the definition above we make the assumptions at each tick of the system's clock lasts one second, and it takes the elevator 5 seconds to reach one floor from the other. So we can see it as going through 5 intermediate "levels" L when moving from one floor to the other.
Put together the two nodes Control and Environment, in a new node with (exactly) the following interface:
node Simulate( DoorOpen, Call_1, Call_2, Stop : bool) returns ( MotorUp, MotorDown : bool );
Use the Kind 2 web interface to run a simulator for your system and check visually if the safety requirements above hold. Look at the values returned by Simulate to see where the elevator is actually going.
Consider again the elevator problem in the previous exercise.
Define a synchronous observer node that expresses each of the safety requirements listed in the previous exercise. Your observer should have (exactly) the following interface:
node Requirements( Floor_1, Floor_2, DoorOpen, Call_1, Call_2, Stop: bool) returns ( R1, R2, R3, R4, R5, R6 : bool ) ;
Use Kind 2 to verify that the requirements hold. Modify the definition of the Control node as needed to satisfy all the requirements.
Note: The Environment and Simulate nodes are not to be used in this exercise.
Define a synchronous observer that formalizes the following requirement: "If the elevator is at a floor, someone presses the Call button on the other floor, no one turns the Stop switch on at the same time, and the door is closed, then the elevator will move."
What changes did you have to make to this requirement for it to go through?