Page 1 of 1

### HOW CAN I CACULATE THE SUM OF HUGE LIST OF REALS WITHOUT STACK OVERFLOW .

Posted: 21 Oct 2011 21:56
My Dear friends
I have a huge list of Reals Like [22222,35555,98989,........].
I would like to calculate the sum of all list Elements ,
when i Use non tail Recursive Procedure i got
Stack overflow Error ??
Any one Can Help me ???
thanks

### this solution worked without stack overflow .. any comment my friends ....

Posted: 21 Oct 2011 22:51

Code: Select all

``````predicates
% calculate the sum of list of Reals
list_sum:(real* List ,real Start ,real Result)procedure (i,i,o).

clauses
list_sum([],R,R).

list_sum([H|T],Start,Result):-
NewStart=H+Start,
list_sum(T,NewStart,Result).

goal
list_sum(List,0,Result).``````
abdelrahman

Posted: 22 Oct 2011 1:31
the simplest way I would do this is:

Code: Select all

``````facts
realtotal :(real) :=0.0.

predicates
% calculate the sum of list of Reals
list_sum:(real* List )procedure (i).

clauses
list_sum([]).

list_sum([H|T]):-
realtotal :=H+realtotal ,
list_sum(T).

goal
realtotal:=0.0, % makes sure its starts at 0
list_sum(List),
stdio::write(toString(realtotal)). ``````
single pass with no backtracking. would handle a list of any size with no memory issues.

### My Dear paul Thank you , but can i use this with wide scope .

Posted: 22 Oct 2011 23:02
My Dear Paul , thank you very much for your sentences ,
but i have an explanation ,
can i use this predicate with wide scope through many classes or
hence it uses object fact , it should be used locally at the scope of current class .
forgive me I am so novice in OOP.
Need more Declaration , thanks for your interest ...
abdelrahman

Posted: 23 Oct 2011 7:42
Hi, I don't understand why you get a stack overflow with your code. Your code is correct. How many numbers are you adding? Maybe it is the list itself causing the problem, and not the summing. But I have made a list of 10^6 reals with no problem.

Anyway, the following adjustments to Paul's code should work. It is not very nice, but maybe it will avoid the stack overflow.

1) Make the predicate a class predicate. Declare it in the .cl file (and then it can be used anywhere in your program):

Code: Select all

``````predicates
list_sum:(real* List )->real.``````
2) In the pro file:

Code: Select all

``````class facts
realtotal :(real) :=0.0.

clauses
list_sum([])=real_total:-!.

list_sum([H|T])=0:-
realtotal :=H+realtotal ,
_=list_sum(T).
``````
Try it and see.
cheers
Steve

### MY Dear Steve , thank you for your interest ...

Posted: 23 Oct 2011 15:29
My Dear Steve ,
the code i've published here is working and not the code that produces Stack overflow ,
the one that produced stack overflow was non_tail Recursive one . i didn't write it ,
i replaced it with this new one . but i expected that i am novice and you with many other friends are professionals and can write more elegant and effective code .
the global declaration you wrote is the effective one that i am searching for it to use the predicate with wide scope through many classes ...
thank you Very much Steve ..
abdelrahman

Posted: 24 Oct 2011 14:56
Personally, I am not very happy about using class facts as local temporary variable of a predicate.

So I prefere your own solution.

If you insist on using a modifiable variable, then I would suggest that you use the varM class:

Code: Select all

``````clauses
list_sum(L) = Sum:value :-
Sum = varM::new(0),
foreach V = list::getMember_nd(L) do
Sum:value := Sum:value+V
end foreach.``````

Posted: 24 Oct 2011 15:00
very interesting Thomas, I did not know we had that capability.

I used the class facts because I did not know about the varM class.

thanks

Posted: 24 Oct 2011 15:37
Hi,
I keep forgetting to use varM!! cheers
Steve

### My Dear Thomas , thanks .

Posted: 25 Oct 2011 3:25
My Dear Thomas , thanks for your New Idea ,
actually by Trial , unfortunately Steve's code also produced a stack over flow ,,,
so i returned to the working Tail recursive code .
I didn't try your code yet and Because I didn't use the varM Class Before ,studying For Each , hence
your code needs me more time to understand ...
on my opinion , I think simple ideas directly using variables are much more easier when works efficiently .
Again ,
Thanks ...

Posted: 25 Oct 2011 12:01
Another way: list::forAll() is the same foreach...getMember_nd loop.

Code: Select all

``````clauses
list_sum(L) = Sum:value :-
Sum = varM::new(0),
list::forAll(L,{(V):- Sum:value := Sum:value+V}).``````

Posted: 20 Nov 2011 16:24
Thomas,
is varM only in VIP 7.3 and later. I tried to use it in a 7.2 application it came back as unknown.

P.

Posted: 20 Nov 2011 19:17
Yes, varM was introduced in Vip7.3 together with the collection library; all requiring generic interfaces and classes (introduced in Vip 7.3)

Posted: 20 Nov 2011 19:34
thanks Thomas,

at least now I know I am not completely crazy (although I know a few folks who might argue the fact) 