2014-02-23 253 views
3

我想做一个谓词来检查一个节点是否可以在prolog中的图中到达另一个节点。例如Connected(1,X,[[1,3],[3,4],[2,5]])第一个参数是我想要启动的节点,第二个是我想要达到的节点,第三个是边缘列表。到目前为止,我已经设法做到了这一点,但当我试图通过使用findall/3获得所有的节点时,我得到了一个无限循环。Prolog连接图的边缘

有什么方法可以阻止无限循环或者我应该从开始的问题出发?

这是到目前为止我的代码:

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). 

我在序言新的,我想不出什么我做错了。

+0

一个边沿共同表示是'XY'不'[X,Y]' 。 – false

回答

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

看看?- gtrace, goes(1,[[1,3],[3,4],[2,5]], X).做什么。

对于所有递归go :- go当停止时,您需要一个条件。

在你的情况下,我建议添加一个参数Traversed这是你所访问的所有节点(或边缘)的列表。然后,如果您已经访问过它们,则不会再次转到节点上。 因此,您可以递归地查看越来越少的元素,并且可以在某个点结束。

许多递归使用谓词!。看看它。