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.