Prolog-错误:linux中的本地堆栈不足

Prolog-错误:linux中的本地堆栈不足,prolog,transitive-closure,failure-slice,Prolog,Transitive Closure,Failure Slice,我有一个非常简单的swipl程序 edge(X,Y) :- edge(X,Z),edge(Z,Y). edge(a,b). edge(a,f). edge(b,c). edge(c,d). edge(g,c). edge(f,g). edge(f,c). edge(f,e). edge(c,e). edge(e,d). 但是当我进行查询时,edge(a,c)。i会得到一个本地堆栈外异常。奇怪的是,当我在windows中执行相同的查询时,程序工作得非常好 我试图增加本地堆栈,但程序抛出异常的时间

我有一个非常简单的swipl程序

edge(X,Y) :- edge(X,Z),edge(Z,Y).
edge(a,b).
edge(a,f).
edge(b,c).
edge(c,d).
edge(g,c).
edge(f,g).
edge(f,c).
edge(f,e).
edge(c,e).
edge(e,d).
但是当我进行查询时,
edge(a,c)。
i会得到一个本地堆栈外异常。奇怪的是,当我在windows中执行相同的查询时,程序工作得非常好


我试图增加本地堆栈,但程序抛出异常的时间更长。

您的谓词定义了一个可爱的无限循环。它只是坐在那里调用自己,甚至从不尝试事实,因为谓词是第一个,并且与事实的名称相同

有帮助的是:(1)在谓词之前断言事实,(2)不要用与事实相同的名称定义谓词(从技术上讲,它并不意味着相同的事情,所以为什么它应该有相同的名称?),以及(3)在递归子句中,在递归调用之前检查预定义的边

edge(a,b).
edge(a,f).
edge(b,c).
edge(c,d).
edge(g,c).
edge(f,g).
edge(f,c).
edge(f,e).
edge(c,e).
edge(e,d).

connected(X, Y) :-
    edge(X, Y).
connected(X, Y) :-
    edge(X, Z), connected(Z, Y).

您的谓词定义了一个可爱的无限循环。它只是坐在那里调用自己,甚至从不尝试事实,因为谓词是第一个,并且与事实的名称相同

有帮助的是:(1)在谓词之前断言事实,(2)不要用与事实相同的名称定义谓词(从技术上讲,它并不意味着相同的事情,所以为什么它应该有相同的名称?),以及(3)在递归子句中,在递归调用之前检查预定义的边

edge(a,b).
edge(a,f).
edge(b,c).
edge(c,d).
edge(g,c).
edge(f,g).
edge(f,c).
edge(f,e).
edge(c,e).
edge(e,d).

connected(X, Y) :-
    edge(X, Y).
connected(X, Y) :-
    edge(X, Z), connected(Z, Y).

实际上,看看问题是什么,考虑如下:

边(X,Y):-边(X,Z),假,边(Z,Y)。 边缘(a,b):-错误。 边缘(a,f):-错误。 边缘(b,c):-错误。 边缘(c,d):-错误。 边(g,c):-假。 边(f,g):-假。 边缘(f,c):-错误。 边缘(f,e):-假。 边缘(c,e):-错误。 边缘(e,d):-错误。
如果程序的这个片段没有终止,那么原始程序也不会终止。看看还剩下什么!单个递归,其中参数要么被忽略(
Y
),要么被传递(
X
)。因此,该程序无论如何都无法终止。换句话说,你的程序永远不会终止。

去看看问题是什么,考虑如下:

边(X,Y):-边(X,Z),假,边(Z,Y)。 边缘(a,b):-错误。 边缘(a,f):-错误。 边缘(b,c):-错误。 边缘(c,d):-错误。 边(g,c):-假。 边(f,g):-假。 边缘(f,c):-错误。 边缘(f,e):-假。 边缘(c,e):-错误。 边缘(e,d):-错误。
如果程序的这个片段没有终止,那么原始程序也不会终止。看看还剩下什么!单个递归,其中参数要么被忽略(
Y
),要么被传递(
X
)。因此,该程序无论如何都无法终止。换句话说:您的程序永远不会终止。

在windows上,这也应该失败,因为您创建了无限递归…在windows上,这也应该失败,因为您创建了无限递归…谢谢,它可以工作。但是你知道为什么windows不会崩溃吗?@GeovanyGameros你能解释一下你所说的“windows”而不是“崩溃”是什么意思吗?你是说当你在Windows中运行你的代码时,你不会得到堆栈溢出吗?如果你没有,实际会发生什么?这里的问题是代码进入无限递归。在Windows中,它可能会在看到堆栈溢出并报告它之前导致其他一些错误情况。我的意思是,在Windows中,代码不会得到堆栈溢出。当我运行代码时,我得到“true”。也许我有另一个swi序言version@GeovanyGameros你确定你在运行完全相同的代码吗?不管怎样,我提供的答案是你最初问题的解决方案。为什么Windows给出不同的结果是另一个问题。:)谢谢,它起作用了。但是你知道为什么windows不会崩溃吗?@GeovanyGameros你能解释一下你所说的“windows”而不是“崩溃”是什么意思吗?你是说当你在Windows中运行你的代码时,你不会得到堆栈溢出吗?如果你没有,实际会发生什么?这里的问题是代码进入无限递归。在Windows中,它可能会在看到堆栈溢出并报告它之前导致其他一些错误情况。我的意思是,在Windows中,代码不会得到堆栈溢出。当我运行代码时,我得到“true”。也许我有另一个swi序言version@GeovanyGameros你确定你在运行完全相同的代码吗?不管怎样,我提供的答案是你最初问题的解决方案。为什么Windows给出不同的结果是另一个问题。:)