我想创建一个谓词,检查节点是否可以到prolog中的图中的另一个节点。例如Connected(1,X,[[1,3],[3,4],[2,5]])
第一个参数是我想要开始的节点,第二个参数是我想要到达的节点,第三个是边缘列表。到目前为止,我已设法做到这一点,但当我尝试通过使用findall / 3获取我到达的所有节点时,我得到一个无限循环。
有没有办法阻止无限循环,或者我应该从问题中解决问题?
到目前为止,这是我的代码:
match([X,Y],List):- member([X,Y], List).
match([X,Y],List):- member([Y,X], List).
go(X,Y,List):-match([X,Y],List).
go(X,Y,List):-match([X,Z],List),go(Z,Y,List).
goes(X,List,List2):-findall(Y,go(X,Y,List),List2).
我是Prolog的新手,我无法弄清楚我做错了什么。
答案 0 :(得分:4)
可能对您的代码进行更正
match([X,Y], List, Rest):- select([X,Y], List, Rest).
match([X,Y], List, Rest):- select([Y,X], List, Rest).
go(X,Y,List) :- match([X,Y],List,_).
go(X,Y,List) :- match([X,Z],List,Rest), go(Z,Y,Rest).
goes(X,List,List2) :- findall(Y, go(X,Y,List), List2).
现在匹配'消耗'边缘,然后避免无限循环
答案 1 :(得分:1)
查看?- gtrace, goes(1,[[1,3],[3,4],[2,5]], X).
的内容。
对于所有递归go :- go
,当它停止时你需要一个条件。
在你的情况下,我建议添加一个参数Traversed
,它是你访问过的所有节点(或边)的列表。然后,如果您已经访问过节点,则不要再次检查节点。
因此,您可以越来越少地以递归方式查看元素,并且在某些时候结束了。[/ p>
许多递归都使用谓词!
。看看吧。