% This program creates a schedule of feasible start and end times for each % train on a route track. The schedule is based on the given route of the % train and the planned stay of a train on the track. % Execution of this program: ezcsp --bprolog --grounder gringo-3.0.5 % --solver clasp-3.0.5 scheduling.enc.ez % definition of finite domain cspdomain(fd). % define overlapping time for each train on subsequent tracks #const overlappingTime = 1. % define csp variables begin and end of a train on a track cspvar(solved_schedule_begin(TRAIN,TRACK),MINTIME,MAXTIME) :- route_next(TRAIN,TRACK,TRACKNEXT), maxTime(MAXTIME), minTime(MINTIME). cspvar(solved_schedule_end(TRAIN,TRACK),MINTIME,MAXTIME) :- route_next(TRAIN,TRACK,TRACKNEXT), maxTime(MAXTIME), minTime(MINTIME). % define also for last track cspvar(solved_schedule_begin(TRAIN,TRACKNEXT),MINTIME,MAXTIME) :- route_next(TRAIN,TRACK,TRACKNEXT), route_last(TRAIN,TRACKNEXT), maxTime(MAXTIME), minTime(MINTIME). cspvar(solved_schedule_end(TRAIN,TRACKNEXT),MINTIME,MAXTIME) :- route_next(TRAIN,TRACK,TRACKNEXT), route_last(TRAIN,TRACKNEXT), maxTime(MAXTIME), minTime(MINTIME). % begin of next track has to be end-1 of previous track required(solved_schedule_begin(TRAIN,TRACK) == (solved_schedule_end(TRAIN,TRACKPREV) - overlappingTime)) :- route_next(TRAIN,TRACKPREV,TRACK). % end of time on a track is begin + time on track required(solved_schedule_end(TRAIN,TRACK) == (solved_schedule_begin(TRAIN,TRACK) + OCCUPATION)) :- route_track(TRAIN,TRACK), train_trackoccupation(TRAIN,TRACK,OCCUPATION). % derive which tracks are in a route of a train route_track(TRAIN,TRACK) :- route_next(TRAIN,TRACK,TRACKNEXT). route_track(TRAIN,TRACK) :- route_last(TRAIN,TRACK). % two trains cannot be on the same track at the same time required((solved_schedule_begin(TRAIN2,TRACK) >= solved_schedule_end(TRAIN1,TRACK)) \/ (solved_schedule_begin(TRAIN1,TRACK) >= solved_schedule_end(TRAIN2,TRACK))) :- train(TRAIN1), train(TRAIN2), TRAIN1 != TRAIN2, route_track(TRAIN1,TRACK), route_track(TRAIN2,TRACK). % defines how long a train (normally) occupies a track train_trackoccupation(TRAIN,TRACK,OCCUPATION):- train_timeontrack(TRAIN,TRACK,DURATION), train_stay(TRAIN,STATION,STAY), OCCUPATION=DURATION+STAY, station_tracks(STATION,TRACK). % instead of using default negation in next rule, derive station tracks track_of_station(TRACK) :- station_tracks(STATION,TRACK). train_trackoccupation(TRAIN,TRACK,OCCUPATION):- train_timeontrack(TRAIN,TRACK,OCCUPATION), % not station_tracks(STATION,TRACK) : station_tracks(STATION,TRACK). not track_of_station(TRACK).