我在prolog中创建了一个程序,它应该为我提供两个站之间的所有可能路径。在每条路线中,每个车站只能访问一次。到目前为止我的代码是:
% facts
connection(s1,s2).
connection(s1,s4).
connection(s2,s3).
connection(s2,s5).
connection(s3,s4).
connection(s4,s5).
connection(s5,s6).
connection(s6,s1).
% predicates
direction1(X,Y) :- connection(X,Y).
direction2(X,Y) :- connection(Y,X).
route1(X,Y,R):- route1(X,Y,[],R).
route1(X,Y,_,[X,Y]) :- direction1(X,Y).
route1(X,Y,L,R) :- \+direction1(X,Y), direction1(X,Z), \+member(Z,L), route1(Z,Y,[Z|L],RZ), R=[X|RZ].
route2(X,Y,R):- route2(X,Y,[],R).
route2(X,Y,_,[X,Y]) :- direction2(X,Y).
route2(X,Y,L,R) :- \+direction2(X,Y), direction2(X,Z), \+member(Z,L), route2(Z,Y,[Z|L],RZ), R=[X|RZ].
route(X,Y,R) :- route1(X,Y,R); route2(X,Y,R).
问题是prolog并没有给我所有路线,例如当我要求路线[s1,s4,R]时,prolog没有给我路线[s1,s2,s3, S4]。我认为这是由" + direction1(X,Y)"和" +方向2(X,Y)"。但我需要这样做以防止prolog在一条路线中多次访问一个电台。任何想法如何解决这个问题?
答案 0 :(得分:1)
微创修复方法是删除您正确识别为此失败源的\+direction1(X,Y)
,并在\+ member(X, L)
的定义中添加另一个route1/4
防护。
编辑:以上是不够的。这是对整个事物的更清晰的重写,具有更易读的格式和变量名称:
route1(X,Y,R):- route1(X,Y,[X],R). % note that X is visited immediately
route1(X,Y,_,[X,Y]) :- direction1(X,Y).
route1(X, Y, Visited, Route) :-
direction1(X, Z),
Z \= Y,
\+ member(Z, Visited),
route1(Z, Y, [Z|Visited], Route1),
Route = [X|Route1].
然后,您应该统一路线谓词的两个变体:其中一个仅查找仅沿“方向1”边缘的路线,而另一个仅沿“方向2”边缘找到路线。通常,您希望能够在任何方向上遍历任何边缘。