路由无限循环prolog

路由无限循环prolog,prolog,Prolog,就从序言开始,练习路线问题 train(a,b). train(b,a). train(b,c). train(c,b). route(X,Y,[]) :- train(X,Y) ; train(Y,X). route(X,Y,[H|T]) :- route(X,H,[]), route(H,Y,T). 通过执行此路由/3,第一条规则为两个直接连接的位置提供一个空集,表示存在路由。第二条规则说明了有中间位置可以从一个地方到达另一个地方的情况。但当我询问这个问题

就从序言开始,练习路线问题

train(a,b).
train(b,a).
train(b,c).
train(c,b).

route(X,Y,[]) :-
      train(X,Y)
   ;  train(Y,X).
route(X,Y,[H|T]) :-
   route(X,H,[]),
   route(H,Y,T).
通过执行此路由/3,第一条规则为两个直接连接的位置提供一个空集,表示存在路由。第二条规则说明了有中间位置可以从一个地方到达另一个地方的情况。但当我询问这个问题时,我得到了一个循环路线


有人说有一个助手谓词访问了_route/4以跟踪已经访问过的地方,但不知道这种方法是如何工作的。提示或示例可能会有所帮助。

当前解决方案的问题是,Prolog解算器会生成无限多个轨迹,如[a、b、a、b、a、b、a…],永远不会到达终点

您可能要做的是排除X、Y或H是T成员的情况(这可能是访问的路径/4谓词)。这样,您就不会两次通过同一个节点

编辑

我已经坐下来,稍微更新了一下我的Prolog知识,创建了这样的代码,看起来很有效:

train(a,b).
%train(b,a). Your predicate is symmetric, you don't need to specify both directions
train(b,c).
%train(c,b).
train(c,d).
train(c,e).
train(d,f).
train(e,f).

visited_route(X, Y, [], V) :-
    ( train(X,Y) ; train(Y,X) ),
    not(member(Y, V)).

visited_route(X, Y, [H | T], V) :-
    visited_route(X, H, [], [X | V]),
    visited_route(H, Y, T, [X | V]).

route(X,Y,R) :-
    visited_route(X, Y, R, []).

已访问的路由有一个附加列表,其中包含从X到Y(不包括Y)访问的所有节点。当解算器在首次访问的路径谓词中找到从X到Y的路径时,它会检查该路径是否未通过已访问的节点,如果未通过,则丢弃候选路径。

请不要破坏您的问题!