В настоящее время я работаю над примерами Learn Prolog Now и над одним упражнением У меня есть КБ, в котором заканчивается локальный стек, если я просто внесу небольшое изменение в одно правило. это КБ:
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).
и соответствующее правило:
travel(X,Y) :- travel(X,Z), travel(Z,Y).
и это рассматриваемый запрос, который выходит за пределы стека:
?- travel(valmont,losAngeles).
Но если я изменю правило на
travel(X,Y) :- travel(Z,Y), travel(X,Z).
Тогда это работает.
Если я отслеживаю запрос, я быстро застреваю следующим образом:
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
...
Но я не понимаю, почему. Разве он не должен просто понять, что реглан — это конечная станция, и поэтому он должен вернуться еще на один уровень?
Спасибо!
Изменить: я использую SWI Prolog
Правка: я обнаружил проблему после пошагового ее изучения. В случае с регланом вообще нет правила никуда. Следовательно, после попытки byPlane, byTrain, byCar
он снова пытается travel(raglan, X)
(первая цель последнего правила), таким образом, зацикливается. Но я не вижу, чем другое правило лучше.