超出堆栈限制(0.2Gb)...可能无限递归(循环):
Posted
技术标签:
【中文标题】超出堆栈限制(0.2Gb)...可能无限递归(循环):【英文标题】:Stack limit (0.2Gb) exceeded...Probable infinite recursion (cycle): 【发布时间】:2019-10-13 13:06:45 【问题描述】:Prolog 很新,但我正在尝试实现上下文无关语法,但我在使用我拥有的规则通过测试用例时遇到了问题。
我尝试更改规则的顺序以使其在逻辑上看起来更正确,但我似乎无法获得一致的正确输出,并且我继续遇到相同的堆栈错误。我认为这与vp --> vp, np.
递归有关,但如果是这种情况,那么为什么np --> np, pp.
也不给我一个错误呢?我的代码如下:
:- use_module(library(tabling)).
:- table s/2.
s --> np, vp.
np --> det, n.
np --> np, pp.
vp --> vp, pp.
vp --> v, np.
pp --> p, np.
det --> [the].
n --> [cop].
n --> [criminal].
n --> [street].
v --> [chased].
p --> [in].
p --> [by].
理想情况下,向查询询问这个应该返回 true:
$- s([the,cop,chased,the,criminal], []).
问这个应该返回 false:
$- s([the, cop, the, criminal, chased], []).
我都试过了,他们只是给我同样的错误:
Stack limit (0.2Gb) exceeded
Stack sizes: local: 0.2Gb, global: 22Kb, trail: 5Kb
Stack depth: 1,561,893, last-call: 0%, Choice points: 1,561,869
Probable infinite recursion (cycle):
[1,561,893] vp([length:3], _1424)
[1,561,892] vp([length:3], _1456)
感谢任何反馈!
【问题讨论】:
你使用np --> np, pp
和vp --> vp,pp
,所以你的语法是左递归 (metalevel.at/prolog/dcg#leftrecursion),这是个问题。
@anon 请不要在有人回答问题 30 分钟后立即删除您的问题。这是一个很好的问题,保留它可以让回答者因帮助您回答问题而获得荣誉。
【参考方案1】:
问题是你构造了一个left recursive grammar。事实上,如果我们查看您定义的规则,我们会看到:
:- use_module(library(tabling)).
:- table s/2.
s --> np, vp.
np --> det, n.
np --> np, pp.
vp --> vp, pp.
vp --> v, np.
pp --> p, np.
det --> [the].
n --> [cop].
n --> [criminal].
n --> [street].
v --> [chased].
p --> [in].
p --> [by].
现在基于 Prolog 实现谓词的方式,它不能使用这种左递归语法,因为如果你调用np/2
,它会首先调用np/2
,因此我们永远不会退出“循环”(直到调用堆栈溢出)。
然而,我们可以在这里使用tabling,就像您以某种方式使用s/2
一样,这是不必要的,因为s
中没有左递归路径(直接或间接)产生s --> s, ...
。我们需要表np/2
和vp/2
,比如:
:- use_module(library(tabling)).
:- table np/2.
:- table vp/2.
s --> np, vp.
np --> det, n.
np --> np, pp.
vp --> vp, pp.
vp --> v, np.
pp --> p, np.
det --> [the].
n --> [cop].
n --> [criminal].
n --> [street].
v --> [chased].
p --> [in].
p --> [by].
那么我们确实可以得到预期的结果:
?- s([the,cop,chased,the,criminal], []).
true.
?- s([the, cop, the, criminal, chased], []).
false.
【讨论】:
以上是关于超出堆栈限制(0.2Gb)...可能无限递归(循环):的主要内容,如果未能解决你的问题,请参考以下文章