簡體   English   中英

錯誤:未處理的異常:超出本地堆棧 - Prolog

[英]ERROR: Unhandled exception: Out of local stack - 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.

你的謂詞mylength/3有以下問題。 我假設你想用模式mylength(+,-,-)運行它。 那么第一個參數不是下降的情況。

問題是第二個子句,其中頭部中的第一個參數[H1|T1]更改地傳遞給正文中同一謂詞的第一個參數,這與length / 2中發生的情況相反。 導致無限遞歸,因為給定的第二個參數[T1copy]與第一個子句不匹配。

無限遞歸可能導致內存耗盡,因為例如每次調用都會為H1copy生成一個新變量。 特定的錯誤消息取決於Prolog系統。

再見

PS:在咨詢謂詞時可能會出現問題。 一個人獲得了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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM