#============================================================================= # This is a substitute for the Maple limit(). The only difference # is that the test on argument 'a' as a form name=algebraic has # been done properly. In the Maple version, the lazy programmer # tested 'a' for type 'point', which is a stupid thing to do and # causes problems if 'point' is ever redefined (as it is in, # e.g., AESOP). See the NOTE for my routine `type/point` in # objects.p for more info. #============================================================================= # # Have to do this first, since 'limit' is a Maple reserved name. # unprotect(limit): limit := proc(expr1,a,dir) local ddir,x,y,L,expr,r,W; # options `Copyright 1993 by Waterloo Maple Software`,trace; # # This is the erroneous line: # # if nargs < 2 or 3 < nargs or not type(expr1,algebraic) or not type(a,point) then # # Here is the fix: # if nargs < 2 or 3 < nargs or not type(expr1,algebraic) then ERROR(`invalid arguments`) fi; if not type(op(1,a),name) or not type(op(2,a),algebraic) then ERROR(`invalid second argument`) fi; # # From here on, no changes have been made. # if nargs = 3 and not member(dir,{'left','right','complex','real'}) then ERROR(`invalid directional argument`) fi; _Envsignum0 := '_Envsignum0'; if type(a,set) then r := `limit/multi`(args); if r = FAIL then RETURN('limit'(args)) else RETURN(r) fi fi; if has([args],`limit/X`) then RETURN(subs(y = `limit/X`,limit(op(subs(`limit/X` = y,[args]))))) fi; x := op(1,a); L := op(2,a); if not has(expr1,x) then RETURN(expr1) fi; if type(expr1,procedure) then expr := traperror(expr1(W)); if expr = lasterror then RETURN('limit(args)') fi else expr := subs(x = W,expr1) fi; if has(indets(expr,specfunc(anything,diff)),W) then RETURN('limit(args)') fi; if has(L,infinity) then if L <> infinity and L <> -infinity then ERROR(`invalid limiting point`) fi; if L = infinity then if nargs = 2 then r := `limit/limit`(subs(W = 1/`limit/X`,E = exp(1),expr),right); if r = FAIL then RETURN('limit(args)') else RETURN(r) fi fi else if nargs = 2 then r := `limit/limit`(subs(W = -1/`limit/X`,E = exp(1),expr),right); if r = FAIL then RETURN('limit(args)') else RETURN(r) fi fi fi; if dir = right and L = infinity or dir = left and L = -infinity then ERROR(`inconsistent direction with infinities`) fi; if dir = left then r := `limit/limit`(subs(W = 1/`limit/X`,E = exp(1),expr),right) elif dir = right then r := `limit/limit`(subs(W = -1/`limit/X`,E = exp(1),expr),right) else r := `limit/limit`(subs(W = 1/`limit/X`,E = exp(1),expr),dir) fi; if r = FAIL then RETURN('limit(args)') else RETURN(r) fi fi; if nargs = 3 then ddir := dir else ddir := real fi; if type(L,float) and not hastype(expr,float) then r := normal(expr); if not has(r,W) then RETURN(r) fi; if ddir = left then r := subs(W = L-`limit/X`,r); r := traperror(series(leadterm(r),`limit/X`,max(6,Order))) elif ddir = right then r := subs(W = L+`limit/X`,r); r := traperror(series(leadterm(r),`limit/X`,max(6,Order))) elif ddir = real then y := traperror(series(leadterm(r),W = L,max(6,Order))); r := subs(W = L-W,r); r := traperror(series(leadterm(r),W,max(6,Order))); if type(y,series) and type(r,series) and op(1,y) = op(1,r) and op(2,y) = op(2,r) then else r := 'r' fi else r := traperror(series(leadterm(r),W = L,max(6,Order))) fi; if type(r,series) then if op(2,r) = 0 then RETURN(op(1,r)) elif 0 < op(2,r) then RETURN(0) fi fi fi; if ddir = left then r := `limit/limit`(subs(W = L-`limit/X`,E = exp(1),expr),right) else r := `limit/limit`(subs(W = L+`limit/X`,E = exp(1),expr),ddir) fi; if r = FAIL then RETURN('limit(args)') else RETURN(r) fi end: # # re-protect limit() # protect(limit):