0patches.red 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175
  1. module patches; % Patches to correct problems in REDUCE 3.7.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 2001 Anthony C. Hearn. All Rights Reserved.
  4. global '(patch!-date!*);
  5. patch!-date!* := "7-Sep-2001";
  6. % Bugs fixed by these patches.
  7. % 28 Jun 99. Gnuplot handling on the Macintosh was not correct.
  8. % 7 Aug 99. The evaluation of df(tan((sqrt(1-x^2)*asin acos x
  9. % + 2*sqrt(1-x^2)*x)/x),x) did not terminate.
  10. % 20 Oct 99. The sequence a1:=12x^2-16x+3; a2:=3x-4; off mcd;
  11. % on combineexpt; e^(a1/a2); gave the wrong answer.
  12. % 8 Nov 99. factorize(2*c*s*u^3*v^5-2*c*s*u^3*v +2*c*s*u*v^5-2*c*s*u*v
  13. % -s^2*u^4*v^4+s^2*u^4+s^2*u^2*v^6-s^2*u^2*v^4-s^2*u^2*v^2
  14. % +s^2*u^2 +s^2*v^6-s^2*v^2+u^4*v^4-u^4*v^2 -v^4+v^2) gave
  15. % a catastrophic error.
  16. % 9 Nov 99. Patched procedures generated a "redefined" message.
  17. % 16 Nov 99. Some EXCALC calculations could cause a catastrophic error.
  18. % 18 Dec 99. Integrations could give catastrophic errors because some
  19. % kernels were not unique.
  20. % 31 Jan 00. The sequence weight x=1,y=1; wtlevel 10; factor x; led to
  21. % the error that x was invalid as a kernel.
  22. % 5 Feb 00. The sequence x := mat((1,2)); sign sqrt 42; led to a
  23. % spurious error.
  24. % 6 Feb 00. The sequence on complex; sqrt(i*sqrt(3)-1); gave a wrong
  25. % result.
  26. % 10 Feb 00. Some root evaluations could lead to an error like
  27. % <equation> invalid as scalar.
  28. % 18 Feb 00. A sequence like m := mat((a,b),(c,d)); det sub(a=1,m);
  29. % would cause a type mismatch error.
  30. % 18 Apr 00. Complaints about the pattern matching limit of 5 terms
  31. % are resolved by the addition of a variable matchlength!*,
  32. % whose initial value of 5 can be changed as needed.
  33. % 22 Apr 00. The RULE mechanism left spurious expressions in various
  34. % non-local variables.
  35. % 28 Jul 00. A sum index within a derivative was treated as an identifier
  36. % (e.g., sum(x^n/factorial n*sub(x=0,df(cos x,x,n)),n,0,5);
  37. % 2 Aug 00. With complex on, some factorizations seemed to run forever
  38. % (e.g., factorize (400y^12+400y^10*z+40y^9*z^2+100y^8*z^2
  39. % +20y^7*z^5+120y^7*z^4+20y^7*z^3+41y^6*z^4+60y^5*z^7
  40. % +60y^5*z^5+20y^4*z^7+6y^4*z^6+20y^4*z^5
  41. % +2y^3*z^6+9y^2*z^8+6y*z^8+z^8))
  42. % 29 Aug 00. The sequence load_package gentran,scope; matrix a(10,10);
  43. % on gentranopt; gentran a(1,1) ::=: a(1,1); caused a
  44. % segmentation violation or similar error.
  45. % 19 Sep 00. Clearing some sqrt rules could lead to a spurious
  46. % "not found" message.
  47. % 20 Sep 00. The sequence load_package algint;
  48. % int(1/sqrt((2*e^c-y)/(e^c*y)),y);
  49. % caused a catastrophic error.
  50. % 8 Nov 00. Some sequences did not optimize completely when the SCOPE
  51. % command "optimize" was used.
  52. % 20 Nov 00. The sum operator did not always preserve a noncom order
  53. % (e.g., noncom u,v; sum(u(m)*v(1-m),m,0,1);)
  54. % 12 Dec 00. int with four arguments did not automatically load the
  55. % defint package.
  56. % 13 Dec 00. Some gcd calculations could produce an endless loop. E.g.,
  57. % in on numval,rounded; y:=x^4+x3*x^3+x2*x^2+x1*x+x0;
  58. % on fullroots; solve(y,x);
  59. % 9 Jan 01. SOLVE did not return results in same order as the given
  60. % variables (e.g., solve({y=x+t^2,x=y+u^2},{x,y,u,t});
  61. % 14 Jan 01. Some resultants (e.g. resultant(p^3-3p^2-a,3p*(p-2),p))
  62. % caused an error.
  63. % 19 Jan 01. Some algebraic integrals could produce a catastrophic
  64. % error when the algint package was loaded.
  65. % 22 Jan 01. Some algebraic integrals could produce a spurious zero
  66. % divisor message when the algint package was loaded (e.g.,
  67. % int((sqrt((-sqrt(a^4*x^2+4)+a^2*x)/(2*x))
  68. % *(-sqrt(a^4*x^2+4)*a^2*x-a^4*x^2-4))/(2*(a^4*x^2+4)),x))
  69. % 23 Jan 01. Inverses of matrices containing non-commuting objects
  70. % could be incorrect (e.g. noncom q; 1/mat((1,0,0),
  71. % (x/p*q 1,1,0),(x*y/(2p*(p-1))*q 1*q 1,y/(p-2)*q 1,1))).
  72. % 2 Feb 01. Some calls of SOLVE could produce a "zero divisor" error
  73. % error (e.g., solve(sqrt x*sqrt((4x^2*x+1)/x)-1=0,x)).
  74. % 9 Feb 01. The patched version of combine!-logs included an undefined
  75. % macro.
  76. % 20 Feb 01. Even with combineexpt on, expressions like a*a^x and
  77. % e*e^(2/(2-x)) did not simplify adequately.
  78. % 6 Mar 01. With algint loaded, some integrals would abort before
  79. % completion (e.g., int((x^(2/3)*sqrt(sqrt(y)*sqrt(pi) + 2pi
  80. % *y*x)*sqrt(- sqrt(y)*sqrt(pi)+2pi*y*x))/(4pi*y*x^3 - x),x)).
  81. % 7 Apr 01. Factorizations with rounded and complex rounded were not
  82. % supported.
  83. % 23 Apr 01. A term could be dropped from the solution of a set of
  84. % linear equations involving surds.
  85. % 7 May 01. Patches of 19 Sep 00 updated to correct bug.
  86. % 1 Jun 01. With precise on, sqrt(x^2) returned x rather than abs(x).
  87. % 11 Jun 01. Expressions involving noncommuting arguments of a
  88. % commuting operator were not handled correctly.
  89. % E.g., operator p,q; noncom q; p q a*p q b -p q b*p q a;
  90. % 15 Jun 01. Patch of 9 Jan 01 gave a catastrophic error with depend
  91. % statements, e.g., depend u,z; solve(u=y/x,z).
  92. % 7 Aug 01. Resultants could return an error or the wrong sign
  93. % (replaces patch of 14 Jan 01).
  94. % 9 Aug 01. Rules for tan, like let tan(~x)=>sin x/cos x, made some
  95. % integrals not return a closed form (e.g., int(1/sin(y)^2,y)).
  96. % 24 Aug 01. Some factorizations with complex on could have the wrong
  97. % sign.
  98. % 7 Sep 01. Some solve problems could cause a catastrophic error in
  99. % SQFRF.
  100. % Alg declarations.
  101. fluid '(matchlength!*);
  102. matchlength!* := 5;
  103. flag('(matchlength!*),'share);
  104. fluid '(!*sqrtrulep);
  105. patch alg;
  106. % 20 Oct 99, 20 Feb 01.
  107. symbolic procedure exptunwind(u,v);
  108. begin scalar x,x1,x2,y,z,z2;
  109. a: if null v then return u;
  110. x := caar v;
  111. x1 := cadr x;
  112. x2 := caddr x;
  113. y := cdar v;
  114. v := cdr v;
  115. if !*combineexpt and length u=1 and null cdr(z2 := kernels u)
  116. then u := {(({'expt,car z2,ldeg u} . 1) . lc u)};
  117. while (z := assocp1(x1,v)) and
  118. (z2 := simp {'plus,{'times,x2,y},{'times,caddar z,cdr z}})
  119. and (!*combineexpt or (fixp numr z2 and fixp denr z2))
  120. do <<if fixp numr z2 and fixp denr z2
  121. then <<x2 := divide(numr z2,denr z2);
  122. if car x2>0
  123. then <<if fixp x1 then u := multf(x1**car x2,u)
  124. else u := multpf(mksp(x1,car x2),u);
  125. z2 := cdr x2 ./ denr z2>>;
  126. y := numr z2>>
  127. else y := 1;
  128. x2 := prepsq(quotf(numr z2,y) ./ denr z2);
  129. v := delete(z,v)>>;
  130. if !*combineexpt and y=1 and fixp x1 then
  131. <<while (z := assocp2(x2,v)) and cdr z=1 and fixp cadar z do
  132. <<x1 := cadar z * x1; v := delete(z,v)>>;
  133. if eqcar(x2,'quotient) and fixp cadr x2 and fixp caddr x2
  134. and cadr x2<caddr x2
  135. then <<z := nrootn(x1**cadr x2,caddr x2);
  136. if cdr z = 1 then u := multd(car z,u)
  137. else if car z = 1
  138. then u := multf(formsf(x1,x2,1),u)
  139. else <<u := multd(car z,u);
  140. v := (list('expt,cdr z,x2) . 1) . v>>>>
  141. else u := multf(formsf(x1,x2,y),u)>>
  142. else u := multf(formsf(x1,x2,y),u);
  143. go to a
  144. end;
  145. % 31 Jan 00.
  146. symbolic procedure factor1(u,v,w);
  147. begin scalar x,y,z,r;
  148. y := lispeval w;
  149. for each j in u do
  150. if (x := getrtype j) and (z := get(x,'factor1fn))
  151. then apply2(z,u,v)
  152. else <<while eqcar(j:=reval j,'list) and cdr j do
  153. <<r:=append(r,cddr j); j:=cadr j>>;
  154. x := !*a2kwoweight j;
  155. if v then y := aconc!*(delete(x,y),x)
  156. else if not(x member y)
  157. then msgpri(nil,j,"not found",nil,nil)
  158. else y := delete(x,y)>>;
  159. set(w,y);
  160. if r then return factor1(r,v,w)
  161. end;
  162. % 5 Feb 00.
  163. algebraic (let sign(sqrt ~a) => 1 when sign a=1);
  164. % 18 Feb 00.
  165. symbolic procedure getrtype u;
  166. begin scalar x,y;
  167. return
  168. if null u then nil
  169. else if atom u
  170. then if not idp u then not numberp u and getrtype1 u
  171. else if flagp(u,'share)
  172. then if (x := eval u) eq u then nil else getrtype x
  173. else if (x := get(u,'avalue)) and
  174. not(car x memq '(scalar generic))
  175. or (x := get(u,'rtype)) and (x := list x)
  176. then if y := get(car x,'rtypefn) then apply1(y,nil)
  177. else car x
  178. else nil
  179. else if not idp car u then nil
  180. else if (x := get(car u,'avalue)) and (x := get(car x,'rtypefn))
  181. then apply1(x,cdr u)
  182. else if car u eq 'sub then 'yetunknowntype
  183. else getrtype2 u
  184. end;
  185. symbolic procedure let3(u,v,w,b,flgg);
  186. begin scalar x,y1,y2,z;
  187. x := u;
  188. if null x then <<u := 0; return errpri1 u>>
  189. else if numberp x then return errpri1 u;
  190. y2 := getrtype v;
  191. if b and idp x then <<remprop(x,'rtype); remprop(x,'avalue)>>;
  192. if (y1 := getrtype x)
  193. then return if z := get(y1,'typeletfn)
  194. then lispapply(z,list(x,v,y1,b,getrtype v))
  195. else typelet(x,v,y1,b,getrtype v)
  196. else if y2 and not(y2 eq 'yetunknowntype)
  197. then return if z := get(y2,'typeletfn)
  198. then lispapply(z,list(x,v,nil,b,y2))
  199. else typelet(x,v,nil,b,y2)
  200. else letscalar(u,v,w,x,b,flgg)
  201. end;
  202. % 18 Apr 00.
  203. symbolic procedure mcharg1(u,v,w);
  204. if null u and null v then list nil
  205. else begin integer m,n;
  206. m := length u;
  207. n := length v;
  208. if flagp(w,'nary) and m>2
  209. then if m<=matchlength!* and flagp(w,'symmetric)
  210. then return mchcomb(u,v,w)
  211. else if n=2 then <<u := cdr mkbin(w,u); m := 2>>
  212. else return nil;
  213. return if m neq n then nil
  214. else if flagp(w,'symmetric) then mchsarg(u,v,w)
  215. else if mtp v then list pair(v,u)
  216. else mcharg2(u,v,list nil,w)
  217. end;
  218. % 19 Sep 00, 7 May 01, 15 Jun 01.
  219. symbolic procedure letscalar(u,v,w,x,b,flgg);
  220. begin
  221. if not atom x
  222. then if not idp car x then return errpri2(u,'hold)
  223. else if car x eq 'df
  224. then if null letdf(u,v,w,x,b) then nil
  225. else return nil
  226. else if getrtype car x
  227. then return let2(reval x,v,w,b)
  228. else if not get(car x,'simpfn)
  229. then <<redmsg(car x,"operator");
  230. mkop car x;
  231. return let3(u,v,w,b,flgg)>>
  232. else nil
  233. else if null b and null w
  234. then <<remprop(x,'avalue);
  235. remprop(x,'rtype);
  236. remflag(list x,'antisymmetric);
  237. remprop(x,'infix);
  238. remprop(x,'kvalue);
  239. remflag(list x,'linear);
  240. remflag(list x,'noncom);
  241. remprop(x,'op);
  242. remprop(x,'opmtch);
  243. remprop(x,'simpfn);
  244. remflag(list x,'symmetric);
  245. wtl!* := delasc(x,wtl!*);
  246. if flagp(x,'opfn)
  247. then <<remflag(list x,'opfn); remd x>>;
  248. rmsubs();
  249. return nil>>;
  250. if eqcar(x,'expt) and caddr x memq frlis!*
  251. then letexprn(u,v,w,!*k2q x,b,flgg)
  252. else if eqcar(x,'sqrt)
  253. then <<!*sqrtrulep := t;
  254. let2({'expt,cadr x,'(quotient 1 2)},v,w,b)>>;
  255. x := simp0 x where !*precise = t;
  256. return if not domainp numr x then letexprn(u,v,w,x,b,flgg)
  257. else errpri1 u
  258. end;
  259. symbolic procedure setk1(u,v,b);
  260. begin scalar x,y,z,!*uncached;
  261. !*uncached := t;
  262. if atom u
  263. then <<if null b
  264. then <<if not get(u,'avalue)
  265. then msgpri(nil,u,"not found",nil,nil)
  266. else remprop(u,'avalue);
  267. return nil>>
  268. else if (x:= get(u,'avalue)) then put!-avalue(u,car x,v)
  269. else put!-avalue(u,'scalar,v);
  270. return v>>
  271. else if not atom car u
  272. then rerror(alg,25,"Invalid syntax: improper assignment");
  273. u := car u . revlis cdr u;
  274. if null b
  275. then <<z:=assoc(u,wtl!*);
  276. if not(y := get(car u,'kvalue))
  277. or not (x := assoc(u,y))
  278. then <<if null z and null !*sqrtrulep then
  279. msgpri(nil,u,"not found",nil,nil)>>
  280. else put(car u,'kvalue,delete(x,y));
  281. if z then wtl!*:=delasc(u,wtl!*);
  282. return nil>>
  283. else if not (y := get(car u,'kvalue))
  284. then put!-kvalue(car u,nil,u,v)
  285. else <<if x := assoc(u,y)
  286. then <<updoldrules(u,v); y := delasc(car x,y)>>;
  287. put!-kvalue(car u,y,u,v)>>;
  288. return v
  289. end;
  290. % 7 May 01.
  291. symbolic procedure clearrules u;
  292. begin scalar !*sqrtrulep;
  293. return rule!-list(u,nil)
  294. end;
  295. % 2 Feb 01.
  296. symbolic procedure simprad(u,n);
  297. if !*reduced then multsq(radfa(numr u,n),invsq radfa(denr u,n))
  298. else begin scalar iflag,x,y,z;
  299. if !*rationalize then <<
  300. y:=list(denr u,1);
  301. u:=multf(numr u, exptf(denr u,n-1)) ./ 1 >>
  302. else y := radf(denr u,n);
  303. if n=2 and minusf numr u
  304. then <<iflag := t; x := radf(negf numr u,n)>>
  305. else x := radf(numr u,n);
  306. z := simp list('quotient,retimes cdr x, retimes cdr y);
  307. if domainp numr z and domainp denr z
  308. then z := multsq(mkrootsq(prepf numr z,n),
  309. invsq mkrootsq(prepf denr z,n))
  310. else <<if iflag
  311. then <<iflag := nil;
  312. z := negsq z>>;
  313. z := mkrootsq(prepsq z,n)>>;
  314. z := multsq(multsq(if !*precise and evenp n
  315. then car x ./ 1
  316. else car x ./ 1, 1 ./ car y), z);
  317. if iflag then z := multsq(z,mkrootsq(-1,2));
  318. return z
  319. end;
  320. symbolic procedure radfa(u,n);
  321. begin scalar x,y;
  322. x := fctrf u;
  323. if numberp car x then x := append(zfactor car x,cdr x)
  324. else x := (car x ./ 1) . cdr x;
  325. y := 1 ./ 1;
  326. for each j in x do y := multsq(y,radfb(car j,cdr j,n));
  327. return y
  328. end;
  329. symbolic procedure radfb(u,m,n);
  330. begin scalar x,y;
  331. x := radf(u,n);
  332. y := exptf(car x,m) ./ 1;
  333. return multsq(exptsq(mkrootlsq(cdr x,n),m),y)
  334. end;
  335. % 20 Feb 01.
  336. symbolic procedure reval2(u,v);
  337. if v or null !*combineexpt or dmode!* then !*q2a1(simp!* u,v)
  338. else !*q2a1((simp!* u where !*mcd = nil),v);
  339. % 1 Jun 01.
  340. symbolic procedure simpexpt2(u,n,flg);
  341. begin scalar m,n,x,y;
  342. if u=1 then return 1 ./ 1;
  343. m:=numr n;
  344. if pairp u then <<
  345. if car u eq 'expt
  346. then <<n:=multsq(m:=simp caddr u,n);
  347. if !*precise
  348. then u := list('abs,cadr u)
  349. else u := cadr u;
  350. return simpexpt1(u,n,flg)>>
  351. else if car u eq 'sqrt and not !*keepsqrts
  352. then return simpexpt2(cadr u, multsq(1 ./ 2,n),flg)
  353. else if car u eq 'times and not !*precise
  354. then <<x := 1 ./ 1;
  355. for each z in cdr u do x := multsq(simpexpt1(z,n,flg),x);
  356. return x>>
  357. else if car u eq 'times and (y:=split!-sign cdr u) and car y
  358. then <<x := simpexpt1(retimes append(cadr y,cddr y),n,flg);
  359. for each z in car y do x := multsq(simpexpt1(z,n,flg),x);
  360. return x>>
  361. else if car u eq 'quotient
  362. and (not !*precise
  363. or posnump caddr u and posnump prepsq n
  364. )
  365. then <<if not flg and !*mcd then
  366. return simpexpt1(prepsq simp!* u,n,t);
  367. n := prepsq n;
  368. return quotsq(simpexpt{cadr u,n},simpexpt{caddr u,n})>>
  369. else if car u eq 'minus and not !*precise and not(cadr u = 1)
  370. then return (multsq(simpexpt list(-1,expon),
  371. simpexpt list(cadr u,expon))) where expon=prepsq n>>;
  372. if null flg
  373. then <<if null(dmode!* and idp u and get(u,dmode!*))
  374. then u := prepsq simp!* u;
  375. return simpexpt1(u,n,t)>>
  376. else if numberp u and zerop u then return nil ./ 1
  377. else if not numberp m then m := prepf m;
  378. n := prepf denr n;
  379. if m memq frlis!* and n=1 then return list ((u . m) . 1) . 1;
  380. if !*mcd or not numberp m or n neq 1
  381. or atom u or denr simp!* u neq 1 then return simpx1(u,m,n)
  382. else return mksq(u,m)
  383. end;
  384. endpatch;
  385. % Algint declarations.
  386. fluid '(!*noacn !*structure !*tra !*trmin gaussiani intvar sqrtflag);
  387. fluid '(!*pvar listofallsqrts listofnewsqrts);
  388. global '(modevalcount);
  389. patch algint;
  390. % 20 Sep 00.
  391. symbolic procedure algebraiccase(expression,zlist,varlist);
  392. begin
  393. scalar rischpart,deriv,w,firstterm;
  394. scalar sqrtflag,!*structure;
  395. sqrtflag:=t;
  396. sqrtsave(listofallsqrts,listofnewsqrts,list(intvar . intvar));
  397. rischpart:= errorset!*(list('doalggeom,mkquote expression),
  398. !*backtrace);
  399. newplace list (intvar.intvar);
  400. if atom rischpart
  401. then <<
  402. if !*tra then prin2t "Inner integration failed";
  403. deriv:=nil ./ 1;
  404. rischpart:=deriv >>
  405. else
  406. if atom car rischpart
  407. then <<
  408. if !*tra or !*trmin then
  409. prin2t "The 'logarithmic part' is not elementary";
  410. return (nil ./ 1) . expression >>
  411. else <<
  412. rischpart:=car rischpart;
  413. deriv:=!*diffsq(rischpart,intvar) where sqrtflag=nil;
  414. if !*tra or !*trmin then <<
  415. prin2t "Inner working yields";
  416. printsq rischpart;
  417. prin2t "with derivative";
  418. printsq deriv >> >>;
  419. deriv:=!*addsq(expression,negsq deriv);
  420. if null numr deriv
  421. then return rischpart . (nil ./ 1);
  422. if null involvesq(deriv,intvar)
  423. then return !*addsq(rischpart,
  424. !*multsq(deriv,((mksp(intvar,1) .* 1) .+ nil) ./ 1))
  425. . (nil ./ 1);
  426. varlist:=getvariables deriv;
  427. zlist:=findzvars(varlist,list intvar,intvar,nil);
  428. varlist:=setdiff(varlist,zlist);
  429. firstterm:=simp!* car zlist;
  430. w:=sqrt2top !*multsq(deriv,invsq !*diffsq(firstterm,intvar));
  431. if null involvesq(w,intvar)
  432. then return !*addsq(rischpart,!*multsq(w,firstterm)) . (nil ./ 1);
  433. if !*noacn then interr "Testing only logarithmic code";
  434. deriv:=transcendentalcase(deriv,intvar,nil,zlist,varlist);
  435. return !*addsq(car deriv, rischpart) . cdr deriv
  436. end;
  437. % 22 Jan 01, 9 Feb 01.
  438. symbolic procedure combine!-logs(coef,logarg);
  439. begin
  440. scalar ans,dencoef,parts,logs,lparts,!*rationalize,trueimag;
  441. !*rationalize:=t;
  442. coef:=simp!* coef;
  443. if null numr logarg then return coef;
  444. parts:=split!-real!-imag numr coef;
  445. if null numr cdr parts then return multsq(coef,logarg);
  446. dencoef:=multf(denr coef,denr logarg);
  447. if !*tra then <<
  448. prin2t "attempting to find 'real' form for";
  449. mathprint list('times,list('plus,prepsq car parts,
  450. list('times,prepsq cdr parts,'i)),
  451. prepsq logarg) >>;
  452. logarg:=numr logarg;
  453. logs:= 1 ./ 1;
  454. while pairp logarg do <<
  455. if ldeg logarg neq 1 then interr "what a log";
  456. if atom mvar logarg then interr "what a log";
  457. if car mvar logarg neq 'log then interr "what a log";
  458. logs:=!*multsq(logs,
  459. !*exptsq(simp!* cadr mvar logarg,lc logarg));
  460. logarg:=red logarg >>;
  461. logs:=rationalizesq logs;
  462. ans:=multsq(!*multsq(car parts,logs),1 ./ dencoef);
  463. lparts:=split!-real!-imag numr logs;
  464. if numr difff(denr cdr lparts,intvar)
  465. then interr "unexpected denominator";
  466. lparts:=!*multsq(denr cdr lparts ./ 1,car lparts) . cdr lparts;
  467. if not onep denr car lparts then interr "unexpected denominator";
  468. trueimag:=quotsq(addf(!*exptf(numr car lparts,2),
  469. !*exptf(numr cdr lparts,2)) ./ 1,
  470. !*exptf(denr logs,2) ./ 1);
  471. if numr diffsq(trueimag,intvar)
  472. then ans:=!*addsq(ans,
  473. !*multsq(gaussiani ./ multf(2,dencoef),
  474. !*multsq(simplogsq trueimag,cdr parts)));
  475. trueimag:=!*multsq(car lparts,!*invsq(numr cdr lparts ./ 1));
  476. if numr diffsq(trueimag,intvar)
  477. then ans:=!*addsq(ans,!*multsq(!*multsq(cdr parts,1 ./ dencoef),
  478. !*k2q list('atan,prepsq!* trueimag)));
  479. return ans;
  480. end;
  481. % 6 Mar 01.
  482. symbolic procedure modevalvar v;
  483. begin scalar w;
  484. if atom v
  485. then <<if (w := get(v,'modvalue)) then return w;
  486. put(v,'modvalue,modevalcount);
  487. modevalcount := modevalcount+1;
  488. return modevalcount-1>>
  489. else if car v neq 'sqrt
  490. then <<if !*tra then <<princ "Unexpected algebraic:"; print v>>;
  491. error1()>>
  492. else if numberp cadr v then return (mksp(v,1) .* 1) .+ nil;
  493. w := modeval(!*q2f simp cadr v,!*pvar);
  494. w := assoc(w,listofallsqrts);
  495. if w then return cdr w else return 'failed
  496. end;
  497. endpatch;
  498. % Excalc declarations.
  499. global '(basisforml!* detm!* indxl!* metricd!* metricu!*);
  500. smacro procedure ldpf u;
  501. caar u;
  502. smacro procedure lowerind u;
  503. list('minus,u);
  504. patch excalc;
  505. % 16 Nov 99.
  506. symbolic procedure mkmetric u;
  507. begin scalar x,y,z,okord;
  508. putform(list(cadr u,nil,nil),0);
  509. put(cadr u,'indxsymmetries,
  510. '((lambda (indl) (tot!-sym!-indp
  511. (evlis '((nth indl 1)
  512. (nth indl 2)))))));
  513. put(cadr u,'indxsymmetrize,
  514. '((lambda (indl) (symmetrize!-inds '(1 2) indl))));
  515. flag(list cadr u,'covariant);
  516. okord := kord!*;
  517. kord!* := basisforml!*;
  518. x := simp!* caddr u;
  519. y := indxl!*;
  520. metricu!* := t;
  521. for each j in indxl!* do
  522. <<for each k in y do
  523. setk(list(cadr u,lowerind j,lowerind k),0);
  524. y := cdr y>>;
  525. for each j on partitsq(x,'basep) do
  526. if ldeg ldpf j = 2 then
  527. setk(list(cadr u,lowerind cadr mvar ldpf j,
  528. lowerind cadr mvar ldpf j),
  529. mk!*sq lc j)
  530. else
  531. setk(list(cadr u,lowerind cadr mvar ldpf j,
  532. lowerind cadr mvar lc ldpf j),
  533. mk!*sq multsq(lc j,1 ./ 2));
  534. kord!* := okord;
  535. x := for each j in indxl!* collect
  536. for each k in indxl!* collect
  537. simpindexvar list(cadr u,lowerind j,lowerind k);
  538. z := subfg!*;
  539. subfg!* := nil;
  540. y := lnrsolve(x,generateident length indxl!*);
  541. subfg!* := z;
  542. metricd!* := mkasmetric x;
  543. metricu!* := mkasmetric y;
  544. detm!* := mk!*sq detq x
  545. end;
  546. endpatch;
  547. % Ezgcd declarations.
  548. fluid '(image!-set reduced!-degree!-lclst unlucky!-case);
  549. symbolic smacro procedure polyzerop u; null u;
  550. patch ezgcd;
  551. % 8 Nov 99.
  552. symbolic procedure ezgcdf(u,v);
  553. begin scalar kordx,x;
  554. kordx := kord!*;
  555. x := errorset2{'ezgcdf1,mkquote u,mkquote v};
  556. if null errorp x then return first x;
  557. setkorder kordx;
  558. return gcdf1(u,v)
  559. end;
  560. symbolic procedure poly!-gcd(u,v);
  561. begin scalar !*exp,z;
  562. if polyzerop u then return poly!-abs v
  563. else if polyzerop v then return poly!-abs u
  564. else if u=1 or v=1 then return 1;
  565. !*exp := t;
  566. if quotf1(u,v) then z := v
  567. else if quotf1(v,u) then z := u
  568. else if !*gcd then z := gcdlist list(u,v)
  569. else z := 1;
  570. return poly!-abs z
  571. end;
  572. symbolic procedure gcdlist3(l,onestep,vlist);
  573. begin
  574. scalar unlucky!-case,image!-set,gg,gcont,l1,w,w1,w2,
  575. reduced!-degree!-lclst,p1,p2;
  576. l1:=for each p in l collect p . ezgcd!-comfac p;
  577. l:=for each c in l1 collect
  578. quotfail1(car c,comfac!-to!-poly cdr c,
  579. "Content divison in GCDLIST3 failed");
  580. gcont:=gcdlist for each c in l1 collect cddr c;
  581. if domainp gcont then if not(gcont=1)
  582. then errorf "GCONT has numeric part";
  583. l := sort(for each p in l collect poly!-abs p,function ordp);
  584. w := nil;
  585. while l do <<
  586. w := car l . w;
  587. repeat l := cdr l until null l or not(car w = car l)>>;
  588. l := reversip w;
  589. w := nil;
  590. if null cdr l then return multf(gcont,car l);
  591. if domainp (gg:=car (l:=sort(l,function degree!-order))) then
  592. return gcont;
  593. if ldeg gg=1 then <<
  594. if division!-test(gg,l) then return multf(poly!-abs gg,gcont)
  595. else return gcont >>;
  596. if onestep then <<
  597. p1 := poly!-abs car l; p2 := poly!-abs cadr l;
  598. if p1=p2 then <<
  599. if division!-test(p1,cddr l) then return multf(p1,gcont) >>
  600. else <<
  601. gg := poly!-gcd(lc p1,lc p2);
  602. w1 := multf(red p1, quotfail1(lc p2, gg,
  603. "Division failure when just one pseudoremainder step needed"));
  604. w2 := multf(red p2,negf quotfail1(lc p1, gg,
  605. "Division failure when just one pseudoremainder step needed"));
  606. w := ldeg p1 - ldeg p2;
  607. if w > 0 then w2 := multf(w2, (mksp(mvar p2, w) .* 1) .+ nil)
  608. else if w < 0
  609. then w1 := multf(w1, (mksp(mvar p1, -w) .* 1) .+ nil);
  610. gg := ezgcd!-pp addf(w1, w2);
  611. if division!-test(gg,l) then return multf(gg,gcont) >>>>;
  612. return gcdlist31(l,vlist,gcont,gg,l1)
  613. end;
  614. endpatch;
  615. % Int declarations.
  616. fluid '(!*failhard !*purerisch !*reverse !*trdint sqrt!-places!-alist
  617. badpart ccount cmap cmatrix content cval denbad denominator!*
  618. lhs!* loglist orderofelim rhs!* tanlist !*intflag!* indexlist
  619. intvar listofnewsqrts listofallsqrts lorder power!-list!*
  620. sqrtflag sqrtlist sqrt!-intvar basic!-listofnewsqrts
  621. basic!-listofallsqrts sqfr sillieslist varlist);
  622. global '(!*number!* !*seplogs !*spsize!* !*statistics gensymcount);
  623. patch int;
  624. % 18 Dec 99.
  625. symbolic procedure findtrialdivs zl;
  626. begin scalar dlists1,args1;
  627. for each z in zl do
  628. if exportan z
  629. then <<if car z eq 'tan
  630. then <<args1 := (mksp(z,2) .* 1) .+ 1;
  631. tanlist := (args1 ./ 1) . tanlist>>
  632. else args1 := !*kk2f z;
  633. dlists1 := (z . args1) . dlists1>>;
  634. return dlists1
  635. end;
  636. % 12 Dec 00.
  637. symbolic procedure simpdint u;
  638. begin scalar low,upp,fn,var,x,y;
  639. if length u neq 4
  640. then rerror(int,2,"Improper number of arguments to INT");
  641. load!-package 'defint;
  642. fn := car u;
  643. var := cadr u;
  644. low := caddr u;
  645. upp := cadddr u;
  646. low := reval low;
  647. upp := reval upp;
  648. if low = upp then return nil ./ 1
  649. else if null getd 'new_defint then nil
  650. else if upp = 'infinity
  651. then if low = 0
  652. then if not smemql('(infinity unknown),
  653. x := defint!* {fn,var})
  654. then return simp!* x else nil
  655. else if low = '(minus infinity)
  656. then return mkinfint(fn,var)
  657. else if freeof(var,low)
  658. then if not smemql('(infinity unknown),
  659. x := defint!* {fn,var})
  660. and not smemql('(infinity unknown),
  661. y := indefint!* {fn,var,low})
  662. then return simp!* {'difference,x,y} else nil
  663. else nil
  664. else if upp = '(minus infinity) or low = 'infinity
  665. then return negsq simpdint {fn,var,upp,low}
  666. else if low = '(minus infinity)
  667. then return
  668. simpdint{prepsq simp{'sub,{'equal,var,{'minus,var}},fn},
  669. var,{'minus,upp},'infinity}
  670. else if low = 0
  671. then if freeof(var,upp)
  672. and not smemql('(infinity unknown),
  673. x := indefint!* {fn,var,upp})
  674. then return simp!* x else nil
  675. else if freeof(var,upp) and freeof(var,low)
  676. and not smemq('(infinity unknown),
  677. x := indefint!* {fn,var,upp})
  678. and not smemql('(infinity unknown),
  679. y := indefint!* {fn,var,low})
  680. then return simp!* {'difference,x,y};
  681. return mkdint(fn,var,low,upp)
  682. end;
  683. % 1 Jun 01.
  684. symbolic procedure simpint u;
  685. if atom u or null cdr u or cddr u and (null cdddr u or cddddr u)
  686. then rerror(int,1,"Improper number of arguments to INT")
  687. else if cddr u then simpdint u
  688. else begin scalar ans,dmod,expression,variable,loglist,oldvarstack,
  689. !*intflag!*,!*purerisch,cflag,intvar,listofnewsqrts,
  690. listofallsqrts,sqrtfn,sqrt!-intvar,sqrt!-places!-alist,
  691. basic!-listofallsqrts,basic!-listofnewsqrts,coefft,
  692. varchange,w,!*precise;
  693. !*intflag!* := t;
  694. variable := !*a2k cadr u;
  695. if not(idp variable or pairp variable and numlistp cdr variable)
  696. then <<varchange := variable . intern gensym();
  697. if !*trint
  698. then prin2t {"Integration kernel", variable,
  699. "replaced by simple variable", cdr varchange};
  700. variable := cdr varchange>>;
  701. intvar := variable;
  702. w := cddr u;
  703. if w then rerror(int,3,"Too many arguments to INT");
  704. listofnewsqrts:= list mvar gaussiani;
  705. listofallsqrts:= list (cadr mvar gaussiani . gaussiani);
  706. sqrtfn := get('sqrt,'simpfn);
  707. put('sqrt,'simpfn,'proper!-simpsqrt);
  708. if dmode!* then
  709. << if (cflag:=get(dmode!*, 'cmpxfn)) then onoff('complex, nil);
  710. if (dmod := get(dmode!*,'dname)) then
  711. onoff(dmod,nil)>> where !*msg := nil;
  712. begin scalar dmode!*,!*exp,!*gcd,!*keepsqrts,!*limitedfactors,!*mcd,
  713. !*rationalize,!*structure,!*uncached,kord!*,
  714. ans1,denexp,badbit,nexp,oneterm;
  715. !*keepsqrts := !*limitedfactors := t;
  716. !*exp := !*gcd := !*mcd := !*structure := !*uncached := t;
  717. dmode!* := nil;
  718. if !*algint
  719. then <<
  720. sqrt!-intvar:=!*q2f simpsqrti variable;
  721. if (red sqrt!-intvar) or (lc sqrt!-intvar neq 1)
  722. or (ldeg sqrt!-intvar neq 1)
  723. then interr "Sqrt(x) not properly formed"
  724. else sqrt!-intvar:=mvar sqrt!-intvar;
  725. basic!-listofallsqrts:=listofallsqrts;
  726. basic!-listofnewsqrts:=listofnewsqrts;
  727. sqrtsave(basic!-listofallsqrts,basic!-listofnewsqrts,
  728. list(variable . variable))>>;
  729. coefft := (1 ./ 1);
  730. expression := int!-simp car u;
  731. if varchange
  732. then <<depend1(car varchange,cdr varchange,t);
  733. expression := int!-subsq(expression,{varchange})>>;
  734. denexp := 1 ./ denr expression;
  735. nexp := numr expression;
  736. while not atom nexp and null cdr nexp and
  737. not depends(mvar nexp,variable) do
  738. <<coefft := multsq(coefft,(((caar nexp) . 1) . nil) ./ 1);
  739. nexp := lc nexp>>;
  740. ans1 := nil;
  741. while nexp do begin
  742. scalar x,zv,tmp;
  743. if atom nexp then <<x := !*f2q nexp; nexp := nil>>
  744. else <<x := !*t2q car nexp; nexp := cdr nexp>>;
  745. x := multsq(x,denexp);
  746. zv := findzvars(getvariables x,list variable,variable,nil);
  747. begin scalar oldzlist;
  748. while oldzlist neq zv do <<
  749. oldzlist := zv;
  750. foreach zz in oldzlist do
  751. zv:=findzvars(distexp(pseudodiff(zz,variable)),
  752. zv,variable,t)>>;
  753. % The following line was added to make, for example,
  754. % int(df(sin(x)/x),x) return the expected result.
  755. zv := sort(zv, function ordp)
  756. end;
  757. tmp := ans1;
  758. while tmp do
  759. <<if zv=caar tmp
  760. then <<rplacd(car tmp,addsq(cdar tmp,x));
  761. tmp := nil; zv := nil>>
  762. else tmp := cdr tmp>>;
  763. if zv then ans1 := (zv . x) . ans1
  764. end;
  765. if length ans1 = 1 then oneterm := t;
  766. nexp := ans1;
  767. ans := nil ./ 1;
  768. badbit:=nil ./ 1;
  769. while nexp do
  770. <<u := cdar nexp;
  771. if !*trdint
  772. then <<princ "Integrate"; printsq u;
  773. princ "with Zvars "; print caar nexp>>;
  774. ans1 := errorset!*(list('integratesq,mkquote u,
  775. mkquote variable,mkquote loglist,
  776. mkquote caar nexp),
  777. !*backtrace);
  778. nexp := cdr nexp;
  779. if errorp ans1 then badbit := addsq(badbit,u)
  780. else <<ans := addsq(caar ans1, ans);
  781. badbit:=addsq(cdar ans1,badbit)>>>>;
  782. if !*trdint
  783. then <<prin2 "Partial answer="; printsq ans;
  784. prin2 "To do="; printsq badbit>>;
  785. if badbit neq '(nil . 1)
  786. then <<setkorder nil;
  787. badbit := reordsq badbit;
  788. ans := reordsq ans;
  789. coefft := reordsq coefft;
  790. if !*trdint then <<princ "Retrying..."; printsq badbit>>;
  791. if oneterm and ans = '(nil . 1) then ans1 := nil
  792. else ans1 := errorset!*(list('integratesq,mkquote badbit,
  793. mkquote variable,mkquote loglist,nil),
  794. !*backtrace);
  795. if null ans1 or errorp ans1
  796. then ans := addsq(ans,simpint1(badbit . variable . w))
  797. else <<ans := addsq(ans,caar ans1);
  798. if not smemq(variable, ans) then ans := nil ./ 1;
  799. if cdar ans1 neq '(nil . 1)
  800. then ans := addsq(ans,
  801. simpint1(cdar ans1 . variable . w))
  802. >>>>;
  803. end;
  804. ans := multsq(coefft,ans);
  805. if !*trdint then << prin2t "Resimp and all that"; printsq ans >>;
  806. put('int,'simpfn,'simpiden);
  807. put('sqrt,'simpfn,sqrtfn);
  808. << if dmod then onoff(dmod,t);
  809. if cflag then onoff('complex,t)>> where !*msg := nil;
  810. oldvarstack := varstack!*;
  811. varstack!* := nil;
  812. ans := errorset!*(list('int!-resub,mkquote ans,mkquote
  813. varchange),t);
  814. put('int,'simpfn,'simpint);
  815. varstack!* := oldvarstack;
  816. return if errorp ans then error1() else car ans
  817. end;
  818. symbolic procedure mkdint(fn,var,low,upp);
  819. begin scalar x,!*precise;
  820. if getd 'defint0
  821. and not((x := defint0 {fn,var,low,upp}) eq 'failed)
  822. then return simp x
  823. else if not smemq('infinity,low) and not smemq('infinity,upp)
  824. then <<x := prepsq!* simpint {fn,var};
  825. if not eqcar(x,'int)
  826. then return simp!* {'difference,
  827. subeval {{'equal,var,upp},x},
  828. subeval {{'equal,var,low},x}}>>;
  829. return mksq({'int,fn,var,low,upp},1)
  830. end;
  831. % 9 Aug 01.
  832. symbolic
  833. procedure transcendentalcase(integrand,svar,xlogs,zlist,varlist);
  834. begin scalar divlist,jhd!-content,content,prim,sqfr,dfu,indexlist,
  835. sillieslist,originalorder,wrongway,power!-list!*,
  836. sqrtlist,tanlist,loglist,dflogs,eprim,dfun,unintegrand,
  837. sqrtflag,badpart,rhs!*,lhs!*,gcdq,cmap,cval,orderofelim,cmatrix;
  838. scalar ccount,denominator!*,result,denbad,temp;
  839. gensymcount:=0;
  840. integrand:=sqrt2top integrand;
  841. if !*trint then << printc "Extension variables z<i> are";
  842. print zlist>>;
  843. begin scalar w,gg;
  844. gg:=1;
  845. foreach z in zlist do
  846. <<w := subs2 diffsq(simp z,svar);
  847. gg := !*multf(gg,quotf(denr w,gcdf(denr w,gg)))>>;
  848. gg := quotf(gg,gcdf(gg,denr integrand));
  849. unintegrand := (!*multf(gg,numr integrand)
  850. ./ !*multf(gg,denr integrand));
  851. if !*trint then <<
  852. printc "After unnormalization the integrand is ";
  853. printsq unintegrand >>
  854. end;
  855. divlist := findtrialdivs zlist;
  856. sqrtlist := findsqrts zlist;
  857. divlist := trialdiv(denr unintegrand,divlist);
  858. prim := sqfree(cdr divlist,zlist);
  859. jhd!-content := content;
  860. printfactors(prim,nil);
  861. eprim := sqmerge(countz car divlist,prim,nil);
  862. printfactors(eprim,t);
  863. sqfr := for each u in eprim collect multup u;
  864. if !*reverse then zlist := reverse zlist;
  865. indexlist := createindices zlist;
  866. dfu:=dfnumr(svar,car divlist);
  867. loglist := append(loglist,factorlistlist prim);
  868. loglist := mergein(xlogs,loglist);
  869. loglist := mergein(tanlist,loglist);
  870. cmap := createcmap();
  871. ccount := length cmap;
  872. if !*trint then <<printc "Loglist "; print loglist>>;
  873. dflogs := difflogs(loglist,denr unintegrand,svar);
  874. if !*trint
  875. then <<printc "************ 'Derivative' of logs is:";
  876. printsq dflogs>>;
  877. dflogs := addsq((numr unintegrand) ./ 1,negsq dflogs);
  878. gcdq := gcdf(denr dflogs,denr dfu);
  879. dfun := !*multf(numr dfu,denbad:=quotf(denr dflogs,gcdq));
  880. denbad := !*multf(denr dfu,denbad);
  881. denbad := !*multf(denr unintegrand,denbad);
  882. dflogs := !*multf(numr dflogs,quotf(denr dfu,gcdq));
  883. dfu := dfun;
  884. rhs!* := multbyarbpowers f2df dfu;
  885. if checkdffail(rhs!*,svar)
  886. then <<if !*trint then printsq checkdffail(rhs!*,svar);
  887. interr "Simplification fails on above expression">>;
  888. if !*trint then <<
  889. printc "Distributed Form of Numerator is:";
  890. printdf rhs!*>>;
  891. lhs!* := f2df dflogs;
  892. if !*trint then << printc "Distributed Form of integrand is:";
  893. printdf lhs!*;
  894. terpri()>>;
  895. cval := mkvect(ccount);
  896. for i := 0:ccount do putv(cval,i,nil ./ 1);
  897. power!-list!* := tansfrom(rhs!*,zlist,indexlist,0);
  898. lorder:=maxorder(power!-list!*,zlist,0);
  899. originalorder := for each x in lorder collect x;
  900. if !*trint then <<
  901. printc "Maximum order for variables determined as ";
  902. print lorder >>;
  903. if !*statistics then << !*number!*:=0;
  904. !*spsize!*:=1;
  905. foreach xx in lorder do
  906. !*spsize!*:=!*spsize!* * (xx+1) >>;
  907. dfun:=solve!-for!-u(rhs!*,lhs!*,nil);
  908. backsubst4cs(nil,orderofelim,cmatrix);
  909. if !*statistics then << prin2 !*number!*; prin2 " used out of ";
  910. printc !*spsize!* >>;
  911. badpart:=substinulist badpart;
  912. dfun:=df2q substinulist dfun;
  913. result:= !*multsq(dfun,!*invsq(denominator!* ./ 1));
  914. result:= !*multsq(result,!*invsq(jhd!-content ./ 1));
  915. dflogs:=logstosq();
  916. if not null numr dflogs then <<
  917. if !*seplogs and (not domainp numr result) then <<
  918. result:=mk!*sq result;
  919. result:=(mksp(result,1) .* 1) .+ nil;
  920. result:=result ./ 1 >>;
  921. result:=addsq(result,dflogs)>>;
  922. if !*trint
  923. then <<
  924. terpri();
  925. printc
  926. "*****************************************************";
  927. printc
  928. "************ THE INTEGRAL IS : **********************";
  929. printc
  930. "*****************************************************";
  931. terpri();
  932. printsq result;
  933. terpri()>>;
  934. if badpart then begin scalar n,oorder;
  935. if !*trint
  936. then printc "plus a part which has not been integrated";
  937. lhs!*:=badpart;
  938. lorder:=maxorder(power!-list!*,zlist,0);
  939. oorder:=originalorder;
  940. n:=length lorder;
  941. while lorder do <<
  942. if car lorder > car originalorder then
  943. wrongway:=t;
  944. if car lorder=car originalorder then n:= n-1;
  945. lorder:=cdr lorder;
  946. originalorder:=cdr originalorder >>;
  947. if !*trint and wrongway then printc "Went wrong way";
  948. dfun:=df2q badpart;
  949. dfun:= !*multsq(dfun,invsq(denbad ./ 1));
  950. badpart := dfun;
  951. if wrongway then <<
  952. if !*trint then printc "Resetting....";
  953. result:=nil ./ 1;
  954. dfun := integrand; badpart:=dfun >>;
  955. if rootcheckp(unintegrand,svar) then
  956. return simpint1(integrand . svar.nil) . (nil ./ 1)
  957. else if !*purerisch or allowedfns zlist then
  958. << badpart := dfun;
  959. dfun := nil ./ 1 >>
  960. else << !*purerisch:=t;
  961. if !*trint
  962. then <<printc " Applying transformations ...";
  963. printsq dfun>>;
  964. temp := get('tan,'opmtch);
  965. remprop('tan,'opmtch);
  966. denbad:=transform(dfun,svar);
  967. if denbad=dfun
  968. then <<dfun:=nil ./ 1;
  969. badpart:=denbad;
  970. put('tan,'opmtch,temp)>>
  971. else <<denbad:=errorset!*(list('integratesq,mkquote denbad,
  972. mkquote svar,mkquote xlogs, nil),
  973. !*backtrace);
  974. put('tan,'opmtch,temp);
  975. if not atom denbad then <<
  976. denbad:=car denbad;
  977. dfun:=untan car denbad;
  978. if (dfun neq '(nil . 1)) then
  979. badpart:=untan cdr denbad;
  980. if car badpart and not(badpart=denbad) then <<
  981. wrongway:=nil;
  982. lhs!*:=f2df car badpart;
  983. lorder:=maxorder(power!-list!*,zlist,0);
  984. n:=length lorder;
  985. while lorder do <<
  986. if car lorder > car oorder then
  987. wrongway:=t;
  988. if car lorder=car oorder then n:= n-1;
  989. lorder:=cdr lorder;
  990. oorder:=cdr oorder >>;
  991. if wrongway or (n=0) then <<
  992. if !*trint then printc "Still backwards";
  993. dfun := nil ./ 1;
  994. badpart := integrand>>>>>>
  995. else <<badpart := dfun; dfun := nil ./ 1 >>>>>>;
  996. if !*failhard then rerror(int,9,"FAILHARD switch set");
  997. if !*seplogs and not domainp result then <<
  998. result:=mk!*sq result;
  999. if not numberp result
  1000. then result:=(mksp(result,1) .* 1) .+ nil;
  1001. result:=result ./ 1>>;
  1002. result:=addsq(result,dfun) end
  1003. else badpart:=nil ./ 1;
  1004. return (sqrt2top result . badpart)
  1005. end;
  1006. endpatch;
  1007. unfluid '(indexlist);
  1008. patch limits;
  1009. % 1 Jun 01.
  1010. symbolic procedure simplimit u;
  1011. begin scalar fn,exprn,var,val,old,v,!*precise,!*protfg;
  1012. if length u neq 4
  1013. then rerror(limit,1,
  1014. "Improper number of arguments to limit operator");
  1015. fn:= car u; exprn := cadr u; var := !*a2k caddr u; val := cadddr u;
  1016. !*protfg := t;
  1017. old := get('cot,'opmtch);
  1018. put('cot,'opmtch,
  1019. '(((!~x) (nil . t) (quotient (cos !~x) (sin !~x)) nil)));
  1020. v := errorset!*({'apply,mkquote fn,mkquote {exprn,var,val}},nil);
  1021. put('cot,'opmtch,old);
  1022. !*protfg := nil;
  1023. return if errorp v or (v := car v) = aeval 'failed then mksq(u,1)
  1024. else simp!* v
  1025. end;
  1026. endpatch;
  1027. % Matrix declarations.
  1028. fluid '(!*bezout);
  1029. patch matrix;
  1030. % 7 Aug 99, 23 Apr 01.
  1031. symbolic procedure quotfexf!*1(u,v);
  1032. if null u then nil
  1033. else (if x then x
  1034. else (if denr y = 1 then numr y
  1035. else if denr (y := (rationalizesq y
  1036. where !*rationalize = t))=1
  1037. then numr y
  1038. else rerror(matrix,11,
  1039. "Catastrophic division failure"))
  1040. where y=rationalizesq(u ./ v))
  1041. where x=quotf(u,v);
  1042. % 23 Jan 01.
  1043. symbolic procedure lnrsolve(u,v);
  1044. begin scalar temp,vlhs,vrhs,ok,
  1045. !*exp,!*solvesingular;
  1046. if !*ncmp then return clnrsolve(u,v);
  1047. !*exp := t;
  1048. if asymplis!* or wtl!* then
  1049. <<temp := asymplis!* . wtl!*;
  1050. asymplis!* := wtl!* := nil>>;
  1051. vlhs := for i:=1:length car u collect intern gensym();
  1052. vrhs := for i:=1:length car v collect intern gensym();
  1053. u := car normmat augment(u,v);
  1054. v := append(vlhs,vrhs);
  1055. ok := setkorder v;
  1056. u := foreach r in u collect prsum(v,r);
  1057. v := errorset!*({function solvebareiss, mkquote u,mkquote vlhs},t);
  1058. if caar v memq {'singular,'inconsistent} then
  1059. <<setkorder ok; rerror(matrix,13,"Singular matrix")>>;
  1060. v := pair(cadr s,car s) where s = cadar v;
  1061. u := foreach j in vlhs collect
  1062. coeffrow(negf numr q,vrhs,denr q) where q = cdr atsoc(j,v);
  1063. setkorder ok;
  1064. if temp then <<asymplis!* := car temp; wtl!* := cdr temp>>;
  1065. return for each j in u collect
  1066. for each k in j collect
  1067. if temp then resimp k else cancel k;
  1068. end;
  1069. % 23 Apr 01.
  1070. symbolic procedure extmult(u,v);
  1071. if null u or null v then nil
  1072. else (if x then cdr x .* (if car x then negf c!:subs2multf(lc u,lc v)
  1073. else c!:subs2multf(lc u,lc v))
  1074. .+ extadd(extmult(!*t2f lt u,red v),
  1075. extmult(red u,v))
  1076. else extadd(extmult(red u,v),extmult(!*t2f lt u,red v)))
  1077. where x = ordexn(car lpow u,lpow v);
  1078. % 14 Jan 01, 7 Aug 01.
  1079. symbolic procedure resultant(u,v,var);
  1080. if domainp u and domainp v then 1
  1081. else begin scalar x;
  1082. kord!* := var . kord!*;
  1083. if null domainp u and null(mvar u eq var) then u := reorder u;
  1084. if null domainp v and null(mvar v eq var) then v := reorder v;
  1085. x := if !*bezout then bezout_resultant(u,v,var)
  1086. else polyresultantf(u,v,var);
  1087. setkorder cdr kord!*;
  1088. return x
  1089. end;
  1090. symbolic procedure resultantsq(u,v,var);
  1091. if domainp numr u and domainp numr v and denr u = 1 and denr v = 1
  1092. then 1 ./ 1
  1093. else begin scalar x;
  1094. kord!* := var . kord!*;
  1095. if null domainp numr u and null(mvar numr u eq var)
  1096. then u := reordsq u;
  1097. if null domainp numr v and null(mvar numr v eq var)
  1098. then v := reordsq v;
  1099. x := if !*bezout then bezout_resultant(!*q2f u,!*q2f v,var)
  1100. else polyresultantf(!*q2f u,!*q2f v,var);
  1101. setkorder cdr kord!*;
  1102. return !*f2q x
  1103. end;
  1104. symbolic procedure polyresultantf(u,v,var);
  1105. begin scalar beta,cd,cn,delta,gam,r,s,temp,x;
  1106. cd := cn := r := s := 1;
  1107. gam := -1;
  1108. if domainp u or domainp v then return 1
  1109. else if ldeg u<ldeg v
  1110. then <<s := (-1)^(ldeg u*ldeg v); temp := u; u := v; v := temp>>;
  1111. while v do
  1112. <<delta := ldeg u-ldegr(v,var);
  1113. beta := negf(multf(r,exptf(gam,delta)));
  1114. r := lcr(v,var);
  1115. gam := multf(exptf(negf r,delta),exptf(gam,1-delta));
  1116. temp := u;
  1117. u := v;
  1118. if not evenp ldeg temp and not evenp ldegr(u,var) then s := -s;
  1119. v := quotf(pseudo_remf(temp,v,var),beta);
  1120. if v
  1121. then <<cn := multf(cn,exptf(beta,ldeg u));
  1122. cd := multf(cd,
  1123. exptf(r,(1+delta)*ldeg u-ldeg temp+ldegr(v,var)));
  1124. if (x := quotf(cd,cn)) then <<cn := 1; cd := x>>>>>>;
  1125. return if not domainp u and mvar u eq var then nil
  1126. else if ldeg temp neq 1
  1127. then quotf(multf(s,multf(cn,exptf(u,ldeg temp))),cd)
  1128. else u
  1129. end;
  1130. symbolic procedure lcr(u,var);
  1131. if domainp u or mvar u neq var then u else lc u;
  1132. symbolic procedure ldegr(u,var);
  1133. if domainp u or mvar u neq var then 0 else ldeg u;
  1134. symbolic procedure pseudo_remf(u,v,var);
  1135. !*q2f simp pseudo!-remainder {mk!*sq(u ./ 1),mk!*sq(v ./ 1),var};
  1136. symbolic procedure bezout_resultant(u,v,w);
  1137. begin integer n,nm; scalar ap,ep,uh,ut,vh,vt;
  1138. if domainp u or null(mvar u eq w)
  1139. then return if not domainp v and mvar v eq w
  1140. then exptf(u,ldeg v)
  1141. else 1
  1142. else if domainp v or null(mvar v eq w)
  1143. then return if mvar u eq w then exptf(v,ldeg u) else 1;
  1144. n := ldeg v - ldeg u;
  1145. if n < 0 then return multd((-1)**(ldeg u*ldeg v),
  1146. bezout_resultant(v,u,w));
  1147. ep := 1;
  1148. nm := ldeg v;
  1149. uh := lc u;
  1150. vh := lc v;
  1151. ut := if n neq 0 then multpf(w to n,red u) else red u;
  1152. vt := red v;
  1153. ap := addf(multf(uh,vt),negf multf(vh,ut));
  1154. ep := b!:extmult(!*sf2exb(ap,w),ep);
  1155. for j := (nm - 1) step -1 until (n + 1) do
  1156. <<if degr(ut,w) = j then
  1157. <<uh := addf(lc ut,multf(!*k2f w,uh));
  1158. ut := red ut>>
  1159. else uh := multf(!*k2f w,uh);
  1160. if degr(vt,w) = j then
  1161. <<vh := addf(lc vt,multf(!*k2f w,vh));
  1162. vt := red vt>>
  1163. else vh := multf(!*k2f w,vh);
  1164. ep := b!:extmult(!*sf2exb(addf(multf(uh,vt),
  1165. negf multf(vh,ut)),w),ep)>>;
  1166. if n neq 0
  1167. then <<ep := b!:extmult(!*sf2exb(u,w),ep);
  1168. for j := 1:(n-1) do
  1169. ep := b!:extmult(!*sf2exb(multpf(w to j,u),w),ep)>>;
  1170. return if null ep then nil else lc ep
  1171. end;
  1172. endpatch;
  1173. % Ncpoly declarations.
  1174. fluid '(!*complex !*trnc dipvars!*);
  1175. patch ncpoly;
  1176. % 9 Jan 01.
  1177. symbolic procedure nc_factsolve(s,vl,all);
  1178. begin scalar v,sb,ns,so,soa,sol,nz,w,q,z,r,abort;
  1179. v:= numr simp car vl;
  1180. ns:=for each e in s collect numr simp e;
  1181. r:=t;
  1182. while r do
  1183. <<r:=nil; s:=ns; ns:=nil;
  1184. for each e in s do if not abort then
  1185. <<e:=absf numr subf(e,sb);
  1186. while(q:=quotf(e,v)) do e:=q;
  1187. if null e then nil else
  1188. if domainp e or not(mvar e member vl) then abort:=t else
  1189. if null red e and domainp lc e then
  1190. <<w:=mvar e; sb:=(w . 0).sb; r:=t;
  1191. vl:=delete(w,vl)>>
  1192. else if not member(e,ns) then ns:=e.ns
  1193. >>;
  1194. >>;
  1195. if abort or null vl then return nil;
  1196. nc_factorize_timecheck();
  1197. if null ns and vl then
  1198. <<sol:={for each x in vl collect x.1};
  1199. goto done>>;
  1200. s:=for each e in ns collect prepf e;
  1201. if !*trnc then
  1202. <<prin2 "solving ";
  1203. prin2 length s; prin2 " polynomial equations for ";
  1204. prin2 length vl;
  1205. prin2t "variables";
  1206. for each e in s do writepri(mkquote e,'only);>>;
  1207. w:=(cdr solveeval{'list.s,'list.vl} where dipvars!*=nil);
  1208. loop:
  1209. nc_factorize_timecheck();
  1210. if null w then goto done;
  1211. so:= cdr car w; w:=cdr w; soa:=nil;
  1212. if smemq('i,so) and null !*complex then go to loop;
  1213. for each y in vl do if not smember(y,so) then
  1214. <<soa:=(y . 1) . soa; nz:=t>>;
  1215. for each y in so do
  1216. <<z:=nc_factorize_unwrap(reval caddr y,soa);
  1217. nz:=nz or z neq 0;
  1218. soa:=(cadr y . z).soa;
  1219. >>;
  1220. if not nz then goto loop;
  1221. q:=assoc(car vl,soa);
  1222. if null q or cdr q=0 then go to loop;
  1223. soa := for each j in soa collect (car j . sublis(soa,cdr j));
  1224. sol := soa . sol;
  1225. if all then go to loop;
  1226. done:
  1227. sol:=for each s in sol collect append(sb,s);
  1228. if !*trnc then
  1229. <<prin2t "solutions:";
  1230. for each w in sol do
  1231. writepri(mkquote('list.
  1232. for each s in w collect {'equal,car s,cdr s}),'only);
  1233. prin2t "-------------------------";
  1234. >>;
  1235. return sol
  1236. end;
  1237. endpatch;
  1238. % Plot declarations.
  1239. global '(!*plotpause !*plotusepipe dirchar!* opsys!* plotcleanup!*
  1240. plotcmds!* plotcommand!* plotdir!* plotdta!* plotheader!*
  1241. tempdir!*);
  1242. patch plot;
  1243. % 28 Jun 99.
  1244. symbolic procedure init_gnuplot();
  1245. <<
  1246. !*plotpause := -1;
  1247. plotcleanup!* := {};
  1248. tempdir!* := getenv 'tmp;
  1249. if null tempdir!* then tempdir!* := getenv 'temp;
  1250. dirchar!* := "/";
  1251. plotcommand!* := "gnuplot";
  1252. opsys!* := assoc('opsys, lispsystem!*);
  1253. if null opsys!* then opsys!* := 'unknown
  1254. else opsys!* := cdr opsys!*;
  1255. if getenv "gnuplot" then plotdir!* := getenv "gnuplot"
  1256. else if null plotdir!* and not (opsys!* = 'unix)
  1257. then plotdir!* := get!-lisp!-directory();
  1258. if opsys!* = 'win32 then <<
  1259. plotcommand!* := "wgnuplot";
  1260. plotheader!* := "";
  1261. dirchar!* := "\";
  1262. plotdta!* := for each n in
  1263. {"gnutmp.tm1", "gnutmp.tm2", "gnutmp.tm3", "gnutmp.tm4",
  1264. "gnutmp.tm5", "gnutmp.tm6", "gnutmp.tm7", "gnutmp.tm8"}
  1265. collect gtmpnam n;
  1266. plotcleanup!* := if null tempdir!* then {"erase gnutmp.tm*"}
  1267. else {bldmsg("erase %w\gnutmp.tm*", tempdir!*)} >>
  1268. else if opsys!* = 'msdos then <<
  1269. plotheader!* := ""; % ?? "set term vga";
  1270. dirchar!* := "\";
  1271. plotdta!* := for each n in
  1272. {"gnutmp.tm1", "gnutmp.tm2", "gnutmp.tm3", "gnutmp.tm4",
  1273. "gnutmp.tm5", "gnutmp.tm6", "gnutmp.tm7", "gnutmp.tm8"}
  1274. collect gtmpnam n;
  1275. plotcmds!*:= gtmpnam "gnutmp.tm0";
  1276. plotcleanup!* := if null tempdir!* then {"erase gnutmp.tm*"}
  1277. else {bldmsg("erase %w\gnutmp.tm*", tempdir!*)} >>
  1278. else if opsys!* = 'riscos then <<
  1279. plotheader!* := "";
  1280. dirchar!* := ".";
  1281. plotdta!* := for i:=1:10 collect tmpnam();
  1282. plotcmds!*:= tmpnam();
  1283. plotcleanup!* :=
  1284. bldmsg("remove %w", plotcmds!*) .
  1285. for each f in plotdta!* collect bldmsg("remove %w", f)
  1286. >>
  1287. else if opsys!* = 'unix then <<
  1288. plotheader!* := "set term x11";
  1289. plotdta!* := for i:=1:10 collect tmpnam();
  1290. plotcmds!*:= tmpnam();
  1291. plotcleanup!* :=
  1292. bldmsg("rm %w", plotcmds!*) .
  1293. for each f in plotdta!* collect bldmsg("rm %w", f) >>
  1294. else if opsys!* = 'finder then <<
  1295. plotcommand!* := "gnuplot";
  1296. plotcmds!*:= "::::gnuplot:reduce.plt";
  1297. plotheader!* := "";
  1298. dirchar!* := ":";
  1299. plotdta!* := for each n in
  1300. {"::::gnuplot:gnutmp.tm1", "::::gnuplot:gnutmp.tm2",
  1301. "::::gnuplot:gnutmp.tm3", "::::gnuplot:gnutmp.tm4",
  1302. "::::gnuplot:gnutmp.tm5", "::::gnuplot:gnutmp.tm6",
  1303. "::::gnuplot:gnutmp.tm7", "::::gnuplot:gnutmp.tm8"}
  1304. collect gtmpnam n;
  1305. plotcleanup!* := nil >>
  1306. else <<
  1307. rederr bldmsg("gnuplot for %w not available yet", opsys!*);
  1308. plotdta!* := for i:=1:10 collect tmpnam();
  1309. plotcmds!*:= tmpnam();
  1310. plotheader!* := "set term dumb" >>;
  1311. if 'pipes member lispsystem!* then !*plotusepipe:=t
  1312. else plotcommand!* := bldmsg("%w %w", plotcommand!*, plotcmds!*);
  1313. if plotdir!* then
  1314. plotcommand!* := bldmsg("%w%w%w",
  1315. plotdir!*, dirchar!*, plotcommand!*);
  1316. nil >>;
  1317. endpatch;
  1318. patch poly;
  1319. % 7 Aug 99.
  1320. symbolic procedure rationalizesq u;
  1321. begin scalar !*structure,!*sub2,v,x;
  1322. if x := get(dmode!*,'rationalizefn) then u := apply1(x,u);
  1323. powlis!* := '(i 2 (nil . t) -1 nil) . powlis!*;
  1324. v := subs2q u;
  1325. powlis!* := cdr powlis!*;
  1326. return if domainp denr v then v
  1327. else if (x := rationalizef denr v) neq 1
  1328. then <<v := multf(numr v,x) ./ multf(denr v,x);
  1329. if null !*algint and null !*rationalize
  1330. then v := gcdchk v;
  1331. subs2q v>>
  1332. else u
  1333. end;
  1334. % 6 Feb 00, 7 Sep 01.
  1335. symbolic procedure sqfrf u;
  1336. begin integer n; scalar !*gcd,units,v,w,x,y,z,!*msg,r;
  1337. !*gcd := t;
  1338. if (r := !*rounded) then
  1339. <<on rational; u := numr resimp !*f2q u>>;
  1340. n := 1;
  1341. x := mvar u;
  1342. v := gcdf(u,diff(u,x));
  1343. u := quotf(u,v);
  1344. if flagp(dmode!*,'field) and ((y := lnc u) neq 1)
  1345. then <<u := multd(!:recip y,u); v := multd(y,v)>>;
  1346. while degr(v,x)>0 do
  1347. <<w := gcdf(v,u);
  1348. if u neq w then z := (quotf(u,w) . n) . z;
  1349. v := quotf(v,w);
  1350. u := w;
  1351. n := n + 1>>;
  1352. if r then
  1353. <<on rounded;
  1354. u := numr resimp !*f2q u;
  1355. z := for each j in z
  1356. collect numr resimp !*f2q car j . cdr j>>;
  1357. if v neq 1 and assoc(v,units) then v := 1;
  1358. if v neq 1 then if n=1 then u := multf(v,u)
  1359. else if (w := rassoc(1,z)) then rplaca(w,multf(v,car w))
  1360. else if null z and ((w := rootxf(v,n)) neq 'failed)
  1361. then u := multf(w,u)
  1362. else if not domainp v then z := aconc(z,v . 1)
  1363. else errach {"sqfrf failure",u,n,z};
  1364. return (u . n) . z
  1365. end;
  1366. % 2 Aug 00.
  1367. symbolic procedure sqfrp u;
  1368. begin scalar !*ezgcd, dmode!*;
  1369. if null getd 'ezgcdf1 then load_package ezgcd;
  1370. !*ezgcd := t;
  1371. return domainp gcdf!*(u,diff(u,mvar u))
  1372. end;
  1373. % 13 Dec 00.
  1374. symbolic procedure gcdk(u,v);
  1375. begin scalar lclst,var,w,x;
  1376. if u=v then return u
  1377. else if domainp u or degr(v,(var := mvar u))=0 then return 1
  1378. else if ldeg u<ldeg v then <<w := u; u := v; v := w>>;
  1379. if quotf1(u,v) then return v
  1380. else if !*heugcd and (x := heu!-gcd(u,v)) then return x
  1381. else if ldeg v=1
  1382. or getd 'modular!-multicheck and modular!-multicheck(u,v,var)
  1383. or not !*mcd
  1384. then return 1;
  1385. a: w := remk(u,v);
  1386. if null w then return v
  1387. else if degr(w,var)=0 then return 1;
  1388. lclst := addlc(v,lclst);
  1389. if x := quotf1(w,lc w) then w := x
  1390. else for each y in lclst do
  1391. if atom y and not flagp(dmode!*,'field)
  1392. or not
  1393. (domainp y and (flagp(dmode!*,'field)
  1394. or ((x := get(car y,'units))
  1395. and y member (for each z in x collect car z))))
  1396. then while (x := quotf1(w,y)) do w := x;
  1397. u := v; v := prim!-part w;
  1398. if degr(v,var)=0 then return 1 else go to a
  1399. end;
  1400. % 19 Jan 01.
  1401. symbolic procedure quarticf pol;
  1402. begin scalar !*sub2,a,a2,a0,b,dsc,p,p1,p2,q,shift,var;
  1403. var := mvar pol;
  1404. p := shift!-pol pol;
  1405. a := coeffs car p;
  1406. shift := caddr p;
  1407. if cadr a then rerror(poly,16,list(pol,"not correctly shifted"))
  1408. else if cadddr a then return list(1,pol);
  1409. a2 := cddr a;
  1410. a0 := caddr a2;
  1411. a2 := car a2;
  1412. a := car a;
  1413. q := quadraticf1(a,a2,a0);
  1414. if not(q eq 'failed)
  1415. then <<a2 := car q; q := cdr q;
  1416. a := exptsq(addsq(!*k2q mvar pol,shift),2);
  1417. b := numr subs2q quotsq(addsq(multsq(!*f2q car q,a),
  1418. !*f2q cadr q),
  1419. !*f2q cadr p);
  1420. a := numr subs2q quotsq(addsq(multsq(!*f2q caddr q,a),
  1421. !*f2q cadddr q),
  1422. !*f2q cadr p);
  1423. a := quadraticf!*(a,var);
  1424. b := quadraticf!*(b,var);
  1425. return multf(a2,multf(car a,car b))
  1426. . nconc!*(cdr a,cdr b)>>
  1427. else if null !*surds or denr shift neq 1
  1428. then return list(1,pol);
  1429. shift := numr shift;
  1430. if knowndiscrimsign eq 'negative then go to complex;
  1431. dsc := powsubsf addf(exptf(a2,2),multd(-4,multf(a,a0)));
  1432. p2 := minusf a0;
  1433. if not p2 and minusf dsc then go to complex;
  1434. p1 := not a2 or minusf a2;
  1435. if not p1 then if p2 then p1 := t else p2 := t;
  1436. p1 := if p1 then 'positive else 'negative;
  1437. p2 := if p2 then 'negative else 'positive;
  1438. a := rootxf(a,2);
  1439. if a eq 'failed then return list(1,pol);
  1440. dsc := rootxf(dsc,2);
  1441. if dsc eq 'failed then return list(1,pol);
  1442. p := invsq !*f2q addf(a,a);
  1443. q := multsq(!*f2q addf(a2,negf dsc),p);
  1444. p := multsq(!*f2q addf(a2,dsc),p);
  1445. b := multf(a,exptf(addf(!*k2f mvar pol,shift),2));
  1446. a := powsubsf addf(b,q);
  1447. b := powsubsf addf(b,p);
  1448. knowndiscrimsign := p1;
  1449. a := quadraticf!*(a,var);
  1450. knowndiscrimsign := p2;
  1451. b := quadraticf!*(b,var);
  1452. knowndiscrimsign := nil;
  1453. return multf(car a,car b) . nconc!*(cdr a,cdr b);
  1454. complex:
  1455. a := rootxf(a,2);
  1456. if a eq 'failed then return list(1,pol);
  1457. a0 := rootxf(a0,2);
  1458. if a0 eq 'failed then return list(1,pol);
  1459. a2 := powsubsf addf(multf(2,multf(a,a0)),negf a2);
  1460. a2 := rootxf(a2,2);
  1461. if a2 eq 'failed then return list(1,pol);
  1462. p := addf(!*k2f mvar pol,shift);
  1463. q := addf(multf(a,exptf(p,2)),a0);
  1464. p := multf(a2,p);
  1465. a := powsubsf addf(q,p);
  1466. b := powsubsf addf(q,negf p);
  1467. knowndiscrimsign := 'negative;
  1468. a := quadraticf!*(a,var);
  1469. b := quadraticf!*(b,var);
  1470. knowndiscrimsign := nil;
  1471. return multf(car a,car b) . nconc!*(cdr a,cdr b)
  1472. end;
  1473. % 7 Apr 01.
  1474. symbolic procedure factorize u;
  1475. (begin scalar x,y;
  1476. x := simp!* u;
  1477. y := denr x;
  1478. if not domainp y then typerr(u,"polynomial");
  1479. u := numr x;
  1480. if u = 1 then return
  1481. {'list, if !*nopowers then 1 else {'list,1,1}}
  1482. else if fixp u then !*ifactor := t;
  1483. if !*force!-prime and not primep !*force!-prime
  1484. then typerr(!*force!-prime,"prime");
  1485. u := if dmode!* and not(dmode!* memq '(!:rd!: !:cr!:))
  1486. then if get(dmode!*,'factorfn)
  1487. then begin scalar !*factor;
  1488. !*factor := t;
  1489. return fctrf u
  1490. end
  1491. else rerror(poly,14,
  1492. list("Factorization not supported over domain",
  1493. get(dmode!*,'dname)))
  1494. else fctrf u;
  1495. return facform2list(u,y)
  1496. end) where !*ifactor = !*ifactor;
  1497. % 7 Apr 01, 24 Aug 01.
  1498. symbolic procedure factor!-prim!-sqfree!-f u;
  1499. begin scalar x,y,!*msg,r;
  1500. r := !*rounded;
  1501. if r and univariatep numr u and lc numr u=1 and denr u=1
  1502. then return unifactor u
  1503. else if r or !*complex or !*rational then
  1504. <<if r then on rational;
  1505. u := numr resimp !*f2q car u . cdr u>>;
  1506. if null !*limitedfactors
  1507. then <<if null dmode!* then y := 'factorf
  1508. else <<x := get(dmode!*,'sqfrfactorfn);
  1509. y := get(dmode!*,'factorfn);
  1510. if x and not(x eq y) then y := 'factorf>>;
  1511. if y
  1512. then <<y := apply1(y,car u);
  1513. u := (exptf(car y,cdr u) . for each j in cdr y
  1514. collect(car j . cdr u));
  1515. go to ret>>>>;
  1516. u := factor!-prim!-sqfree!-f!-1(car u,cdr u);
  1517. ret: if r then
  1518. <<on rounded;
  1519. u := car u . for each j in cdr u collect
  1520. (numr resimp !*f2q car j . cdr j)>>;
  1521. return u
  1522. end;
  1523. % 7 Apr 01.
  1524. symbolic procedure unifactor u;
  1525. if not eqcar(u := root_val list mk!*sq u,'list)
  1526. then errach {"unifactor1",u}
  1527. else 1 . for each j in cdr u collect
  1528. if not eqcar(j,'equal) then errach{"unifactor2",u}
  1529. else addsq(!*k2q cadr j,negsq simp caddr j);
  1530. % 11 Jun 01.
  1531. symbolic procedure noncomp u;
  1532. !*ncmp and noncomp1 u;
  1533. symbolic procedure noncomp1 u;
  1534. if null pairp u then nil
  1535. else if pairp car u then noncomfp u
  1536. else flagp(car u,'noncom) or noncomlistp cdr u;
  1537. symbolic procedure noncomlistp u;
  1538. pairp u and (noncomp1 car u or noncomlistp cdr u);
  1539. endpatch;
  1540. % Rlisp declarations.
  1541. fluid '(newrules!*);
  1542. patch rlisp;
  1543. % 9 Nov 99.
  1544. symbolic procedure load!-package u;
  1545. begin scalar x,y;
  1546. if stringp u then return load!-package intern compress explode2 u
  1547. else if null idp u then rederr list(u,"is not a package name")
  1548. else if memq(u,loaded!-packages!*)
  1549. then return u
  1550. else if or(atom(x:= errorset(list('evload,list('quote,list u)),
  1551. nil,!*backtrace)),
  1552. cdr x)
  1553. then rederr
  1554. list("error in loading package",u,"or package not found");
  1555. loaded!-packages!* := u . loaded!-packages!*;
  1556. x := get(u,'package);
  1557. if x then x := cdr x;
  1558. a: if null x then go to b
  1559. else if null atom get(car x,'package) then load!-package car x
  1560. else if or(atom(y := errorset(list('evload,
  1561. list('quote,list car x)),
  1562. nil,!*backtrace)),
  1563. cdr y)
  1564. then rederr list("module",car x,"of package",u,
  1565. "cannot be loaded");
  1566. x := cdr x;
  1567. go to a;
  1568. b: if (x := get(u,'patchfn))
  1569. then begin scalar !*usermode,!*redefmsg; eval list x end
  1570. end;
  1571. % 22 April 00.
  1572. symbolic procedure begin11 x;
  1573. begin scalar mode,result,newrule!*;
  1574. if cursym!* eq 'end
  1575. then if terminalp() and null !*lisp!_hook
  1576. then progn(cursym!* := '!*semicol!*, !*nosave!* := t,
  1577. return nil)
  1578. else progn(comm1 'end, return 'end)
  1579. else if eqcar((if !*reduce4 then x else cadr x),'retry)
  1580. then if programl!* then x := programl!*
  1581. else progn(lprim "No previous expression",return nil);
  1582. if null !*reduce4 then progn(mode := car x,x := cadr x);
  1583. program!* := x;
  1584. if eofcheck() then return 'c else eof!* := 0;
  1585. add2inputbuf(x,if !*reduce4 then nil else mode);
  1586. if null atom x
  1587. and car x memq '(bye quit)
  1588. then if getd 'bye
  1589. then progn(lispeval x, !*nosave!* := t, return nil)
  1590. else progn(!*byeflag!* := t, return nil)
  1591. else if null !*reduce4 and eqcar(x,'ed)
  1592. then progn((if getd 'cedit and terminalp()
  1593. then cedit cdr x
  1594. else lprim "ED not supported"),
  1595. !*nosave!* := t, return nil)
  1596. else if !*defn
  1597. then if erfg!* then return nil
  1598. else if null flagp(key!*,'ignore)
  1599. and null eqcar(x,'quote)
  1600. then progn((if x then dfprint x else nil),
  1601. if null flagp(key!*,'eval) then return nil);
  1602. if !*output and ifl!* and !*echo and null !*lessspace
  1603. then terpri();
  1604. result := errorset!*(x,t);
  1605. if errorp result or erfg!*
  1606. then progn(programl!* := list(mode,x),return 'err2)
  1607. else if !*defn then return nil;
  1608. if null !*reduce4
  1609. then if null(mode eq 'symbolic) then x := getsetvars x else nil
  1610. else progn(result := car result,
  1611. (if null result then result := mkobject(nil,'noval)),
  1612. mode := type result,
  1613. result := value result);
  1614. add2resultbuf((if null !*reduce4 then car result else result),
  1615. mode);
  1616. if null !*output then return nil
  1617. else if null(semic!* eq '!$)
  1618. then if !*reduce4 then (begin
  1619. terpri();
  1620. if mode eq 'noval then return nil
  1621. else if !*debug then prin2t "Value:";
  1622. rapply1('print,list list(mode,result))
  1623. end)
  1624. else if mode eq 'symbolic
  1625. then if null car result and null(!*mode eq 'symbolic)
  1626. then nil
  1627. else begin
  1628. terpri();
  1629. result:=
  1630. errorset!*(list('print,mkquote car result),t)
  1631. end
  1632. else if car result
  1633. then result := errorset!*(list('assgnpri,mkquote car result,
  1634. (if x then 'list . x else nil),
  1635. mkquote 'only),
  1636. t);
  1637. if null !*reduce4
  1638. then return if errorp result then 'err3 else nil
  1639. else if null(!*mode eq 'noval)
  1640. then progn(terpri(), prin2 "of type: ", print mode);
  1641. return nil
  1642. end;
  1643. endpatch;
  1644. % Roots declarations.
  1645. % fluid '(rootacc!#!# rootacc!#!# !*noeqns);
  1646. % patch roots;
  1647. % 10 Feb 00.
  1648. % Commented out since now solved another way (7 Apr 01).
  1649. % symbolic procedure root_val x;
  1650. % roots x
  1651. % where rootacc!#!#=p, iniprec!#=p where p=precision 0, !*msg=nil,
  1652. % !*noeqns=t;
  1653. % endpatch;
  1654. % Scope declarations.
  1655. global '(kvarlst prevlst varlst!*);
  1656. patch scope;
  1657. % 29 Aug 00.
  1658. symbolic procedure maxtype type;
  1659. if atom type then type
  1660. else if pairp cdr type then cadr type else car type;
  1661. % 8 Nov 00.
  1662. symbolic procedure prepmultmat(preprefixlist);
  1663. begin scalar tlcm,var,varexp,kvl,kfound,pvl,pfound,tel,ratval,ratlst,
  1664. newvarlst,hvarlst;
  1665. hvarlst:= nil;
  1666. while not null (varlst!*) do
  1667. <<var := car varlst!*; varlst!* := cdr varlst!*;
  1668. if flagp(var,'ratexp)
  1669. then
  1670. <<tlcm:=1;
  1671. remflag(list var,'ratexp);
  1672. foreach elem in get(var,'varlst!*) do
  1673. if pairp cdr elem then tlcm := lcm2(tlcm,cddr elem);
  1674. varexp:=fnewsym();
  1675. tel:=(varexp.(if tlcm = 2
  1676. then list('sqrt,var)
  1677. else list('expt,var,
  1678. if onep cdr(tel:=simpquot list(1,tlcm)) then
  1679. car tel
  1680. else
  1681. list('quotient,car tel,cdr tel))));
  1682. if assoc(var,kvarlst)
  1683. then
  1684. <<kvl:=kfound:=nil;
  1685. while kvarlst and not(kfound) do
  1686. if caar(kvarlst) eq var
  1687. then
  1688. << kvl:=tel.kvl; kfound:=t;
  1689. pvl:=pfound:=nil; prevlst:=reverse(prevlst);
  1690. while prevlst and not(pfound) do
  1691. if cdar(prevlst) eq var
  1692. then << pvl:=cons(caar prevlst,varexp).pvl;
  1693. pfound:=t
  1694. >>
  1695. else << pvl:=car(prevlst).pvl;
  1696. prevlst:=cdr(prevlst)
  1697. >>;
  1698. if pvl then
  1699. if prevlst then prevlst:=append(reverse prevlst,pvl)
  1700. else prevlst:=pvl
  1701. >>
  1702. else
  1703. << kvl:=car(kvarlst).kvl; kvarlst:=cdr kvarlst>>;
  1704. if kvl then
  1705. if kvarlst then kvarlst:=append(reverse kvl,kvarlst)
  1706. else kvarlst:=reverse kvl
  1707. >>
  1708. else preprefixlist:=tel.preprefixlist;
  1709. ratlst:=newvarlst:=nil;
  1710. foreach elem in get(var,'varlst!*) do
  1711. if pairp cdr elem
  1712. then
  1713. << ratval:=divide((tlcm * cadr elem)/(cddr elem),tlcm);
  1714. ratlst:=cons(car elem,cdr ratval).ratlst;
  1715. if car(ratval)>0
  1716. then newvarlst:=cons(car elem,car ratval).newvarlst
  1717. >>
  1718. else newvarlst:=elem.newvarlst;
  1719. if ratlst
  1720. then << put(varexp,'varlst!*,reverse ratlst);
  1721. hvarlst:=varexp.hvarlst
  1722. >>;
  1723. if newvarlst
  1724. then << put(var,'varlst!*,reverse newvarlst);
  1725. hvarlst:=var.hvarlst
  1726. >>
  1727. else remprop(var,'varlst!*)
  1728. >>
  1729. else hvarlst:=var.hvarlst
  1730. >>;
  1731. varlst!* := hvarlst;
  1732. return preprefixlist
  1733. end;
  1734. endpatch;
  1735. % Solve declarations.
  1736. fluid '(!*multiplicities vars!*);
  1737. global '(multiplicities!*);
  1738. patch solve;
  1739. % 9 Jan 01.
  1740. symbolic procedure !*solvelist2solveeqlist u;
  1741. begin scalar x,y,z;
  1742. u := for each j in u collect solveorder j;
  1743. for each j in u do
  1744. <<if caddr j=0 then rerror(solve,2,"zero multiplicity")
  1745. else if null cadr j
  1746. then x := for each k in car j collect
  1747. list('equal,!*q2a k,0)
  1748. else x := for each k in pair(cadr j,car j)
  1749. collect list('equal,car k,!*q2a cdr k);
  1750. if length vars!* > 1 then x := 'list . x else x := car x;
  1751. z := (caddr j . x) . z>>;
  1752. z := sort(z,function ordp);
  1753. x := nil;
  1754. if !*multiplicities
  1755. then <<for each k in z do for i := 1:car k do x := cdr k . x;
  1756. multiplicities!* := nil>>
  1757. else <<for each k in z do << x := cdr k . x; y := car k . y>>;
  1758. multiplicities!* := 'list . reversip y>>;
  1759. return 'list . reversip x
  1760. end;
  1761. % 9 Jan 01, 15 Jun 01.
  1762. symbolic procedure solveorder u;
  1763. begin scalar v,w,x,y,z;
  1764. v := vars!*;
  1765. x := cadr u;
  1766. if length x<length v then v := setdiff(v,setdiff(v,x));
  1767. if null x or x=v then return u;
  1768. y := car u;
  1769. while x do <<z := (car x . car y) . z; x := cdr x; y := cdr y>>;
  1770. w := v;
  1771. a: if null w then return reversip x . v . cddr u
  1772. else if null(y := depassoc(car w,z)) then return u
  1773. else x := cdr y . x;
  1774. w := cdr w;
  1775. go to a
  1776. end;
  1777. symbolic procedure depassoc(u,v);
  1778. if null v then nil
  1779. else if u = caar v then car v
  1780. else if depends(caar v,u) then nil
  1781. else depassoc(u,cdr v);
  1782. % 2 Feb 01.
  1783. symbolic procedure check!-solns(z,ex,var);
  1784. begin scalar x;
  1785. if errorp (x :=
  1786. errorset2 {'check!-solns1,mkquote z,mkquote ex,mkquote var})
  1787. then return
  1788. check!-solns1(z,(numr simp!* prepf ex where !*reduced=t),var)
  1789. else return car x
  1790. end;
  1791. symbolic procedure check!-solns1(z,ex,var);
  1792. begin scalar x,y,fv,sx,vs;
  1793. fv := freevarl(ex,var);
  1794. for each z1 in z do
  1795. fv := union(fv,union(freevarl(numr caar z1,var),
  1796. freevarl(denr caar z1,var)));
  1797. fv := delete('i,fv);
  1798. if fv then for each v in fv do
  1799. if not flagp(v,'constant) then
  1800. vs := (v . list('quotient,1+random 999,1000)) . vs;
  1801. sx := if vs then numr subf(ex,vs) else ex;
  1802. while z do
  1803. if null cadar z then <<z := nil; x := 'unsolved>>
  1804. else if
  1805. <<y := numr subf(ex,list(caadar z . mk!*sq caaar z));
  1806. null y
  1807. or fv and null(y := numr subf(sx,list(caadar z .
  1808. mk!*sq subsq(caaar z,vs))))
  1809. or null numvalue y>>
  1810. then <<x := car z . x; z := cdr z>>
  1811. else z := cdr z;
  1812. return if null x then 'unsolved else x
  1813. end;
  1814. % 7 Apr 01.
  1815. symbolic procedure solvequadratic(a2,a1,a0);
  1816. if !*rounded and numcoef a0 and numcoef a1 and numcoef a2
  1817. then for each z in cdr root_val list mkpolyexp2(a2,a1,a0)
  1818. collect simp!* (if eqcar(z,'equal) then caddr z
  1819. else errach {"Quadratic confusion",z})
  1820. else begin scalar d;
  1821. d := sqrtq subtrsq(quotsqf(exptsq(a1,2),4),multsq(a2,a0));
  1822. a1 := quotsqf(negsq a1,2);
  1823. return list(subs2!* quotsq(addsq(a1,d),a2),
  1824. subs2!* quotsq(subtrsq(a1,d),a2))
  1825. end;
  1826. endpatch;
  1827. % Sum declarations.
  1828. fluid '(sum_last_attempt_rules!* !*zeilberg);
  1829. patch sum;
  1830. % 28 Jul 00.
  1831. symbolic procedure freeof!-df(u, v);
  1832. if atom u then t
  1833. else if car(u) eq 'df
  1834. then freeof!-df(cadr u, v) and not smember(v,cddr u)
  1835. else freeof!-dfl(cdr u, v);
  1836. symbolic procedure freeof!-dfl(u, v);
  1837. if null u then t else freeof!-df(car u,v) and freeof!-dfl(cdr u,v);
  1838. symbolic procedure simp!-sum u;
  1839. begin scalar y;
  1840. y := cdr u;
  1841. u := car u;
  1842. if not atom y and not freeof!-df(u, car y) then
  1843. if atom y
  1844. then return !*p2f(car fkern(list('sum,u)) .* 1) ./ 1
  1845. else return sum!-df(u, y);
  1846. u := simp!* u;
  1847. return if null numr u then u
  1848. else if atom y
  1849. then !*p2f(car fkern(list('sum,prepsq u)) .* 1) ./ 1
  1850. else if !*zeilberg then gosper!*(mk!*sq u,y)
  1851. else simp!-sum0(u,y)
  1852. end;
  1853. symbolic procedure sum!-subst(u,x,a);
  1854. if u = x then a
  1855. else if atom u then u
  1856. else sum!-subst(car u, x,a) . sum!-subst(cdr u,x,a);
  1857. symbolic procedure sum!-df(u,y);
  1858. begin scalar w,z,upper,lower,dif;
  1859. if length(y) = 3 then <<
  1860. lower := cadr y;
  1861. upper := caddr y;
  1862. dif := addsq(simp!* upper, negsq simp!* lower);
  1863. if denr dif = 1 then
  1864. if null numr dif
  1865. then return simp!* sum!-subst(u, car y, upper)
  1866. else if fixp numr dif then dif := numr dif
  1867. else dif := nil
  1868. else dif := nil;
  1869. if dif and dif <= 0 then return nil ./ 1 >>;
  1870. if null dif then <<
  1871. z := 'sum . (u . y);
  1872. let sum_last_attempt_rules!*;
  1873. w:= opmtch z;
  1874. rule!-list (list sum_last_attempt_rules!*,nil);
  1875. return if w then simp w else mksq(z,1)>>;
  1876. z := nil ./ 1;
  1877. a: if dif < 0 then return z;
  1878. z := addsq(z,simp!* sum!-subst(u, car y, list('plus,lower,dif)));
  1879. dif := dif - 1;
  1880. go to a
  1881. end;
  1882. % 20 Nov 00.
  1883. symbolic procedure termlst(u,v,klst);
  1884. begin scalar x,kern,lst;
  1885. if null u then return nil
  1886. else if null klst or domainp u
  1887. then return list multsq(v,!*f2q u);
  1888. kern := car klst;
  1889. klst := cdr klst;
  1890. x := setkorder list kern;
  1891. u := reorder u;
  1892. v := reorder(numr v) ./ reorder(denr v);
  1893. while not domainp u and mvar u eq kern do <<
  1894. lst := nconc(termlst(lc u, multsq(!*p2q lpow u, v),klst),lst);
  1895. u := red u>>;
  1896. if u then lst := nconc(termlst(u,v,klst),lst);
  1897. setkorder x;
  1898. return lst
  1899. end;
  1900. endpatch;
  1901. % Taylor declarations.
  1902. fluid '(!*taylorautocombine);
  1903. patch taylor;
  1904. % 1 Jun 01.
  1905. symbolic procedure simptaylor u;
  1906. if remainder(length u,3) neq 1
  1907. then Taylor!-error('wrong!-no!-args,'taylor)
  1908. else if null subfg!* then mksq('taylor . u,1)
  1909. else begin scalar !*precise,arglist,degree,f,ll,result,var,var0;
  1910. if !*taylorautocombine and not ('taysimpsq memq mul!*)
  1911. then mul!* := aconc!*(mul!*,'taysimpsq);
  1912. f := simp!* car u;
  1913. u := revlis cdr u;
  1914. arglist := u;
  1915. while not null arglist do
  1916. << var := car arglist;
  1917. var := if eqcar(var,'list) then cdr var else {var};
  1918. for each el in var collect begin
  1919. el := simp!* el;
  1920. if kernp el then return mvar numr el
  1921. else typerr(prepsq el,'kernel)
  1922. end;
  1923. var0 := cadr arglist;
  1924. degree := caddr arglist;
  1925. if not fixp degree
  1926. then typerr(degree,"order of Taylor expansion");
  1927. arglist := cdddr arglist;
  1928. ll := {var,var0,degree,degree + 1} . ll>>;
  1929. result := taylorexpand(f,reversip ll);
  1930. return if smember('Taylor!*,result) then result
  1931. else mksq('taylor . prepsq f . u,1)
  1932. end;
  1933. endpatch;
  1934. endmodule;
  1935. end;