I have created this knowledge base in Prolog, which reflects a bus company wth busses going from and to places, leaving and arriving at set times:
connection(kerkrade, heerlen, 1100, 1200).
connection(kerkrade, bleijerheide, 1100, 1225).
connection(heerlen, kerkrade, 1115, 1230).
connection(heerlen, maastricht, 1230, 1330).
connection(maastricht, heerlen, 1430, 1530).
connection(maastricht, sittard, 1331, 1430).
connection(maastricht, sittard, 1345, 1445).
connection(sittard, maastricht, 1630, 1530).
connection(sittard, denbosch, 1530, 1700).
connection(denbosch, sittard, 1800, 1930).
connection(denbosch, amsterdam, 1000, 1330).
checkTime(X,Y,Z):-
connection(X,Y,S,_),
(Z =< S).
aRoute(From, To, Time):-
checkTime(From,To,Time).
testRoute(A,B,T):-
walk(A,B,T,[]).
walk(A,B,Time,V) :-
aRoute(A,X,Time),
not(member(X,V)),
(
B = X;
connection(A,X,_,S), walk(X,B,S,[A|V])
).
Whenever I ask my knowledge base if there is a route between two points, it returns whether that's possible; true
or false
:
testRoute(kerkrade, sittard, 900).
true; (signifies that there are three routes, of which two are possible)
true;
false.
However, this is not what I desire. In the best case I want to show the connections used to create the route between two points in the toplevel like this:
connection(kerkrade, heerlen, 1100, 1200)
connection(heerlen, maastricht, 1230, 1330)
/* and so on.. */
How do I do this? I think I have to pass a variable like X
along with my call to testRoute, so that it can report the value of it. I'm having trouble writing the predicate for that, as I am unsure where to place it. My idea is that I have to add an extra parameter to walk(A,B,Time,V)
but I wouldn't know what I could do with it after that in order to make it report the intermediate steps of the route.
You could keep a list with the connections by writing:
checkTime(X,Y,Z, connection(X,Y,S,W)):-
connection(X,Y,S,W),
(Z =< S).
aRoute(From, To, Time,Head):-
checkTime(From,To,Time,Head).
testRoute(A,B,T,L):-
walk(A,B,T,[],L).
walk(A,B,Tijd,V,[Head|L]) :-
aRoute(A,X,Tijd,Head),
not(member(X,V)),
(
B = X,L=[];
connection(A,X,_,S), walk(X,B,S,[A|V],L)
).
Example:
?- testRoute(kerkrade, sittard, 900,L).
L = [connection(kerkrade, heerlen, 1100, 1200), connection(heerlen, maastricht, 1230, 1330), connection(maastricht, sittard, 1331, 1430)] ;
L = [connection(kerkrade, heerlen, 1100, 1200), connection(heerlen, maastricht, 1230, 1330), connection(maastricht, sittard, 1345, 1445)] ;
false.