2009-08-27 65 views
4
pred(Args). 
pred(Args) :- 
    goalA, 
    goalB, 
    !, 
    pred(Args). 
pred(Args) :- 
    goalC, 
    goalD, 
    !, 
    pred(Args). 

通常我會寫一個關於內存性能的遞歸謂詞,它與上面的代碼片段相關。切割被用來試圖強制尾巴呼叫優化發生。我最近經歷了一個大的序言代碼庫,並且發現了一些例子,其中的切割實際上是在遞歸調用之後,而不是在它之前。大概這有防止尾部呼叫優化發生而不是協助它的效果。在Prolog中遞歸謂詞的末尾處切割

我的問題是我可以將遞歸調用之後的剪切移動到它之前的位置,而不會影響程序的含義嗎?這是假設在謂詞的每個子句中都有相同的相對位置。

現在我一直在想這件事,我想也許答案是「不一定」,但是在調用之前用切割重寫了所有的代碼並發現測試套件仍在傳遞,我也想知道是否可能有其他一些深奧的理由來編寫這樣的謂詞。或者它只是糟糕的編碼?

回答

2

我的猜測是,這可能是壞的編碼(或誤會什麼筆者在做什麼)

我會這麼說,是因爲我自己,做一次同樣的錯誤:

https://mailbox.iai.uni-bonn.de/mailman/public/swi-prolog/2009/001540.html

http://xonix.habrahabr.ru/blog/60430/(警告,俄語)

但人們從SWI郵件列表證實,尾遞歸碼正確的做法是

head :- 
     <guard goals>, !, 
     <deterministic stuff>, 
     head. 
head :- 
     ... 
+0

由於我移動切割並沒有改變代碼在所有測試用例中的行爲方式,我認爲你可能是對的 - 它只是編碼不好。 – nedned 2009-08-29 07:01:13