2013-11-01 49 views
1

我是新來的prolog。我正在做一個遞歸程序,問題是,即使它打印答案..它不會停止打印答案後,並最終給「本地堆棧」。 我讀過它可能是一個左遞歸問題,但正如我已經告訴過你,我是新來的序言,我真的不明白會發生什麼...... 所以..這裏的代碼。序言遞歸錯誤(簡單)

f(X, Y):- 
    Y is sqrt(1-((X-1)*(X-1))). 

sum(SEGMENTS, 1, TOTAL):- 
    f(2/SEGMENTS*1,H1), 
    TOTAL is (2/SEGMENTS)*H1. 

sum(SEGMENTS, NR, TOTAL):- 
    N1 is (NR-1), 
    sum(SEGMENTS, N1, S1), 
    f(2/SEGMENTS*NR,H1), 
    f(2/SEGMENTS*N1,H2), 
    TOTAL is S1 + (2/SEGMENTS)*((H1+H2)/2). 

它應該用梯形規則或類似的東西來計算半圓區域。 正如我已經告訴你..它確實完成,但在達到基本案例總和(段,1,總)它調用第二個替代功能...:S

謝謝你們!

另外:這是我得到當我運行它

?- sum(3000,3000,TOTAL). 
TOTAL = 1.5707983753431007 ; 
ERROR: Out of local stack 
+0

非常感謝!是的,當我追查它時,我注意到了它..我試圖避免IF條款:) –

+0

mbratch,請添加您的答案作爲答案,以便我可以將其標記爲已回答並給予您信用:) –

+0

謝謝@ p.chang。我添加了一個答案。 – lurker

回答

1

的問題是,回溯將嘗試在第二sum條款1NR值的情況下,第一款成功後。這會導致一個很長的遞歸過程(因爲對於每個遞歸調用NR都會不斷遞減,試圖繞過所有負整數值等等)。

解決問題的一種簡單方法是在第二個sum子句中。鑑於意圖是,它是對的NR > 1的情況下,把NR > 1作爲第一個發言:

sum(SEGMENTS, NR, TOTAL) :- 
    NR > 1, 
    N1 is (NR-1), 
    sum(SEGMENTS, N1, S1), 
    f(2/SEGMENTS*NR,H1), 
    f(2/SEGMENTS*N1,H2), 
    TOTAL is S1 + (2/SEGMENTS)*((H1+H2)/2). 

還要注意的是表達f(2/SEGMENTS*NR, H1)不計算表達式2/SEGMENTS*NR並將它傳遞給f。它實際上象徵性地傳遞了該表達式。它恰好在這裏工作,因爲f將它包含在一個is的右側,因此可以根據需要進行評估。如果你追蹤它,你會明白我的意思。

+0

非常感謝你! –