Sequential Elevator (1)
package Elevator is
procedure Controller;
-- the range of the floors in the building
NumberFloors : constant Integer := 5;
type FloorNumber is new Integer range 1..NumberFloors;
type FloorList is array(FloorNumber) of Boolean;
-- the direction of moving
type DirectionType is (up, down);
-- just stubs for the calls made by the controller
function GetActionId return Integer;
function NewDestination return FloorNumber;
function Approaching return FloorNumber;
function GetCallFloor return FloorNumber;
function StoppedAt return FloorNumber;
function CarReady return FloorNumber;
function CarReadyEmpty return FloorNumber;
function IsDestination(Floor : FloorNumber) return Boolean;
function IsInCallsup(Floor : FloorNumber) return Boolean;
function IsInCallsdown(Floor : FloorNumber) return Boolean;
function ThereAreRequestsAbove(Floor : FloorNumber) return Boolean;
procedure CarStop;
procedure CarContinue;
procedure CarDoorOpen;
procedure CarDoorClose;
procedure CarMoveup;
procedure CarMovedown;
end Elevator;
package body Elevator is
procedure CarStop is
begin
null; --event[{ordered_to_stop}]
null;
end CarStop;
procedure CarDoorOpen is
begin
null; -- event[{open_doors}]
null;
end CarDoorOpen;
procedure CarDoorClose is
begin
null; -- event[{close_doors}]
null;
end CarDoorClose;
procedure CarMoveup is
begin
null; --event[{ordered_to_move}]
null; --event[{ordered_to_move_up}]
null;
end CarMoveup;
procedure CarMovedown is
begin
null; --event[{ordered_to_move}]
null; --event[{ordered_to_move_down}]
null;
end CarMovedown;
procedure Controller is
Callsup, Callsdown, Stops : FloorList;
PeoplePresent : Boolean := False;
DirectionUP : boolean;
Signal : Integer;
Floor : FloorNumber;
Dummy : Boolean := False;
begin
DirectionUP := true; --event[{directionup=t}]
loop
-- obtain a random number that is supposed to model obtaining the
-- code for a particular real-time event
Signal := GetActionId;
case Signal is
when 1 =>
-- someone pushed the call up button on one of the floors
Floor := GetCallFloor;
-- enter the floor in the list of calls up
Callsup(Floor) := True;
when 2 =>
-- someone pushed the call up button on one of the floors
Floor := GetCallFloor;
-- enter the floor in the list of calls up
Callsdown(Floor) := True;
when 3 =>
-- the car is approaching a certain floor
Floor := Approaching; --event[{reporting_approach}]
-- stop there only if this floor was requested as a destination
-- by one of the people in the car or has a person waiting who
-- is going in the direction the car is currently going
if IsDestination(Floor) or
((DirectionUP) and then IsInCallsup(Floor)) or
((not DirectionUP) and then IsInCallsdown(Floor)) then
CarStop;
null;
-- also stop if the floor is the top or first floor
elsif ((DirectionUP) and then (Floor = FloorNumber'last)) or
((not DirectionUP) and then (Floor = FloorNumber'first)) then
CarStop;
null;
else
CarContinue;
end if;
when 4 =>
-- the car has stopped at a certain floor
Floor := StoppedAt; --event[{not_moving}]
-- open the doors
CarDoorOpen;
-- no more people should be waiting for this car on this floor
if DirectionUP then
Callsup(Floor) := False;
else
Callsdown(Floor) := False;
end if;
-- set the direction to up if the car is on the first floor and
-- to down if it is on the top floor
if Floor = FloorNumber'First then
DirectionUP := true; --event[{directionup=t}]
null;
end if;
if Floor = FloorNumber'Last then
DirectionUP := false; --event[{directionup=f}]
null;
end if;
when 5 =>
-- the car is ready to move (people are not standing in the
-- doors)
Floor := CarReady;
-- all people who wanted should have exited by now
Stops(Floor) := False;
-- close the doors
CarDoorClose;
-- move the car in the same direction unless there are no
-- desired destinations in that direction
if (DirectionUP) then
null; --event[{directionupis=t}]
if ThereAreRequestsAbove(Floor) then
CarMoveup;
else
DirectionUP := false; --event[{directionup=f}]
CarMovedown;
end if;
else
null; --event[{directionupis=f}]
CarMovedown;
end if;
when 6 =>
-- someone pushed a button while in the car
Floor := NewDestination;
Stops(Floor) := True;
when 7 =>
-- the car is open and empty
Floor := CarReadyEmpty;
-- clear all the stops now because there's nobody in the car
for I in FloorNumber loop
Stops(I) := False;
end loop;
-- this line is added only for the benefit of FLAVERS, in
-- general the controller does not have to be terminating
-- the exit from the loop may only occur here, when there are
-- no people in the car and the doors are open
exit when Dummy;
CarDoorClose;
-- of course it's unfair, but start moving to the first floor
CarMovedown;
when others =>
null;
end case;
end loop;
CarDoorClose;
end Controller;
begin
Controller;
end Elevator;