刚开始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第一个规则给出两个直接连接的位置,空集表示存在路径。第二条规则规定了从一个到另一个到达的中间位置的情况。但是当我查询这个并且我得到一个循环路线时。
有人说有一个帮助谓词visited_route / 4来跟踪已经访问过的地方,但不知道这种方式是如何工作的。提示或示例将有所帮助。
答案 0 :(得分:2)
当前解决方案的问题在于Prolog解算器会产生无限的音轨,如[a,b,a,b,a,b,a ......]永远不会到达终点。
您可能想要做的是排除X,Y或H是T的成员的情况(这可能是visited_route / 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)的路上访问的所有节点。当求解程序在第一个visited_route谓词中找到从X到Y的路径时,它会检查路由是否没有通过已访问过的节点,如果是,则丢弃候选者。