Prolog连接图的边缘

时间:2014-02-23 18:08:01

标签: graph prolog

我想创建一个谓词,检查节点是否可以到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的新手,我无法弄清楚我做错了什么。

2 个答案:

答案 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>

许多递归都使用谓词!。看看吧。