我在序言很生疏,但我不知道爲什麼這樣的事情會失敗:序言:錯誤出全球棧的看上去像是一個級別的遞歸我
frack(3).
frack(X) :- frack(X-1).
所以,如果我評價弗蘭克•(4)。從定義的上述事實的互動提示下,我期望它不應該無休止地遞歸,因爲4-1 = 3。但我得到這個錯誤在SWI-Prolog的:
ERROR: Out of global stack
我在序言很生疏,但我不知道爲什麼這樣的事情會失敗:序言:錯誤出全球棧的看上去像是一個級別的遞歸我
frack(3).
frack(X) :- frack(X-1).
所以,如果我評價弗蘭克•(4)。從定義的上述事實的互動提示下,我期望它不應該無休止地遞歸,因爲4-1 = 3。但我得到這個錯誤在SWI-Prolog的:
ERROR: Out of global stack
試試:
?- 4-1 = 3.
false.
爲什麼?因爲4-1 = -(4, 1)
,這顯然不是一個數字,而是一個複合詞。
推理有關的Prolog整數,使用clpfd約束,例如(使用GNU 的Prolog或B-的Prolog):
| ?- 4-1 #= X. X = 3
在SWI-Prolog中,給你看圖形示蹤劑可能是有用發生的事情:
?- gtrace, frack(4).
對於更復雜的調試,我建議failure-slice如圖false's answer。
序言不會做算術除非您使用IS操作:
frack(X) :- X1 is X-1, frack(X1).
frack(X) :- frack(X-1).
應該
frack(X) :- Y is X - 1, frack(Y).
你寫它的方式,X-1
表達第一級統一與X
變量在下一級別,永遠不會爲frack(3)
事實。
感謝您使用「統一」一詞。現在它再次合理。我上次在1989年做過序言。這已經有一段時間了。 – 2012-02-10 14:39:46
@WarrenP哇,所以你比我老一輩!我最後在1996年做了Prolog :) :) – dasblinkenlight 2012-02-10 14:44:27
您的解決方案仍然沒有終止。 – false 2012-11-15 12:05:53
這是未終止的原因。您的查詢將不會終止,因爲你的程序的failure-slice不終止:
?- frack(4).frack(3) :- false. frack(X) :- frack(X-1), false.
只能在可見部分修改的東西解決這個問題。三個SO答案建議使用(is)/2
。但是這不會消除非終止!事實上,使用(is)/2
導致基本相同片段:
?- frack(4).frack(3) :- false. frack(X) :- Y is X - 1, frack(Y), false.
至少,現在frack(4)
成功,但它會在回溯循環。您必須在可見部分更改某些內容,例如X
的一些測試,以避免不終止。有關更多信息,請參見failure-slice。
我不知道SWI有。太好了! – 2012-02-10 14:40:45