2013-03-15 70 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).