簡體   English   中英

Prolog Nim Game - 超出本地堆棧錯誤

[英]Prolog Nim Game - Out of local stack error

我最近一直在做一些Prolog。 我讀過Prolog的藝術書。 他們在那里有一個Nim游戲實現。 因此,我已將其重寫為SWI-Prolog,除了出現Out of local stack錯誤外,其他一切似乎都不錯。 調試之后,我發現它似乎在程序的這一部分永遠循環:

nim_sum([N|Ns],Bs,Sum):-
      binary(N,Ds), nim_add(Ds,Bs,Bs1), nim_sum(Ns,Bs1,Sum).
nim_sum([],Sum,Sum).

nim_add(Bs,[],Bs).
nim_add([],Bs,Bs).
nim_add([B|Bs],[C|Cs],[D|Ds]):-
    D is (B+C) mod 2, nim_add(Bs,Cs,Ds).

有沒有人遇到過這種問題? 對於某些替代實施的任何建議?

為了避免“棧外”問題,通常有必要以“最后調用優化”或“尾遞歸”形式編寫遞歸謂詞。

在這里,似乎應該反轉nim_sum / 3的兩個子句(首先輸入“ fact”子句,這是終止條件)。 然后調用nim_sum / 3使自己在具有正文的子句中沒有任何回溯點打開(假設二進制/ 2nim_add / 3是確定性的)。

嘗試將這兩個子句交換為nim_sum,並告訴我們它是如何工作的。

補充:在進一步思考nim_add / 3之后 ,我懷疑Prolog引擎可能無法檢測到它是確定性的,即僅以一種方式成功。 這是削減工作! 運營商。 最簡單的解決方案是在nim_sum / 3調用自身的位置前面添加一個剪切,這樣在遞歸調用時肯定沒有打開回溯點。 但是,這更符合Prolog的精神:

nim_sum([],Sum,Sum).  
nim_sum([N|Ns],Bs,Sum):-  
    binary(N,Ds),  
    nim_add(Ds,Bs,Bs1),  
    nim_sum(Ns,Bs1,Sum).  

nim_add(Bs,[],Bs) :- !.  
nim_add([],Bs,Bs) :- !.  
nim_add([B|Bs],[C|Cs],[D|Ds]):-  
    D is (B+C) mod 2,  
    nim_add(Bs,Cs,Ds).  

同樣,這假設二進制/ 2是確定性的,可能是將整數(非負?)轉換為0和1的列表,首先是最低有效位。

暫無
暫無

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

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