Prolog出本地堆栈错误
我尝试了一本书中的一些基本示例,它会出现“本地堆栈外”错误(代码之后我会告诉更多)。 代码如下:Prolog出本地堆栈错误,prolog,transitive-closure,Prolog,Transitive Closure,我尝试了一本书中的一些基本示例,它会出现“本地堆栈外”错误(代码之后我会告诉更多)。 代码如下: 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),结果返回true,然后输入“;”它
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),结果返回true,然后输入“;”它犯了错误。
这里的问题是什么?问题是您已经以循环的方式定义了什么是边。在寻找从
a
到b
的第二条路径时,Prolog正在tedge(a,VAR)
,edge(a,VAR)
,tedge(a,VAR)
等之间循环
请注意,即使没有将边定义为对称,Prolog也会循环,这是由于循环a->b->c->a
解决方案是跟踪以前访问过的顶点和/或边。可以使用(我从SO user false中学到的谓词)直接实现对非重复顶点的检查。如果使用该谓词,则只需要edge/2
事实和以下查询:
?- closure0(edge, a, b).
简而言之,它进入了无限递归。如果您执行
跟踪
,您将看到发生了什么。为什么要定义边(X,Y):-tedge(X,Y)。?它必然会创建一个循环场景,因为edge/2
还定义了tedge/2
所指的事实。把它放在tedge/2
上,然后查询tedge(a,b)。
。真是奢侈,我不需要再输入答案了!