2014-12-30 43 views
0

我尝试了一本书中的基本示例,它使“超出本地堆栈”错误(我会在代码后告诉更多)。 这里是代码:Prolog超出本地堆栈错误

edge(a,b). 
edge(a,e). 
edge(b,d). 
edge(b,c). 
edge(c,a). 
edge(e,b). 
tedge(Node1,Node2) :- 
    edge(Node1,SomeNode), 
    edge(SomeNode,Node2). 
edge(X,Y) :- tedge(X,Y). 

我试图例如写查询边缘(A,B),并且它返回真,然后输入我“;”它发生了错误。 这里有什么问题?

+0

简短的答案是,它进入无限递归。如果你做一个“跟踪”,你会看到发生了什么。你为什么定义了边(X,Y): - Tedge(X,Y)。它必然会创建一个循环场景,因为'edge/2'还定义了'tedge/2'引用的事实。只要把它留在'tedge/2'并且查询'tedge(a,b).'。 – lurker

回答

2

问题是,您已经定义了循环方式的边界。虽然从ab的Prolog寻找第二条路径是通过tedge(a,VAR)edge(a,VAR)tedge(a,VAR)循环等

注意的Prolog会即使您没有定义您的边缘是对称的,即由于循环a -> b -> c -> a循环。

解决方案是跟踪之前访问过的顶点和/或边缘。检查非循环顶点可以直接使用closure0/3(我从SO用户学习到的谓词false)实现。如果您使用的谓词,您只需要您的edge/2事实和下面的查询:

?- closure0(edge, a, b). 
+2

什么是奢侈品,我不再需要输入答案! – false