Program in Prolog for sum of numbers in interval

假如想象 提交于 2020-01-11 11:46:33

问题


I'm trying to create a program in Prolog which takes two numbers - A and B and finds the sum of the numbers from A to B, including them.

To sum up: sum(1, 5, C) should find that C is 1+2+3+4+5 = 15

This is my code, which is not working :(

sum(A, B, C) :- A =< B, A1 is A+1, C1 is C+A, sum(A1, B, C1).

And then I test it with sum(1, 5, C).

What I get is ERROR: is/2: Arguments are not sufficiently instantiated, but I can't really get what is the problem. :(

Could you please help me to understand why it's not working and how to fix it? Thank you very much in advance! :)


回答1:


You can't instantiate C1 as C+A because C is not yet an integer.

Let's call sum(1, 5, C)

sum(1, 5, C)

---> 1 =< 5 ... true

---> A1 is 1 + 1 ... A1 = 2 (fine)

---> C1 is C + 2, C = something like _G232, not yet instantiated.

Let's take a look at your logic.

We would have a base case, when A and B are equal, that will be our 'starting' sum

sum(X,X,X).

Then we have our general case. each recursive call will give us the sum from k + 1 to n where we call sum(k,n,sum).

sum(A, B, C):- A =< B, A1 is A + 1, sum(A1,B,C1), C is C1 + A.



回答2:


Available in SWI-Prolog, library(aggregate) is a full fledged interface:

?- aggregate(sum(N), between(1,5,N), S).
S = 15.

it does internally a similar work as you can read in Kaarel' answer. Anyway, to learn Prolog, follow C.B. detailed explanation.




回答3:


In SWI-Prolog, the simplest way to implement it is:

?- numlist(1, 5, List), sum_list(List, Sum).
List = [1, 2, 3, 4, 5],
Sum = 15.

Your code tries to evaluate C+A but C is not known yet, therefore the error message.

Btw, you can also calculate this sum directly, without any iteration or list generation, see https://math.stackexchange.com/questions/50485/sum-of-n-consecutive-numbers




回答4:


I suppose you could use brute force to compute the sum of a finite arithmetic sequence, but wouldn't it be easier just to use your maths?

sum(A,B,X) :-
  A =< B ,
  N is 1+B-A ,
  X is N*(A+B) / 2
  .

Or, more generally, for computing the sum of a finite sequence of n terms, starting with a, with a "step size" (relative difference) of d, you get:

sum(A,D,N,S) :- S is (N*(2*A+(N-1)*D))/2 .

But if you're going to use brute force, make it tail recursive:

sum(A,B,S) :- A =< B , sum(A,B,0,S) .

sum(A,B,S,S) :-
  A > B
  .
sum(A,B,T,S) :-
  A =< B ,
  T1 is T+A ,
  A1 is A+1 ,
  sum(A1,B,T1,S)
  .


来源:https://stackoverflow.com/questions/21295094/program-in-prolog-for-sum-of-numbers-in-interval

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!