First, your connect
predicate forgets the mode of transport. Change it to:
connect(X,Y,byCar):- byCar(X,Y) ; byCar(Y,X).
connect(X,Y,byTrain):- byTrain(X,Y) ; byTrain(Y,X).
connect(X,Y,byPlane):- byPlane(X,Y) ; byPlane(Y,X).
Second, there's inconsistency in your use of travelLoop
's path argument:
travel(X,Y):-travelLoop(X,Y,[]). %// -- start empty. Why not [X]?
travelLoop(X,Y,_):-connect(X,Y). %// (1)
travelLoop(X,Y,Passed):-connect(X,Thru),
\+memberchk(Thru,Passed),
travelLoop(Thru,Y,[Thru|Passed]), %// -- start from [Thru|...].
X\=Y. %// why here? should be at (1)
The second clause of travel
needs to fire only if the first was unsuccessful. And why is it detached? Both clauses should be one near the other in the file.
travel(_,_):-write('Wrong travel input, please try again.'),nl.
%// This says: succeed always, and tell the user it didn't.
%// Need to join both clauses into one IF: (success -> true; wrong).
The success clause for travelLoop
is missing:
travelLoop(X,Y, Path):- X=Y, %// report the Path to user: ...
writeln( ... ).
As for the return voyage, isn't it as simple as switching the arguments? So, rename travelLoop
to travel_path
, and rewrite your travel
as
travel(X,Y):- %// the to and fro loop
travel_path(X,Y,[X]), travel_path(Y,X,[Y]) -> true ; wrong.
wrong:- writeln("Wrong input. Try again."), nl.