我对Prolog很陌生,想要创建一个程序,我可以在这里请求带有谓词“route(Startpoint,Endpoint,Route)
”的路径。
到目前为止我的代码是:
% facts
connection(s1,s2).
connection(s2,s3).
connection(s3,s4).
connection(s4,s5).
connection(s5,s6).
connection(s6,s7).
connection(s7,s1).
% predicates
route1(X,Y,[X,Y]) :- connection(X,Y).
route1(X,Y,R) :- connection(X,Z), route1(Z,Y,RZ), R=[X|RZ].
route2(X,Y,[X,Y]) :- connection(Y,X).
route2(X,Y,R) :- connection(Z,X), route2(Z,Y,RZ), R=[X|RZ].
route(X,Y,R) :- route1(X,Y,R); route2(X,Y,R).
我的代码适用于某些路由,但不适用于某个循环(如上面的事实)。如何在Prolog中阻止多次访问某个路由?
例如,当我问“?- route1(s1,s4,R).
”时,Prolog首先向我提供了正确的路线“[s1,s2,s3,s4]
”,但它也为我提供了其他路线,例如“[s1, s2, s3, s4, s5, s6, s7, s1, s2, s3, s4]
”,“{{ 1}}“等等。
提前致谢!
答案 0 :(得分:2)
你可以写:
route1(X,Y,[X,Y]) :- connection(X,Y).
route1(X,Y,R) :- connection(X,Z), route1(Z,Y,RZ),R=[X|RZ],
sort(R,R1),length(R,N),length(R1,N1),
(N>N1->!,fail ;true).
sort/2
删除重复项,因此如果您希望解决方案不重复排序列表,并且输出列表必须具有相同的长度。
?- route1(s1,s4,R).
R = [s1, s2, s3, s4] ;
false.
另一种方法是:
route1(X,Y,R):-route1(X,Y,[],R).
route1(X,Y,_,[X,Y]) :- connection(X,Y).
route1(X,Y,L,R) :- connection(X,Z),\+member(Z,L),
route1(Z,Y,[Z|L],RZ),R=[X|RZ].
示例:
?- route1(s1,s4,R).
R = [s1, s2, s3, s4] ;
false.