Prolog无限循环

时间:2013-12-20 20:09:31

标签: recursion prolog

我对Prolog很新,我希望这个问题没有得到回答,但如果我有道歉,我就无法理解任何其他类似的问题和答案。

我的问题是我有3个城镇,通过公路连接。大多数是单向的,但有两个城镇通过双向连接。即

facts:  
road(a, b, 1).  
road(b, a, 1).  
road(b, c, 3). 

其中a,b和c是城镇,数字是距离

我需要能够从城镇a到c而不会卡在a和b之间

到此为止我可以用谓词来解决:(其中r是路线上的城镇列表)

route(A, B, R, N) :- 
  road(A, B, N), 
  R1 = [B],
  R = [A|R1],
  !.

route(A, B, R, N) :- 
  road(A, C, N1), 
  route(C, B, R1, N2), 
  \+ member(A, R1), 
  R = [A | R1], 
  N is N1+N2.

然而,如果我添加一个像这样的城镇

facts:
road(b, d, 10)

我无法让Prolog认识到这是第二种可能的途径。我知道这是因为我使用了切割,但没有切割它不会停止并以堆栈溢出结束。

此外,我需要能够编写一个新的谓词,当R作为a和c之间的最短路径给出时,该谓词返回true。

很抱歉这么长的说明。我希望有人可以帮助我!

1 个答案:

答案 0 :(得分:1)

这是图形遍历的问题。我认为你的问题是你有一个循环图 - 你发现腿a-->b而你找到的下一条腿是b-->a,它再次找到了腿a-->b和...好吧,你明白了。

我会像这样处理问题,使用 helper 谓词和 accumulators 来构建我的路线并计算总距离。像这样:

% ===========================================================================
% route/4: find the route(s) from Origin to Destination and compute the total distance
%
% This predicate simply invoke the helper predicate with the
% accumulator(s) variables properly seeded.
% ===========================================================================
route(Origin,Destination,Route,Distance) :-
  route(Origin,Destination,[],0,Route,Distance)
  .

% ------------------------------------------------
% route/6: helper predicate that does all the work
% ------------------------------------------------
route(D,D,V,L,R,L) :-              % special case: you're where you want to be.
  reverse([D|V],R)                 % - reverse the visited list since it get built in reverse order
  .                                % - and unify the length accumulator with the final value. 
route(O,D,V,L,Route,Length) :-     % direct connection
  road(O,D,N) ,                    % - a segment exists connecting origin and destination directly
  L1 is L+N ,                      % - increment the length accumulator
  V1 = [O|V] ,                     % - prepend the current origin to the visited accumulator
  route(D,D,V1,L1,Route,Length)    % - recurse down, indicating that we've arrived at our destination
  .                                %
route(O,D,V,L,Route,Length) :-     % indirect connection
  road(O,X,N) ,                    % - a segment exists from the current origin to some destination
  X \= D ,                         % - that destination is other than the desired destination
  not member(X,V) ,                % - and we've not yet visited that destination
  L1 is L+N ,                      % - increment the length accumulator
  V1 = [O|V] ,                     % - prepend the current origin to the visited accumulator
  route(X,D,V1,L1,Route,Length)    % - recurse down using the current destination as the new origin.