% Load and link an external predicate that will, in turn, call the % GNU Scientific Library to calculate the CDF (ie, area under the curve) % of the unit Gaussian distribution. :- load("gsl/gsl.so"). :- external(gsl_std_normal_cdf/2, std_normal_cdf). % -------------------------------------------------------------------------- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Dispatch Control % Please see accompanied documentation for details % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Pick a local car at the nearest base or the nearest car on the road, % depends on how closer to the incident the nearest car is. % % Doesn't use a reward function. % proc(allocResManual(Duration), pi(t, ?(now(t)) : if( % Work time remains t < Duration, % THEN limit( queryAllCars(t) : if( % At least one region has a pending request, % and one of its local car is mobilizable some(region, some(x, some(y, some(anycar, isARegion(region) & validXCoord(region, x) & validYCoord(region, y) & requestPending(loc(x, y)) & isACar(anycar) & homeRegion(anycar, region) & ready(anycar) & carLocKnown(anycar, t))))), %THEN pi(region, pi(x, pi(y, pi(nCar, pi(nDist, pi(bDist, incidentLocation(region, x, y) : nearestMobilizableCar(region, x, y, nCar, nDist) : distanceToBase(region, x, y, bDist) : if( % Some cars at the base is mobilizable and, % the base is not very further away from the incident % compares to the nearest car some(car, isACar(car) & homeRegion(car, region) & atBase(car) & ready(car) & carLocKnown(car, t) & bDist - nDist =< 2 ), %THEN % Mobilize the car from the base pi(car, ?( isACar(car) & homeRegion(car, region) & atBase(car) & ready(car) & carLocKnown(car, t) ): mobilize(car, loc(x, y), t) ), %ELSE % Mobilize the nearest car mobilize(nCar, loc(x, y), t) ) )))))), %ELSE wait(t) ) ) : allocResManual(Duration), %ELSE noOp(t) ) ) ). % % Use the reward function to pick a car, anywhere in the city % proc(allocResAuto(Duration), pi(t, ?(now(t)) : if(t < Duration, % THEN limit( queryAllCars(t) : if( % Request is pending, and a car is mobilizable some(region, some(x, some(y, some(anycar, isARegion(region) & validXCoord(region, x) & validYCoord(region, y) & requestPending(loc(x, y)) & isACar(anycar) & ready(anycar) & carLocKnown(anycar, t) )))), % THEN pi(region, pi(x, pi(y, pi(rangeName, % Find where the incident is incidentLocation(region, x, y) : % Pick a car and mobilize it ?(range(all, rangeName)) : pickBest(bestCar, rangeName, mobilize(bestCar, loc(x, y), t)) )))), % ELSE wait(t) ) ) : allocResAuto(Duration), % ELSE noOp(t) ) ) ). /* --------------------------------------- */ % % Helper Procedures % proc(queryAllCars(Time), pi(rangeName, pi(carList, ?(carRange(all, rangeName)) : ?(range(rangeName, carList)) : limit(queryCars(carList, Time)) )) ). proc(queryCars(List, Time), if( nonEmptyList(List), % THEN pi(car, pi(otherCars, ?(firstCarInList(List, car, otherCars)) : if( % Car is ready but not mobilizable isACar(car) & ready(car) & -carLocKnown(car, Time) & -commLost(car), % THEN % Ask the dispatcher for its location pi(loc, askPosition(car, loc, Time) : queryCars(otherCars, Time) ), % ELSE queryCars(otherCars, Time) ) )), % ELSE noOp(Time) ) ). proc(incidentLocation(Region, X, Y), ?( isARegion(Region) & validXCoord(Region, X) & validYCoord(Region, Y) & requestPending(loc(X, Y)) ) ). proc(nearestMobilizableCar(Region, X, Y, NCar, NDist), pi(t, pi(nLoc, ?(now(t)) : ?( isACar(NCar) & homeRegion(NCar, Region) & ready(NCar) & carLocKnown(NCar, t) & carLocation(NCar, nLoc, t) & distance(nLoc, loc(X,Y), NDist) & all(otherCar, all(otherLoc, all(otherDist, ( ( isACar(otherCar) & homeRegion(otherCar, Region) & ready(otherCar) & -(otherCar=NCar) & carLocKnown(otherCar, t) & carLocation(otherCar, otherLoc, t) & distance(otherLoc, loc(X,Y), otherDist) ) => otherDist >= NDist) ))) ) )) ). proc(distanceToBase(Region, X, Y, BDist), pi(base, pi(bLoc, ?( isABase(base) & in(base, Region) & locOf(base, bLoc) & distance(loc(X,Y), bLoc, BDist) ) )) ).