/* * Naam : R. Wacanno * UvAnetID : 11741163 * Studie : BSc Informatica * * solution4.pl * -Contains the solution to opdracht 4. */ :- op(100, xfx, at). :- op(50, xfx, :). route([ "Amsterdam Centraal" at 11:08, "Amsterdam Amstel" at 11:15, "Utrecht Centraal" at 11:38, "Den Bosch" at 12:08, "Eindhoven" at 12:32, "Weert" at 12:49, "Roermond" at 13:02, "Sittard" at 13:21, "Maastricht" at 13:35 ]). route([ "Amsterdam Centraal" at 11:38, "Amsterdam Amstel" at 11:45, "Utrecht Centraal" at 12:08, "Den Bosch" at 12:38, "Eindhoven" at 13:02, "Weert" at 13:19, "Roetmond" at 13:32, "Sittard" at 13:51, "Maastricht" at 14:05 ]). route([ "Amsterdam Science Park" at 11:10, "Amsterdam Centraal" at 11:20 ]). route([ "Enkhuizen" at 9:39, "Bovenkarspel Flora" at 9:43, "Bovenkarspel Grootebroek" at 9:47, "Hoogkarspel" at 9:52, "Hoorn Kersenboogerd" at 9:59, "Hoorn" at 10:10, "Amsterdam Sloterdijk" at 10:36, "Amsterdam Centraal" at 10:45 ]). /* True if Minutes is the difference in minutes between time 1 and 2*/ diffTime(H1:M1, H2:M2, Minutes) :- Minutes is ((H2 - H1) * 60) + (M2 - M1). /* True if Cost is the time difference between time 1 and 2. */ travelCost(_ at H1:M1, _ at H2:M2, Cost) :- diffTime(H1:M1, H2:M2, Cost). /* True if Y is the right neighbour of X in list L. */ rightNeighbour(X, Y, L) :- append(_, [X,Y|_], L), !. /* True if Time1 is before Time2 with one minute to spare. */ before(Time1, Time2) :- diffTime(Time1, Time2, Min), Min>=1. /* True if an edge exists between From and To with Cost as its cost. */ travel(From, To, Cost) :- route(R), rightNeighbour(From, To, R), travelCost(From, To, Cost). /* True if a waiting period exists on a station between Begin and End with Duration as the waiting duration. */ waitS(Begin, End, Duration) :- route(X), route(Y), member(Begin, X), member(End, Y), Begin = Station at T1, End = Station at T2, diffTime(T1, T2, Duration), before(T1, T2). /* True if an edge exists between From and End directly. */ traverse(From, End, _, [travel(From, End, C)]) :- travel(From, End, C). /* True if an intermediate waiting period exists between From and Inter leading to To. This waiting period should not be contained in the list Visited. */ traverse(From, To, Visited, [wait(S, D)|Path]) :- From = S at _, Inter = S at _, waitS(From, Inter, D), \+ member(wait(S, _), Visited), Inter \== To, traverse(Inter, To, [wait(S, D)|Visited], Path). /* True if an intermediate edge exists between From and Inter leading to To. This edge should not be contained in the list Visited. */ traverse(From, To, Visited, [travel(From, Inter, C)|Path]) :- travel(From, Inter, C), \+ member(travel(From, Inter, C), Visited), Inter \== To, traverse(Inter, To, [travel(From, Inter, C)|Visited], Path). /* True if Path is a list of edges from From to To*/ path(From, To, Path) :- traverse(From, To, [], Path). /* True if Cost is the cost of the single edge contained in the given list. */ cost([travel(_, _, Cost)], Cost). cost([wait(_, Icost)|Tpath], Cost) :- cost(Tpath, Tcost), Cost is Icost + Tcost. cost([travel(_, _, Icost)|Tpath], Cost) :- cost(Tpath, Tcost), Cost is Icost + Tcost. /* True if Path is the path with the lowest cost from From to To. */ shortestPath(From, To, Path) :- findall([Cost, Len, Cpath], (path(From, To, Cpath), cost(Cpath, Cost), length(Cpath, Len)), Paths), sort(Paths, [[_, _, Path]|_]).