%mathpiper,def="Sum"

/* Sums */


Rulebase("Sum",{sumvar'arg,sumfrom'arg,sumto'arg,sumbody'arg});




10  # Sum(_sumvar,sumfrom_IsNumber,sumto_IsNumber,_sumbody)_(sumfrom>sumto) <-- 0;

20 # Sum(_sumvar,sumfrom_IsNumber,sumto_IsNumber,_sumbody)_(sumto<sumfrom) <--
     ApplyFast("Sum",{sumvar,sumto,sumfrom,sumbody});
30 # Sum(_sumvar,sumfrom_IsNumber,sumto_IsNumber,_sumbody) <--
LocalSymbols(sumi,sumsum)[
   Local(sumi,sumsum);
   sumsum:=0;
   For(sumi:=sumfrom,sumi<=sumto,sumi++)
       [
        MacroLocal(sumvar);
        MacroBind(sumvar,sumi);
        sumsum:=sumsum+Eval(sumbody);
       ];
   sumsum;
];

UnFence("Sum",4);
HoldArgument("Sum",sumvar'arg);
HoldArgument("Sum",sumbody'arg);



40 # Sum({}) <-- 0;

50 # Sum(values_IsList) <--
[
   Local(i, sum);
   sum:=0;
   ForEach(i, values) [ sum := sum + i; ];
   sum;
];

%/mathpiper



%mathpiper_docs,name="Sum",categories="User Functions;Series"
*CMD Sum --- find sum of a sequence
*STD
*CALL
        Sum(list)
	Sum(var, from, to, body)

*PARMS

{list} -- list of values to sum

{var} -- variable to iterate over

{from} -- integer value to iterate from

{to} -- integer value to iterate up to

{body} -- expression to evaluate for each iteration

*DESC

The first form of the {Sum} command simply
adds all the entries in "list" and returns their sum.

If the second calling sequence is used, it finds the sum of
the sequence generated by an iterative formula. 
The expression "body" is
evaluated while the variable "var" ranges over all integers from
"from" up to "to", and the sum of all the results is
returned. Obviously, "to" should be greater than or equal to
"from".

Warning: {Sum} does not evaluate its arguments {var} and {body} until the actual loop is run.

*E.G.

In> Sum({1,2,3})
Result> 6

In> Sum(1 .. 10);
Result: 55;

In> Sum(i, 1, 3, i^2);
Result: 14;

*SEE Product
%/mathpiper_docs