2013-03-15 61 views
1

我想使用Prolog程序查找一系列的總和。爲此,我寫了下面的程序:Prolog中一系列的總和

pow(N,1,R):- R is N. 
pow(N,M,R):- X is M-1,pow(N,X,R1),R is R1*N. 

sum(N,1,R) :- R is N+1 . 
sum(N,M,R) :- X is M-1, X>1,sum(N,X,R1),pow(N,M,R2), R is (R1+R2). 

我想找到以下系列的總和:

1+n+n^2+n^3+..................+n^m 

我認爲這是上面的代碼是正確的。但是當我運行該程序時,它顯示輸出「否」。爲什麼?我嘗試了很多,但無法獲得預期的輸出。

+0

你能分享你如何調用總和謂詞? – 2013-03-15 23:00:07

+0

我用sum(2,7,R)調用sum謂詞。答案應該是255,但令人驚訝的是輸出是「否」。 – 2013-03-15 23:03:00

回答

0

你錯過的X>1 else分支,如果你刪除它,你就會得到一個結果:

... 
sum(N,M,R) :- X is M-1, sum(N,X,R1), pow(N,X,R2), R is (R1+R2). 
... 
?- sum(2,3,X). 
X = 15 ; 
^C 

但程序不會終止(^ C用來打斷循環)。

我想重寫使用蓄電池,獲得由LCO(最後召集優化)允許更好的效率和內置的數值:

sum(N,M,R) :- sum(N,M,0,R). 

sum(N,M,A,R) :- 
    ( M > 0 
    -> A1 is A + N^M, %% N**M, 
     M1 is M-1, 
     sum(N,M1,A1,R) 
    ; R is A + 1 
    ). 

編輯 SWI-Prolog的文檔中關於運營商(**)/2是不正確的:最好使用(^)/ 2,由@false

+0

(^)/ 2應該用來代替(**)/ 2。 – false 2013-03-15 23:11:23

+0

@false:[docs](http://www.swi-prolog.org/pldoc/doc_for?object=f%28%28^%29/2%29)說**/2是ISO,而^/2是爲了向後兼容... – CapelliC 2013-03-15 23:15:05

+0

這些文檔是錯誤的。見http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#pow並且'(**)/ 2' **總是**在ISO中給出一個浮點數。 – false 2013-03-15 23:16:52

0

如說通過我的另一種解決方案是:

pow(N,1,R):- R is N. 
pow(N,M,R):- X is M-1,pow(N,X,R1),R is R1*N. 

sum(N,1,R) :- R is N+1 . 
sum(N,M,R) :- M>1,X is M-1,sum(N,X,R1), R is (R1+N**M).