2013-12-20 59 views
2

我对Prolog相当陌生,我希望这个问题没有被问及回答,但如果它有我道歉,我不能理解任何其他类似的问题和答案。序言无限循环

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

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

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

我需要能够从镇到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. 
然而

如果我添加一个镇d像这样

facts: 
road(b, d, 10) 

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

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

对不起有很长的描述。我希望有一个人可以帮助我!

回答

1

这是一个图遍历的问题。我认为你的问题是你有一个循环图—你发现腿a-->b和你发现的下一个腿是b-->a在那里它再次找到腿a-->b和...好吧,你得到的图片。

我会处理这个问题是这样,使用帮手谓词蓄电池建立我的路线和计算总距离。类似这样的:

% =========================================================================== 
% 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. 
+0

此代码不会在路线中添加两个以上的城市。 – Danny