Gas Station With No Queueing (2)
procedure gas;
procedure gas is
N : constant natural := 2; -- number of customers
type cust_range is range 0 .. N;
type pump_range is range 1 .. 2; -- two pumps
task operator is
entry prepay_1_pump_1;
entry prepay_1_pump_2;
entry prepay_2_pump_1;
entry prepay_2_pump_2;
entry charge_1_pump_1;
entry charge_2_pump_1;
entry charge_1_pump_2;
entry charge_2_pump_2;
end operator;
task pump_1 is
entry activate;
entry start_pumping;
entry stop_pumping_1;
entry stop_pumping_2;
end pump_1;
task pump_2 is
entry activate;
entry start_pumping;
entry stop_pumping_1;
entry stop_pumping_2;
end pump_2;
task customer_1 is
entry change;
end customer_1;
task customer_2 is
entry change;
end customer_2;
task body operator is
Pump_1_ActiveCustomers : cust_range;
Pump_2_ActiveCustomers : cust_range;
done : boolean;
begin -- Operator
Pump_1_ActiveCustomers := 0; --event[{p1ac=0}]
Pump_2_ActiveCustomers := 0; --event[{p2ac=0}]
null;
-- infinite loop
loop
select
-- can accept a prepayment from customer 1 for pump 1
accept prepay_1_pump_1 do
-- check for this as the first customer
if Pump_1_ActiveCustomers = 0 then
-- activate the pump
gas.pump_1.activate; --eventb[{p1acis=0}]
null;
end if;
-- increment the number of active customers on pump 1
Pump_1_ActiveCustomers :=
Pump_1_ActiveCustomers + 1; --event[{p1acinc}]
null;
end prepay_1_pump_1;
or
-- can accept a prepayment from customer 1 for pump 2
accept prepay_1_pump_2 do
-- check for this as the first customer for pump 2
if Pump_2_ActiveCustomers = 0 then
-- activate the pump
gas.pump_2.activate; --eventb[{p2acis=0}]
null;
end if;
-- increment the number of active customers on pump 2
Pump_2_ActiveCustomers :=
Pump_2_ActiveCustomers + 1; --event[{p2acinc}]
null;
end prepay_1_pump_2;
or
-- can accept a prepayment from customer 2 for pump 1
accept prepay_2_pump_1 do
-- check for this as the first customer for pump 1
if Pump_1_ActiveCustomers = 0 then
-- activate the pump
gas.pump_1.activate; --eventb[{p1acis=0}]
null;
end if;
-- increment the number of active customers on pump 1
Pump_1_ActiveCustomers :=
Pump_1_ActiveCustomers + 1; --event[{p1acinc}]
null;
end prepay_2_pump_1;
or
-- can accept a prepayment from customer 2 for pump 2
accept prepay_2_pump_2 do
-- check for this as the first customer for pump 2
if Pump_2_ActiveCustomers = 0 then
-- activate the pump
gas.pump_2.activate; --eventb[{p2acis=0}]
null;
end if;
-- increment the number of active customers on pump 2
Pump_2_ActiveCustomers :=
Pump_2_ActiveCustomers + 1; --event[{p2acinc}]
null;
end prepay_2_pump_2;
or
-- can accept charge for customer_1 from pump 1
accept charge_1_pump_1;
-- decrement number of active customers on pump 1
Pump_1_ActiveCustomers :=
Pump_1_ActiveCustomers - 1; --event[{p1acdec}]
null;
-- check for more customers
if Pump_1_ActiveCustomers > 0 then
-- more customers, so activate pump again
gas.pump_1.activate; --eventb[{p1acis>0}]
null;
end if;
-- give change to customer 1
gas.customer_1.change; --eventb[{cust_1_pump_1_change}]
null;
or
-- can accept charge for customer_1 from the pump 2
accept charge_1_pump_2;
-- decrement number of active customers on pump 2
Pump_2_ActiveCustomers :=
Pump_2_ActiveCustomers - 1; --event[{p2acdec}]
null;
-- check for more customers
if Pump_2_ActiveCustomers > 0 then
-- more customers, so activate pump again
gas.pump_2.activate; --eventb[{p2acis>0}]
null;
end if;
-- give change to customer 1
gas.customer_1.change; --eventb[{cust_1_pump_2_change}]
null;
or
-- can accept charge for customer_2 from pump 1
accept charge_2_pump_1;
-- decrement number of active customers on pump 1
Pump_1_ActiveCustomers :=
Pump_1_ActiveCustomers - 1; --event[{p1acdec}]
null;
-- check for more customers
if Pump_1_ActiveCustomers > 0 then
-- more customers, so activate pump again
gas.pump_1.activate; --eventb[{p1acis>0}]
null;
end if;
-- give change to customer 2
gas.customer_2.change;
or
-- can accept charge for customer_2 from the pump 2
accept charge_2_pump_2;
-- decrement number of active customers on pump 2
Pump_2_ActiveCustomers :=
Pump_2_ActiveCustomers - 1; --event[{p2acdec}]
null;
-- check for more customers
if Pump_2_ActiveCustomers > 0 then
-- more customers, so activate pump again
gas.pump_2.activate; --eventb[{p2acis>0}]
null;
end if;
-- give change to customer 2
gas.customer_2.change;
end select;
exit when done;
end loop;
end operator;
task body pump_1 is
done : boolean;
begin -- Pump
-- infinite loop
loop
accept activate;
accept start_pumping;
select
accept stop_pumping_1 do
gas.operator.charge_1_pump_1;
end stop_pumping_1;
or
accept stop_pumping_2 do
gas.operator.charge_2_pump_1;
end stop_pumping_2;
end select;
exit when done;
end loop;
end pump_1;
task body pump_2 is
done : boolean;
begin -- Pump
-- infinite loop
loop
accept activate;
accept start_pumping;
select
accept stop_pumping_1 do
gas.operator.charge_1_pump_2;
end stop_pumping_1;
or
accept stop_pumping_2 do
gas.operator.charge_2_pump_2;
end stop_pumping_2;
end select;
exit when done;
end loop;
end pump_2;
task body customer_1 is
done : boolean;
begin -- Customer_1
-- infinite loop
loop
-- either pump on pump 1 or pump 2
select
gas.operator.prepay_1_pump_1;
gas.pump_1.start_pumping; --event[{cust_1_start_pumping}]
gas.pump_1.stop_pumping_1; --eventb[{cust_1_stop_pumping}]
null;
else
gas.operator.prepay_1_pump_2;
gas.pump_2.start_pumping;
gas.pump_2.stop_pumping_1;
end select;
accept change;
exit when done;
end loop;
end customer_1;
task body customer_2 is
done : boolean;
begin -- Customer_2
-- infinite loop
loop
-- either pump on pump 1 or pump 2
select
gas.operator.prepay_2_pump_1;
gas.pump_1.start_pumping; --event[{cust_2_start_pumping}]
gas.pump_1.stop_pumping_2; --eventb[{cust_2_stop_pumping}]
null;
else
gas.operator.prepay_2_pump_2;
gas.pump_2.start_pumping;
gas.pump_2.stop_pumping_2;
end select;
accept change;
exit when done;
end loop;
end customer_2;
begin
null;
end gas;