1

私は現在、Learn Prolog Now の例に取り組んでいます。1 つの演習では、1 つのルールにわずかな変更を加えるだけで、ローカル スタックが不足する KB があります。これは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).

および関連するルール:

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
...

しかし、理由がわかりません。ラグランがエンドステーションであり、1 レベル後戻りする必要があることを理解するだけでよいのではないでしょうか?

ありがとう!

編集:SWI Prologを使用しています

編集:段階的に問題を解決した後、問題を見つけました。ラグランの場合、どこにもルールはありません。したがって、 を試行した後、(最後のルールの最初のゴール) を再試行するため、ループしますbyPlane, byTrain, byCartravel(raglan, X)しかし、他のルールがどのように優れているかはわかりません。

4

2 に答える 2