Prolog - 我将如何递归地构建列表?

Prolog - How would I recursively build a list?

我正在完成 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).

Write a predicate travel/2 which determines whether it is possible to travel from one place to another by chaining together car, train, and plane journeys. For example, your program should answer yes to the query travel(valmont,raglan) .

So, by using travel/2 to query the above database, you can find out that it is possible to go from Valmont to Raglan. If you are planning such a voyage, that’s already something useful to know, but you would probably prefer to have the precise route from Valmont to Raglan. Write a predicate travel/3 which tells you which route to take when travelling from one place to another. For example, the program should respond X = go(valmont,metz, go(metz,paris, go(paris,losAngeles))) to the query travel(valmont,losAngeles,X) .

这是我的仿函数:

go(X).
go(X,Y).

这是我的 travel/2 谓词:

travel(X,Y) :- byCar(X,Y).
travel(X,Y) :- byCar(X,Z), travel(Z,Y).

travel(X,Y) :- byTrain(X,Y).
travel(X,Y) :- byTrain(X,Z), travel(Z,Y).

travel(X,Y) :- byPlane(X,Y).
travel(X,Y) :- byPlane(X,Z), travel(Z,Y).

但是,我的 travel/3 谓词有问题:

travel(X,Y,G) :- byCar(X,Y),   G = go(X, Y).
travel(X,Y,G) :- byCar(X,Z),   travel(Z,Y,G).

travel(X,Y,G) :- byTrain(X,Y), G = go(X, Y).       
travel(X,Y,G) :- byTrain(X,Z), travel(Z,Y,G).

travel(X,Y,G) :- byPlane(X,Y), G = go(X, Y).       
travel(X,Y,G) :- byPlane(X,Z), travel(Z,Y,G).

当我 运行 问题中的谓词时,我得到:

?- travel(valmont,losAngeles,X).
X = go(paris, losAngeles) .

但这并不是问题所需要的完整列表。我不太确定如何做到这一点;我是否需要重写我的谓词。非常感谢您提供任何帮助来帮助我了解我做错了什么!

您没有在 travel/3 谓词中适当地更改 G

travel(X,Y, go(X, Y)) :- byCar(X,Y).
travel(X,Y, go(X, Y)) :- byTrain(X,Y).
travel(X,Y, go(X, Y)) :- byPlane(X,Y).

travel(X,Y, go(X, Z, G)) :- byCar(X,Z), travel(Z,Y, G).
travel(X,Y, go(X, Z, G)) :- byTrain(X,Z), travel(Z,Y, G).
travel(X,Y, go(X, Z, G)) :- byPlane(X,Z), travel(Z,Y, G).

你得到:

| ?- travel(valmont, losAngeles, G).
G = go(valmont,saarbruecken,go(saarbruecken,paris,go(paris,losAngeles))) ? ;
G = go(valmont,metz,go(metz,paris,go(paris,losAngeles))) ? ;
no

作为奖励,您也可以嵌入旅行类型:

travel_(X,Y, car(X, Y)) :- byCar(X,Y).
travel_(X,Y, train(X, Y)) :- byTrain(X,Y).
travel_(X,Y, plane(X, Y)) :- byPlane(X,Y).
      
travel_(X,Y, car(X, Z, G)) :- byCar(X,Z), travel_(Z,Y, G).
travel_(X,Y, train(X, Z, G)) :- byTrain(X,Z), travel_(Z,Y, G).
travel_(X,Y, plane(X, Z, G)) :- byPlane(X,Z), travel_(Z,Y, G).

现在你得到:

| ?- travel_(valmont, losAngeles, G).
G = car(valmont,saarbruecken,train(saarbruecken,paris,plane(paris,losAngeles))) ? ;
G = car(valmont,metz,train(metz,paris,plane(paris,losAngeles))) ? ;
no