I'm currently working through the Learn Prolog Now examples and for the one exercise I have a KB that runs out of local stack if I just have a tiny change in one rule. this is the KB:
byCar(auckland,hamilton).
byCar(hamilton,raglan).
byCar(valmont,saarbruecken).
byCar(valmont,metz).
byTrain(metz,frankfurt).
byTrain(saarbruecken,frankfurt).
byTrain(metz,paris).
byTrain(saarbruecken,paris).
byPlane(frankfurt,bangkok).
byPlane(frankfurt,singapore).
byPlane(paris,losAngeles).
byPlane(bangkok,auckland).
byPlane(singapore,auckland).
byPlane(losAngeles,auckland).
travel(X,Y) :- byCar(X,Y).
travel(X,Y) :- byTrain(X,Y).
travel(X,Y) :- byPlane(X,Y).
and the relevant rule:
travel(X,Y) :- travel(X,Z), travel(Z,Y).
and this is the query in question which runs out of stack:
?- travel(valmont,losAngeles).
But if I change the rule to
travel(X,Y) :- travel(Z,Y), travel(X,Z).
Then it works.
If I trace the query I get quickly stuck like this:
Redo: (17) travel(raglan, _6896) ? creep
Call: (18) byPlane(raglan, _6896) ? creep
Fail: (18) byPlane(raglan, _6896) ? creep
Redo: (17) travel(raglan, _6896) ? creep
Call: (18) travel(raglan, _6896) ? creep
Call: (19) byCar(raglan, _6896) ? creep
Fail: (19) byCar(raglan, _6896) ? creep
Redo: (18) travel(raglan, _6896) ? creep
Call: (19) byTrain(raglan, _6896) ? creep
Fail: (19) byTrain(raglan, _6896) ? creep
Redo: (18) travel(raglan, _6896) ? creep
Call: (19) byPlane(raglan, _6896) ? creep
Fail: (19) byPlane(raglan, _6896) ? creep
Redo: (18) travel(raglan, _6896) ? creep
...
But I don't see why. Shouldn't it just understand that raglan is an endstation and thus it has to backtrack one level more?
Thanks!
Edit: I use SWI Prolog
Edit: I found the problem after going through it step by step.
In the case of raglan, there is no rule to anywhere at all. Therefore, after trying byPlane, byTrain, byCar, it tries travel(raglan, X) again (the first goal of the last rule), thus looping.
But I don't see how the other rule is any better.