简体   繁体   English

Prolog超出本地堆栈错误

[英]Prolog Out of local stack error

I tried some basic example from a book and it makes "Out of local stack" error (I'll tell more after the code). 我尝试了一本书中的一些基本示例,它使“ Out of local stack”错误(在代码后再讲)。 here is the code: 这是代码:

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

I tried for example to write query edge(a,b) and it returned true and then I entered ';' 例如,我尝试编写查询edge(a,b)并返回true,然后输入“;” and it made the error. 它导致了错误。 What's the problem here? 这是什么问题

The problem is that you have defined what an edge is in a cyclic way. 问题是您已经以循环方式定义了边。 While looking for a second path from a to b Prolog is looping through tedge(a,VAR) , edge(a,VAR) , tedge(a,VAR) , etc. 寻找从ab的第二条路径时,Prolog遍历tedge(a,VAR)edge(a,VAR)tedge(a,VAR)等。

Notice that Prolog would loop even if you had not defined your edges to be symmetric, namely due to the cycle a -> b -> c -> a . 请注意,即使没有将边定义为对称,Prolog也会循环,即由于循环a- a -> b -> c -> a

The solution is to keep track of vertices and/or edges that have been visited before. 解决方案是跟踪先前已访问过的顶点和/或边缘。 Checking for non-recurring vertices can be straightforwardly implemented using closure0/3 (a predicate I learned from SO user false). 可以使用closure0 / 3 (我从SO用户false中学到的谓词)直接执行检查非重复顶点的操作。 If you use that predicate, you only need your edge/2 facts and the following query: 如果使用该谓词,则仅需要edge/2事实和以下查询:

?- closure0(edge, a, b).

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM