

RuleBase("AntiDeriv",{expr,var});

Rule("AntiDeriv",2,2,Not(Contains(VarList(expr),var)))
[
  expr*var;
];

Rule("AntiDeriv",2,3,Type(expr)="*" And Not(Contains(VarList(expr[[1]]),var)))
[
  expr[[1]]*AntiDeriv(expr[[2]],var);
];

Rule("AntiDeriv",2,3,Type(expr)="*" And Not(Contains(VarList(expr[[2]]),var)))
[
 expr[[2]]*AntiDeriv(expr[[1]],var);
];

Rule("AntiDeriv",2,4,Type(expr) = "+")
[
  AntiDeriv(expr[[1]],var)+AntiDeriv(expr[[2]],var);
];

Rule("AntiDeriv",2,4,Type(expr) = "-" And NrArgs(expr) = 2)
[
  AntiDeriv(expr[[1]],var)-AntiDeriv(expr[[2]],var);
];
Rule("AntiDeriv",2,4,Type(expr) = "-" And NrArgs(expr) = 1)
[
  -AntiDeriv(expr[[1]],var);
];

Rule("AntiDeriv",2,10,CanBeUni(expr,var))
[
     NormalForm(AntiDeriv(Apply("MakeUni",{expr,var}),var));
];

Rule("AntiDeriv",2,12,
IsUniVar(expr) And expr[[1]] = var)
[
  Local(base,result);
  base:=expr[[2]];
  result:=FlatCopy(expr[[3]]);
  For(i:=1,i<=Length(result),i++)
  [
    result[[i]]:= result[[i]]/(base+i);
  ];

  UniVariate(var,base+1,result);
];

/* Standard analytic function integration */
Rule("AntiDeriv",2,14,Type(expr)="Sin" And
     CanBeUni(expr[[1]],var) And Length(MakeUni(expr[[1]],var)[[3]]) <= 2
     )
[
  Local(uni);
  uni:=MakeUni(expr[[1]],var);
  -(1/Coef(uni,1))*Cos(expr[[1]]);
];

Rule("AntiDeriv",2,14,Type(expr)="Cos" And
     CanBeUni(expr[[1]],var) And Length(MakeUni(expr[[1]],var)[[3]]) <= 2
     )
[
  Local(uni);
  uni:=MakeUni(expr[[1]],var);
  (1/Coef(uni,1))*Sin(expr[[1]]);
];

Rule("AntiDeriv",2,14,Type(expr)="Exp" And
     CanBeUni(expr[[1]],var) And Length(MakeUni(expr[[1]],var)[[3]]) <= 2
     )
[
  Local(uni);
  uni:=MakeUni(expr[[1]],var);
  (1/Coef(uni,1))*Exp(expr[[1]]);
];

Rule("AntiDeriv",2,15,Type(expr)="*" And
                     CanBeUni(expr[[1]],var) And
                     Type(Apply("AntiDeriv",{expr[[2]],var})) != "AntiDeriv")
[
  Local(anti);
  anti:=Apply("AntiDeriv",{expr[[2]],var});
  expr[[1]]*anti-
    Apply("AntiDeriv",{anti*Deriv(var)expr[[1]],var});
];

Rule("AntiDeriv",2,15,Type(expr)="*" And
                     CanBeUni(expr[[2]],var) And
                     Type(Apply("AntiDeriv",{expr[[1]],var})) != "AntiDeriv")
[
  Local(anti);
  anti:=Apply("AntiDeriv",{expr[[1]],var});
  expr[[2]]*anti-
    Apply("AntiDeriv",{anti*Deriv(var)expr[[2]],var});
];


RuleBase("Integrate",{var,from,to,expr});
HoldArg("Integrate",var);
HoldArg("Integrate",expr);
Rule("Integrate",4,1,Type(Apply("AntiDeriv",{expr,var})) != "AntiDeriv")
[
  Local(ad,result);
  MacroLocal(var);
  ad:=Apply("AntiDeriv",{expr,var});
  MacroSet(var,to);
  result:=Eval(ad);
  MacroSet(var,from);
  result:=result-Eval(ad);
  result;
];



