0

我在 Prolog 中遇到以下问题,例如,我在知识库中有几个事实:

flight(rome,london,ba,1500,150,400).
flight(london,newyork,airfrance,600,60,200).
flight(rome,paris,airfrance,1200,120,500).  
flight(paris,newyork,airfrance,600,60,200).
flight(newyork,london,ba,1500,240,300).

我只对获取从 X 到 Y 的所有可能路线的列表感兴趣。我知道我必须使用递归规则,并且必须将访问过的地方添加到列表中以停止循环反复运行作为飞行路径在知识库中有几个循环。

到目前为止我所拥有的是:

flight_route(X,Y):-
   flight(X,Y,A,B,C,D).

trip(X,X,[]).
trip(X,Z,T) :-
   flight_route(Y,Z),
   not(member(Y,T)),
   trip(X,Y,[Y|T]).

出于某种原因,当我查看跟踪时,规则在尝试检查 not(member(Y,T)) 时失败,但我不明白为什么会这样。

4

2 回答 2

1

更普遍,

trip(X,Y) :-
   closure0(flight_route,X,Y).

定义closure0/3

于 2014-11-21T10:52:24.010 回答
0

问题在于您对trip/3谓词的定义。尝试:

trip(X, X, _).
trip(X, Z, T) :-
   flight_route(X, Y),
   \+ member(Y, T),
   trip(Y, Z, [Y| T]).

在第一个子句中,当您到达目的地时,您如何到达那里并不重要。因此第三个参数中的(匿名)变量。此外,找到从起点而不是终点开始的路径可能更有效。一个可能的问题也可能是您如何调用trip/3谓词。确保使用第三个参数传递的空列表调用它(如果你不接地T,调用\+ member(Y, T)将始终失败)。或者定义一个trip/2参数来抽象该实现细节:

trip(X, Y) :-
    trip(X, Y, []).
于 2014-11-02T14:37:46.833 回答