错误:未处理的异常:超出本地堆栈 - Prolog

时间:2014-06-08 13:54:01

标签: prolog

我试图在Prolog中编写一个简单版本的length/3

如果你看一下length/2的标准实现,它就是如下:

length([], 0).
length([Head|Tail], N) :-
    length(Tail, N1),
    N is 1+N1.

虽然我的代码使用了几乎相同的想法,但我得到的错误是“超出本地堆栈”,我认为这是因为深度递归。我无法理解为什么。我的代码:

mylength(_, [], 0).
mylength([H1|T1], [H1copy|T1copy], N) :-
    mylength([H1|T1], [T1copy], N1),
    N is N1 + 1.

1 个答案:

答案 0 :(得分:1)

您的谓词mylength/3存在以下问题。我认为 您想使用模式mylength(+,-,-)运行它。就是这样 第一个参数不是降序的情况。

问题是第二个子句,第一个参数[H1|T1] 在头部不变地传递给第一个参数 身体中的谓词,与长度/ 2中发生的情况相反。造成 在无限递归中,因为给定的第二个参数[T1copy]没有 匹配第一个条款。

无限递归会导致内存耗尽,因为 例如,每次调用都会为H1copy生成一个新变量。 特定的错误消息取决于Prolog系统。

再见

P.S。:可能出现了问题 在咨询谓词时。一个人获得单身警告 H1copy

但是例如在最新的SWI-Prolog版本中, 超出本地堆栈错误将需要一些时间,因为 SWI-Prolog可以收集垃圾。在^ C和g之后 我明白了:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.1.16)
Copyright (c) 1990-2014 University of Amsterdam, VU Amsterdam

Action (h for help) ? goals

[552,959] mylength([1, 2, 3], [[]], _G40)
[552,958] mylength('<garbage_collected>', '<garbage_collected>', _G40)
[552,957] mylength('<garbage_collected>', '<garbage_collected>', _G40)
[552,956] mylength('<garbage_collected>', '<garbage_collected>', _G40)
[552,955] mylength('<garbage_collected>', '<garbage_collected>', _G40)

我猜以上意味着在当下 在那里我打断了Prolog的翻译 调用堆栈已经深度为552959,即一半 一百万!

运行几分钟后,我得到以下内容 SWI-Prolog中的错误消息:ERROR: Out of local stack