

Min(a,b):= If(a<b,a,b);
Max(a,b):= If(a>b,a,b);

Min(list):=
[
  Local(result);
  result:= list[[1]];
  ForEach(item,Tail(list)) result:=Min(result,item);
  result;
];
Max(list):=
[
  Local(result);
  result:= list[[1]];
  ForEach(item,Tail(list)) result:=Max(result,item);
  result;
];

/* Factorials */
RuleBase("!",{n});
Rule("!",1,0,n = 0) 1;
Rule("!",1,1,IsInteger(n) And n>0) Factorize(i,1,n,i);


Function("Sum",{sumvar,sumfrom,sumto,sumbody})
[
   Local(sumi,sumsum);
   sumsum:=0;
   For(sumi:=sumfrom,sumi<=sumto,sumi++)
       [
        MacroLocal(sumvar);
        MacroSet(sumvar,sumi);
        sumsum:=sumsum+Eval(sumbody);
       ];
   sumsum;
];
UnFence("Sum",4);
HoldArg("Sum",sumvar);
HoldArg("Sum",sumbody);

Function("Sum",{sumlist})
[
   Local(sumi,sumsum);
   sumsum:=0;
   ForEach(sumi,sumlist) sumsum:=sumsum+sumi;
   sumsum;
];

Average(list):=Sum(list)/Length(list);

Function("Factorize",{sumvar,sumfrom,sumto,sumbody})
[
   Local(sumi,sumsum);
   sumsum:=1;
   For(sumi:=sumfrom,sumi<=sumto And sumsum!=0,sumi++)
       [
        MacroLocal(sumvar);
        MacroSet(sumvar,sumi);
        sumsum:=sumsum*Eval(sumbody);
       ];
   sumsum;
];
UnFence("Factorize",4);
HoldArg("Factorize",sumvar);
HoldArg("Factorize",sumbody);

Function("Taylor",{taylorvariable,taylorat,taylororder,taylorfunction})
[
  Local(n,result,dif,polf);
  [
    MacroLocal(taylorvariable);

    result:=Apply("Limit",{taylorvariable,taylorat,taylorfunction});
/*
    MacroSet(taylorvariable,taylorat);
    result:=Eval(taylorfunction);
*/
  ];
  dif:=taylorfunction;
  polf:=(taylorvariable-taylorat);
  For(n:=1,n<=taylororder,n++)
  [
    dif:= Deriv(taylorvariable) dif;
    MacroLocal(taylorvariable);

    result:=result+Apply("Limit",{taylorvariable,taylorat,(dif/(n!))})*(polf^n);
/*
    MacroSet(taylorvariable,taylorat);
    result:=result+(Eval(dif)/(n!))*(polf^n);
*/    
  ];
  result;
];


RuleBase("Fibonacci",{n});
Rule("Fibonacci",1,0, IsInteger(n) And IsZero(n-1)) 1;
Rule("Fibonacci",1,0, IsInteger(n) And IsZero(n-2)) 1;
Rule("Fibonacci",1,1, IsInteger(n) And n > 2)
[
  Local(i,a1,a2,result);
  i:=3;
  a1:=1;
  a2:=1;
  result:=a1+a2;
  While(i<n)
  [
    a1:=a2;
    a2:=result;
    result:=a1+a2;
    i++;
  ];
  result;
];

