1

我在 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).我得到一个 Out of local stack 异常。奇怪的是,当我在 Windows 中执行相同的查询时,程序运行良好。

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

4

2 回答 2

4

要实际查看问题所在,请考虑以下

边缘(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)。因此,该程序无法终止。换句话说:您的程序永远不会终止。

于 2017-03-21T21:43:10.573 回答
4

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

有帮助的是:(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).
于 2017-03-21T18:31:04.640 回答