splitup := proc(f::anything, r::{algebraic, name=algebraic}, vflag::boolean) options `Maple Advisor Database 1.00 for Maple V Release 4 and 5`, `Copyright (c) 1998 by Robert B. Israel. All rights reserved`; if (nargs > 3) then ERROR(`expects 2 or 3 arguments but received`, nargs) fi; if type(f, function) then if member(op(0, f), {int, Int}) then `splitup/int`(args) # integral elif member(op(0,f), {sum, Sum, product, Product}) then `splitup/sum`(args) # sum or product else map(splitup,args) # map over other functions fi elif type(f, {`=`,`+`,`*`,`^`,array,list,set}) then map(splitup,args) # could contain integral, sum or product else f # no need to map fi end; `splitup/int` := proc(f, r) local lims, lims1, lims2, b, c, bc, v1, v2, a; options `Maple Advisor Database 1.00 for Maple V Release 4 and 5`, `Copyright (c) 1998 by Robert B. Israel. All rights reserved`; lims := op(2, f); if not(type(lims, name=algebraic .. algebraic)) then RETURN(map(splitup,args)) fi; # indefinite integral v1:= op(1,lims); if typematch(r,v2::name=a::algebraic) then if v1 <> v2 then RETURN(map(splitup,args)) fi # wrong dummy variable else a:= r fi; bc:= op(2, lims); b := op(1, bc); c := op(2, bc); if signum(0,b-a,1) = 1 or signum(0,a-c,1) = 1 then RETURN(f) fi; # a <= b or >= c lims1 := v1 = b .. a; lims2 := v1 = a .. c; subsop(2 = lims1, f) + subsop(2 = lims2, f); end; `splitup/sum` := proc(f, r, vflag) local summand, lims, b, c, bc, s1, s2, v1, v2, a, f0; options `Maple Advisor Database 1.00 for Maple V Release 4 and 5`, `Copyright (c) 1998 by Robert B. Israel. All rights reserved`; summand:= op(1,f); lims := op(2, f); if not(type(lims,name=algebraic .. algebraic)) then RETURN(map(splitup,args)) fi; # indefinite or over RootOf v1 := op(1,lims); if typematch(r,v2::name=a::algebraic) then if v1 <> v2 then RETURN(map(splitup,args)) fi # wrong variable else a:= r fi; if type(a,constant) and not(is(a,integer)) then ERROR(a,`is not an integer`) # can't split sum or product # at non-integer constant fi; bc:= op(2, lims); b := op(1, bc); c := op(2, bc); if signum(0,b-a,1) = 1 or signum(0,a-c,0) = 1 then RETURN(f) fi; # out of bounds f0:= subs(Sum=add, sum=add, Product=mul, product=mul, op(0,f)); if type(a - b, numeric) and (nargs = 2 or vflag) then s1 := f0(subs(v1 = b+X, summand), X = 0 .. a - b - 1) else s1 := subsop(2 = (v1 = b .. a-1), f) fi; if type(c - a, numeric) and (nargs = 2 or vflag) then s2 := f0(subs(v1 = a+X, summand), X = 0 .. c - a) else s2 := subsop(2 = (v1 = a .. c), f) fi; if f0 = mul then s1*s2 else s1 + s2 fi; end;