int.red 109 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781
  1. COMMENT REDUCE INTEGRATION PACKAGE WITHOUT ALGEBRAIC EXTENSIONS;
  2. COMMENT Messages look better if one does OFF RAISE;
  3. OFF ECHO;
  4. SYMBOLIC;
  5. FLAG('(INTERR),'TRANSFER); %For the compiler;
  6. COMMENT SMACRO's needed to support Cambridge LISP constructs;
  7. SMACRO PROCEDURE EVENP X; REMAINDER(X,2)=0;
  8. SMACRO PROCEDURE GCD(U,V); GCDN(U,V);
  9. INFIX IEQUAL;
  10. SYMBOLIC SMACRO PROCEDURE U IEQUAL V; EQN(U,V);
  11. SMACRO PROCEDURE READCLOCK; TIME();
  12. SMACRO PROCEDURE REVERSEWOC U; REVERSIP U;
  13. SMACRO PROCEDURE SUPERPRINT U; PRETTYPRINT U;
  14. %the next two are needed since arguments may not be numbers;
  15. SMACRO PROCEDURE ONEP U; U=1;
  16. SMACRO PROCEDURE ZEROP U; U=0;
  17. COMMENT The following three smacros can be used if there is a reason
  18. for not using actual vectors;
  19. %SMACRO PROCEDURE MKVECT N; %MKNILL(N+1);
  20. %SMACRO PROCEDURE PUTV(U,N,V); %CAR RPLACA(PNTH(U,N+1),V);
  21. %SMACRO PROCEDURE GETV(U,N); %NTH(U,N+1);
  22. COMMENT End of Cambridge LISP compatibility section;
  23. FLUID '(LORDER SILLIESLIST VARLIST);
  24. GLOBAL '(GENSYMCOUNT);
  25. SYMBOLIC SMACRO PROCEDURE !*F2POL U;
  26. %U is a standard form;
  27. %Value is a polynomial form after power substitutions made;
  28. %If a quotient results from substitutions, an error occurs;
  29. !*Q2F SUBS2F U;
  30. SYMBOLIC SMACRO PROCEDURE !*MULTF!*(U,V); MULTF(U,V);
  31. SYMBOLIC PROCEDURE FLATTEN U;
  32. IF NULL U THEN NIL
  33. ELSE IF ATOM U THEN LIST U
  34. ELSE IF ATOM CAR U THEN CAR U . FLATTEN CDR U
  35. ELSE NCONC(FLATTEN CAR U,FLATTEN CDR U);
  36. SYMBOLIC PROCEDURE GENSYM1 U;
  37. << GENSYMCOUNT:=GENSYMCOUNT+1;
  38. COMPRESS APPEND(EXPLODE U,EXPLODE GENSYMCOUNT) >>;
  39. SYMBOLIC SMACRO PROCEDURE PRINTC X; PRIN2T X;
  40. SYMBOLIC PROCEDURE MKNILL N;
  41. IF N=0 THEN NIL ELSE NIL . MKNILL(N-1);
  42. SYMBOLIC PROCEDURE SQRT N;
  43. % return sqrt of n if same is exact, or something non-numeric
  44. % otherwise;
  45. IF NOT NUMBERP N THEN 'NONNUMERIC
  46. ELSE IF N<0 THEN 'NEGATIVE
  47. ELSE IF FLOATP N THEN SQRT!-FLOAT N
  48. ELSE IF N<2 THEN N
  49. ELSE NR(N,(N+1)/2);
  50. SYMBOLIC PROCEDURE NR(N,ROOT);
  51. % root is an overestimate here. nr moves downwards to root;
  52. BEGIN
  53. SCALAR W;
  54. W:=ROOT*ROOT;
  55. IF N=W THEN RETURN ROOT;
  56. W:=(ROOT+N/ROOT)/2;
  57. IF W>=ROOT THEN RETURN !*P2F MKSP(MKSQRT N,1);
  58. RETURN NR(N,W)
  59. END;
  60. GLOBAL '(SQRT!-FLOAT!-TOLERANCE);
  61. SQRT!-FLOAT!-TOLERANCE := 0.00001;
  62. SYMBOLIC PROCEDURE SQRT!-FLOAT N;
  63. % Simple Newton-Raphson floating point square root calculator.
  64. % Not warranted against truncation errors, etc;
  65. BEGIN INTEGER SCALE; SCALAR ANS;
  66. IF N<0.0 THEN REDERR "SQRT!-FLOAT GIVEN NEGATIVE ARGUMENT";
  67. % Scale argument to within 1e-10 to 1e+10;
  68. SCALE := 0;
  69. WHILE N > 1E+10 DO <<
  70. SCALE := SCALE + 1;
  71. N := N/1E+10 >>;
  72. WHILE N < 1E-10 DO <<
  73. SCALE := SCALE - 1;
  74. N := N*1E-10 >>;
  75. ANS := IF N>2.0 THEN (N+1)/2
  76. ELSE IF N<0.5 THEN 2/(N+1)
  77. ELSE N;
  78. WHILE ABS(ANS**2/N - 1.0) > SQRT!-FLOAT!-TOLERANCE DO
  79. ANS := 0.5*(ANS+N/ANS);
  80. RETURN ANS*10**(5*SCALE)
  81. END;
  82. COMMENT Kludge to define derivative of an integral;
  83. SYMBOLIC PUT('DF,'OPMTCH,'(((INT !&Y !&X) !&X) (NIL . T)
  84. (EVL!* !&Y) NIL) . GET('DF,'OPMTCH));
  85. GLOBAL '(FRLIS!*);
  86. SYMBOLIC FRLIS!* := '!&X . '!&Y . FRLIS!*;
  87. SYMBOLIC IF NOT GETD 'MODBIND
  88. THEN <<PUT('EVL!*,'OPMTCH,'(((!&X) (NIL . T) !&X NIL)));
  89. PUT('EVL!*,'SIMPFN,'SIMPIDEN)>>;
  90. % MKOP 'SQRT>>;
  91. %distinguish between mode and non-mode system;
  92. ALGEBRAIC;
  93. %FOR ALL X LET SQRT X**2=X;
  94. SYMBOLIC;
  95. COMMENT support for module use;
  96. GLOBAL '(EXPORTSLIST!* IMPORTSLIST!* !*MODULEP);
  97. DEFLIST('((EXPORTS RLIS) (IMPORTS RLIS) (MODULE RLIS)
  98. (ENDMODULE ENDSTAT)),'STAT);
  99. SYMBOLIC PROCEDURE EXPORTS U;
  100. BEGIN
  101. EXPORTSLIST!* := UNION(U,EXPORTSLIST!*);
  102. END;
  103. SYMBOLIC PROCEDURE IMPORTS U;
  104. BEGIN
  105. IMPORTSLIST!* := UNION(U,IMPORTSLIST!*);
  106. END;
  107. SYMBOLIC PROCEDURE MODULE U;
  108. %Sets up a module definition;
  109. BEGIN
  110. !*MODULEP := T;
  111. END;
  112. SYMBOLIC PROCEDURE ENDMODULE;
  113. BEGIN
  114. EXPORTSLIST!* := NIL;
  115. IMPORTSLIST!* := NIL;
  116. !*MODULEP := NIL
  117. END;
  118. %**********************************************************************;
  119. % SET REDUCE AND LISP OPTIONS ONCE AND FOR ALL;
  120. %ON COMP;
  121. % ALL FLUID VARIABLES ARE DECLARED HERE;
  122. FLUID '(CONTENT SQFR ZLIST INDEXLIST SQRTLIST )$
  123. FLUID '(!*MCD !*GCD !*EXP !*SQRT !*STRUCTURE);
  124. FLUID '( PT ULIST
  125. REDUCTIONEQ LOGLIST CLIST CCOUNT CVAL CMAP TANLIST LHS
  126. BADPART CUBEROOTFLAG VARLIST CLOGFLAG EXPRESSION RESIDUE
  127. VARIABLE ORDEROFELIM CMATRIX DENOMINATOR TAYLORVARIABLE
  128. !*PURERISCH !*NOLNR);
  129. %FLAGS TO BE SET USING 'ON' AND 'OFF' STATEMENTS;
  130. GLOBAL '(!*RATINTSPECIAL !*TRINT !*SEPLOGS !*FAILHARD !*TRDIV
  131. !*STATISTICS !*NUMBER!* !*SPSIZE!*
  132. BTRLEVEL !*GENSYMLIST!*);
  133. BTRLEVEL:=5; %DEFAULT TO A REASONABLY FULL BACKTRACE;
  134. ON SEPLOGS;%,OVERLAYMODE;
  135. %TOPLEVELCODE:='(COMPILER RLISP APROC);
  136. %**********************************************************************;
  137. SMACRO PROCEDURE FIRSTSUBS U;
  138. CAR U;
  139. % THE FIRST SUBSTITUTION IN A SUBSTITUTION LIST;
  140. SMACRO PROCEDURE RSUBS U;
  141. CDR U;
  142. SMACRO PROCEDURE LSUBS U;
  143. CAR U;
  144. % THE ABOVE TWO FUNCTIONS DEFINE LEFT AND RIGHT HALVES OF A
  145. % SUBSTITUTION RULE;
  146. SMACRO PROCEDURE LFIRSTSUBS U;
  147. CAAR U;
  148. SMACRO PROCEDURE RFIRSTSUBS U;
  149. CDAR U;
  150. % SOME COMBINATIONS OF THE ABOVE;
  151. SMACRO PROCEDURE ARGOF U;
  152. CADR U;
  153. % THE ARGUMENT OF A UNARY FUNCTION;
  154. FLAG ('(ATAN DILOG ERF EXPINT EXPT LOG TAN),'TRANSCENDENTAL);
  155. ALGEBRAIC;
  156. %Patterns for integration of various logarithmic cases;
  157. %FOR ALL X,A,B,C,D LET INT(LOG(A*X+B)/(C*X+D),X)=
  158. % LOG(C*X+D)*LOG(B*C-A*D)/C - LOG C*LOG(C*X+D)/C
  159. % - DILOG((A*C*X+B*C)/(B*C-A*D))/C;
  160. %% A=1;
  161. %FOR ALL X,B,C,D LET INT(LOG(X+B)/(C*X+D),X)=
  162. % LOG(C*X+D)*(LOG(B*C-D)-LOG C)/C -DILOG((C*X+B*C)/(B*C-D))/C;
  163. %% B=0;
  164. %FOR ALL X,A,C,D LET INT(LOG(A*X)/(C*X+D),X)=
  165. % LOG(C*X+D)*(LOG(-1)+LOG(A)+LOG(D)-LOG C)/C - DILOG(-C*X/D)/C;
  166. %% C=1;
  167. %FOR ALL X,A,B,D LET INT(LOG(A*X+B)/(X+D),X)=
  168. % LOG(X+D)*LOG(B-A*D)-DILOG((A*X+B)/(B-A*D));
  169. %% D=0;
  170. %FOR ALL X,A,B,C LET INT(LOG(A*X+B)/(C*X),X)=
  171. % LOG(C*X)*LOG(B)/C - DILOG((A*X+B)/B)/C;
  172. %% A=1, B=0;
  173. %FOR ALL X,C,D LET INT(LOG(X)/(C*X+D),X)=
  174. % LOG(C*X+D)*(LOG(-1)+LOG(D)-LOG(C))/C - DILOG(-C*X/D)/C;
  175. %% A=1, C=1;
  176. %FOR ALL X,B,D LET INT(LOG(X+B)/(X+D),X)=
  177. % LOG(X+D)*LOG(B-D) - DILOG((X+B)/(B-D));
  178. %% A=1, D=0;
  179. %FOR ALL X,B,C LET INT(LOG(X+B)/(C*X),X)=
  180. % LOG(C*X)*LOG(B)/C - DILOG((X+B)/B)/C;
  181. %% B=0, C=1;
  182. %FOR ALL X,A,D LET INT(LOG(A*X)/(X+D),X)=
  183. % LOG(X+D)*(LOG(-1)+LOG(A)+LOG(D)) - DILOG(-X/D);
  184. %% C=1, D=0;
  185. %FOR ALL X,A,B LET INT(LOG(A*X+B)/X,X)=
  186. % LOG(X+D)*(LOG(-1)+LOG(D)) - DILOG(-X/D);
  187. %% A=1, C=1, D=0;
  188. %FOR ALL X,B LET INT(LOG(X+B)/X,X)=
  189. % LOG(X)*LOG(B) - DILOG((X+B)/B);
  190. %% A=1, B=0, C=1;
  191. %FOR ALL X,D LET INT(LOG(X)/(X+D),X)=
  192. % LOG(X+D)*(LOG(-1)+LOG(D)) - DILOG(-X/D);
  193. %
  194. LISP;
  195. !*NOLNR:=NIL;
  196. MODULE CONTENTS;
  197. EXPORTS CONTENTS,CONTENTSMV,DFNUMR,DIFFLOGS,FACTORLISTLIST,MULTSQFREE,
  198. MULTUP,SQFREE,SQMERGE;
  199. IMPORTS INT!-FAC,FQUOTF,GCDF,INTERR,!*MULTF!*,PARTIALDIFF,QUOTF,ORDOP,
  200. ADDF,NEGF,DOMAINP,DIFFF,MKSP,NEGSQ,INVSQ,ADDSQ,MULTSQ,DIFFSQ;
  201. COMMENT we assume that no power substitution is necessary in
  202. this module;
  203. SYMBOLIC PROCEDURE CONTENTS(P,V);
  204. % FIND THE CONTENTS OF THE POLYNOMIAL P WRT VARIABLE V;
  205. % NOTE THAT V MAY NOT BE THE MAIN VARIABLE OF P;
  206. IF DOMAINP(P) THEN P
  207. ELSE IF V=MVAR P THEN CONTENTSMV(P,V,NIL)
  208. ELSE IF ORDOP(V,MVAR P) THEN P
  209. ELSE CONTENTSMV(MAKEMAINVAR(P,V),V,NIL);
  210. SYMBOLIC PROCEDURE CONTENTSMV(P,V,SOFAR);
  211. % FIND CONTENTS OF POLYNOMIAL P;
  212. % V IS MAIN VARIABLE OF P;
  213. % SOFAR IS PARTIAL RESULT;
  214. IF SOFAR=1 THEN 1
  215. ELSE IF DOMAINP P THEN GCDF(P,SOFAR)
  216. ELSE IF NOT V=MVAR P THEN GCDF(P,SOFAR)
  217. ELSE CONTENTSMV(RED P,V,GCDF(LC P,SOFAR));
  218. SYMBOLIC PROCEDURE MAKEMAINVAR(P,V);
  219. % BRING V UP TO BE THE MAIN VARIABLE IN POLYNOMIAL P;
  220. % NOTE THAT THE RECONSTRUCTED P MUST BE USED WITH CARE SINCE;
  221. % IT DOES NOT CONFORM TO THE NORMAL REDUCE ORDERING RULES;
  222. IF DOMAINP P THEN P
  223. ELSE IF V=MVAR P THEN P
  224. ELSE MERGEADD(MULCOEFFSBY(MAKEMAINVAR(LC P,V),LPOW P,V),
  225. MAKEMAINVAR(RED P,V),V);
  226. SYMBOLIC PROCEDURE MULCOEFFSBY(P,POW,V);
  227. % MULTIPLY EACH COEFFICIENT IN P BY THE STANDARD POWER POW;
  228. IF NULL P THEN NIL
  229. ELSE IF DOMAINP P OR NOT V=MVAR P THEN ((POW .* P) .+ NIL)
  230. ELSE (LPOW P .* ((POW .* LC P) .+ NIL)) .+ MULCOEFFSBY(RED P,POW,V);
  231. SYMBOLIC PROCEDURE MERGEADD(A,B,V);
  232. % ADD POLYNOMIALS A AND B GIVEN THAT THEY HAVE SAME MAIN VARIABLE V;
  233. IF DOMAINP A OR NOT V=MVAR A THEN
  234. IF DOMAINP B OR NOT V=MVAR B THEN ADDF(A,B)
  235. ELSE LT B .+ MERGEADD(A,RED B,V)
  236. ELSE IF DOMAINP B OR NOT V=MVAR B THEN
  237. LT A .+ MERGEADD(RED A,B,V)
  238. ELSE (LAMBDA XC;
  239. IF XC=0 THEN (LPOW A .* ADDF(LC A,LC B)) .+
  240. MERGEADD(RED A,RED B,V)
  241. ELSE IF XC>0 THEN LT A .+ MERGEADD(RED A,B,V)
  242. ELSE LT B .+ MERGEADD(A,RED B,V))
  243. (TDEG LT A-TDEG LT B);
  244. SYMBOLIC PROCEDURE SQFREE(P,VL);
  245. IF (NULL VL) OR (DOMAINP P) THEN
  246. <<CONTENT:=P; NIL>>
  247. ELSE BEGIN SCALAR W,V,DP,GG,PG,DPG,P1,W1;
  248. W:=CONTENTS(P,CAR VL); % CONTENT OF P ;
  249. P:=QUOTF(P,W); % MAKE P PRIMITIVE;
  250. W:=SQFREE(W,CDR VL); % PROCESS CONTENT BY RECURSION;
  251. IF P=1 THEN RETURN W;
  252. V:=CAR VL; % PICK OUT VARIABLE FROM LIST;
  253. WHILE NOT (P=1) DO <<
  254. DP:=PARTIALDIFF(P,V);
  255. GG:=GCDF(P,DP);
  256. PG:=QUOTF(P,GG);
  257. DPG:=NEGF PARTIALDIFF(PG,V);
  258. P1:=GCDF(PG,ADDF(QUOTF(DP,GG),DPG));
  259. W1:=P1.W1;
  260. P:=GG>>;
  261. RETURN SQMERGE(REVERSE W1,W,T)
  262. END;
  263. SYMBOLIC PROCEDURE SQMERGE(W1,W,SIMPLEW1);
  264. % W AND W1 ARE LISTS OF FACTORS OF EACH POWER. IF SIMPLEW1 IS TRUE
  265. % THEN W1 CONTAINS ONLY SINGLE FACTORS FOR EACH POWER. ;
  266. IF NULL W1 THEN W
  267. ELSE IF NULL W THEN IF CAR W1=1 THEN NIL.SQMERGE(CDR W1,W,SIMPLEW1)
  268. ELSE (IF SIMPLEW1 THEN LIST CAR W1 ELSE CAR W1).
  269. SQMERGE(CDR W1,W,SIMPLEW1)
  270. ELSE IF CAR W1=1 THEN (CAR W).SQMERGE(CDR W1,CDR W,SIMPLEW1) ELSE
  271. APPEND(IF SIMPLEW1 THEN LIST CAR W1 ELSE CAR W1,CAR W).
  272. SQMERGE(CDR W1,CDR W,SIMPLEW1);
  273. SYMBOLIC PROCEDURE MULTUP L;
  274. % L IS A LIST OF S.F.'S. RESULT IS S.Q. FOR PRODUCT OF ELEMENTS OF L;
  275. BEGIN SCALAR RES;
  276. RES:=1 ./ 1;
  277. WHILE NOT NULL L DO <<
  278. RES:=MULTSQ(RES,(CAR L) ./ 1);
  279. L:=CDR L >>;
  280. RETURN RES
  281. END;
  282. SYMBOLIC PROCEDURE DIFLIST(L,CL,X,RL);
  283. % DIFFERENTIATES L (LIST OF S.F.'S) WRT X TO PRODUCE THE SUM OF;
  284. % TERMS FOR THE DERIVATIVE OF NUMR OF 1ST PART OF ANSWER. CL IS;
  285. % COEFFICIENT LIST (S.F.'S) & RL IS LIST OF DERIVATIVES WE HAVE;
  286. % DEALT WITH SO FAR;
  287. % RESULT IS S.Q.;
  288. IF NULL L THEN NIL ./ 1
  289. ELSE BEGIN SCALAR TEMP;
  290. TEMP:=MULTSQ(MULTUP RL,MULTUP CDR L);
  291. TEMP:=MULTSQ(DIFFF(CAR L,X),TEMP);
  292. TEMP:=MULTSQ(TEMP,(CAR CL) ./ 1);
  293. RETURN ADDSQ(TEMP,DIFLIST(CDR L,CDR CL,X,(CAR L).RL))
  294. END;
  295. SYMBOLIC PROCEDURE MULTSQFREE W;
  296. % W IS LIST OF SQFREE FACTORS. RESULT IS PRODUCT OF EACH LIST IN W
  297. % TO GIVE ONE POLYNOMIAL FOR EACH SQFREE POWER;
  298. IF NULL W THEN NIL
  299. ELSE (!*Q2F MULTUP CAR W).MULTSQFREE CDR W;
  300. SYMBOLIC PROCEDURE L2LSF L;
  301. % L IS A LIST OF KERNELS. RESULT IS A LIST OF SAME MEMBERS AS S.F.'S;
  302. IF NULL L THEN NIL
  303. ELSE ((MKSP(CAR L,1) .* 1) .+ NIL).L2LSF CDR L;
  304. SYMBOLIC PROCEDURE DFNUMR(X,DL);
  305. % GIVES THE DERIVATIVE OF THE NUMR OF THE 1ST PART OF ANSWER.;
  306. % DL IS LIST OF ANY EXPONENTIAL OR 1+TAN**2 THAT OCCUR IN INTEGRAND;
  307. % DENR. THESE ARE DIVIDED OUT FROM RESULT BEFORE HANDING IT BACK.;
  308. % RESULT IS S.Q., READY FOR PRINTING;
  309. BEGIN SCALAR TEMP1,TEMP2,COEFLIST,QLIST,COUNT;
  310. IF NOT NULL SQFR THEN <<
  311. COUNT:=0;
  312. QLIST:=CDR SQFR;
  313. COEFLIST:=NIL;
  314. WHILE NOT NULL QLIST DO <<
  315. COUNT:=COUNT+1;
  316. COEFLIST:=COUNT.COEFLIST;
  317. QLIST:=CDR QLIST >>;
  318. COEFLIST:=REVERSE COEFLIST >>;
  319. TEMP1:=MULTSQ(DIFLIST(L2LSF ZLIST,L2LSF INDEXLIST,X,NIL),
  320. MULTUP SQFR);
  321. IF NOT NULL SQFR AND NOT NULL CDR SQFR THEN <<
  322. TEMP2:=MULTSQ(DIFLIST(CDR SQFR,COEFLIST,X,NIL),
  323. MULTUP L2LSF ZLIST);
  324. TEMP2:=MULTSQ(TEMP2,(CAR SQFR) ./ 1) >>
  325. ELSE TEMP2:=NIL ./ 1;
  326. TEMP1:=ADDSQ(TEMP1,NEGSQ TEMP2);
  327. TEMP2:=CDR TEMP1;
  328. TEMP1:=CAR TEMP1;
  329. QLIST:=NIL;
  330. WHILE NOT NULL DL DO <<
  331. IF NOT CAR DL MEMBER QLIST THEN QLIST:=(CAR DL).QLIST;
  332. DL:=CDR DL >>;
  333. WHILE NOT NULL QLIST DO <<
  334. TEMP1:=QUOTF(TEMP1,CAR QLIST);
  335. QLIST:=CDR QLIST >>;
  336. RETURN TEMP1 ./ TEMP2
  337. END;
  338. SYMBOLIC PROCEDURE DIFFLOGS(LL,DENM1,X);
  339. % LL IS LIST OF LOG TERMS (WITH COEFFTS), DEN IS COMMON DENOMINATOR;
  340. % OVER WHICH THEY ARE TO BE PUT. RESULT IS S.Q. FOR DERIVATIVE OF ALL;
  341. % THESE WRT X;
  342. IF NULL LL THEN NIL ./ 1
  343. ELSE BEGIN SCALAR TEMP,QU,CVAR,LOGORATAN,ARG;
  344. LOGORATAN:=CAAR LL;
  345. CVAR:=CADAR LL;
  346. ARG:=CDDAR LL;
  347. TEMP:=MULTSQ(CVAR ./ 1,DIFFSQ(ARG,X));
  348. IF LOGORATAN='IDEN THEN QU:=1 ./ 1
  349. ELSE IF LOGORATAN='LOG THEN QU:=ARG
  350. ELSE IF LOGORATAN='ATAN THEN QU:=ADDSQ(1 ./ 1,MULTSQ(ARG,ARG))
  351. ELSE INTERR "LOGORATAN=? IN DIFFLOGS";
  352. %NOTE CALL TO SPECIAL DIVISION ROUTINE;
  353. QU:=FQUOTF(!*F2POL !*MULTF!*(!*MULTF!*(DENM1,NUMR TEMP),
  354. DENR QU),NUMR QU);
  355. %*MUST* GO EXACTLY;
  356. TEMP:=MULTSQ(INVSQ (DENR TEMP ./ 1),QU);
  357. %RESULT OF FQUOTF IS A S.Q;
  358. RETURN SUBS2Q ADDSQ(TEMP,DIFFLOGS(CDR LL,DENM1,X))
  359. END;
  360. SYMBOLIC PROCEDURE FACTORLISTLIST (W,CLOGFLAG);
  361. % W IS LIST OF LISTS OF SQFREE FACTORS IN S.F. RESULT IS LIST OF LOG;
  362. % TERMS REQUIRED FOR INTEGRAL ANSWER. THE ARGUMENTS FOR EACH LOG FN;
  363. % ARE IN S.Q.;
  364. BEGIN SCALAR RES,X,Y;
  365. WHILE NOT NULL W DO <<
  366. X:=CAR W;
  367. WHILE NOT NULL X DO <<
  368. Y:=FACBYPP(CAR X,VARLIST);
  369. WHILE NOT NULL Y DO <<
  370. RES:=APPEND(INT!-FAC CAR Y,RES);
  371. Y:=CDR Y >>;
  372. X:=CDR X >>;
  373. W:=CDR W >>;
  374. RETURN RES
  375. END;
  376. SYMBOLIC PROCEDURE FACBYPP(P,VL);
  377. %USE CONTENTS/PRIMITIVE PARTS TO TRY TO FACTOR P;
  378. IF NULL VL THEN LIST P
  379. ELSE BEGIN SCALAR PRINCILAP!-PART,CO;
  380. CO:=CONTENTS(P,CAR VL);
  381. VL:=CDR VL;
  382. IF CO=1 THEN RETURN FACBYPP(P,VL); %THIS VAR NO HELP;
  383. PRINCILAP!-PART:=QUOTF(P,CO); %PRIMITIVE PART;
  384. IF PRINCILAP!-PART=1 THEN RETURN FACBYPP(P,VL); %AGAIN NO HELP;
  385. RETURN NCONC(FACBYPP(PRINCILAP!-PART,VL),FACBYPP(CO,VL))
  386. END;
  387. ENDMODULE;
  388. MODULE CSOLVE;
  389. EXPORTS BACKSUBST4CS,CREATECMAP,FINDPIVOT,PRINTSPREADC,PRINTVECSQ,
  390. SPREADC,SUBST4ELIMINATEDS;
  391. IMPORTS NTH,INTERR,!*MULTF!*,PRINTSF,PRINTSQ,QUOTF,PUTV,NEGF,INVSQ,
  392. NEGSQ,ADDSQ,MULTSQ,MKSP,ADDF,DOMAINP,PNTH;
  393. % routines to do with the C constants;
  394. SYMBOLIC PROCEDURE FINDPIVOT CVEC;
  395. % Finds first non-zero element in CVEC and returns its cell number.;
  396. % If no such element exists, result is nil.;
  397. BEGIN SCALAR I,X;
  398. I:=1;
  399. X:=GETV(CVEC,I);
  400. WHILE I<CCOUNT AND NULL X DO
  401. << I:=I+1;
  402. X:=GETV(CVEC,I) >>;
  403. IF NULL X THEN RETURN NIL;
  404. RETURN I
  405. END;
  406. SYMBOLIC PROCEDURE SUBST4ELIMINATEDCS(NEWEQN,SUBSTORDER,CEQNS);
  407. % Substitutes into NEWEQN for all the C's that have been eliminated so;
  408. % far. These are given by CEQNS. SUBSTORDER gives the order of;
  409. % substitution as well as the constant multipliers. Result is the;
  410. % transformed NEWEQN.;
  411. IF NULL SUBSTORDER THEN NEWEQN
  412. ELSE BEGIN SCALAR NXT,ROW,CVAR,TEMP;
  413. ROW:=CAR CEQNS;
  414. NXT:=CAR SUBSTORDER;
  415. IF NULL (CVAR:=GETV(NEWEQN,NXT)) THEN
  416. RETURN SUBST4ELIMINATEDCS(NEWEQN,CDR SUBSTORDER,CDR CEQNS);
  417. NXT:=GETV(ROW,NXT);
  418. FOR I:=0 : CCOUNT DO
  419. << TEMP:=!*MULTF!*(NXT,GETV(NEWEQN,I));
  420. TEMP:=ADDF(TEMP,NEGF !*MULTF!*(CVAR,GETV(ROW,I)));
  421. PUTV(NEWEQN,I,!*F2POL TEMP) >>;
  422. RETURN SUBST4ELIMINATEDCS(NEWEQN,CDR SUBSTORDER,CDR CEQNS)
  423. END;
  424. SYMBOLIC PROCEDURE BACKSUBST4CS(CS2SUBST,CS2SOLVE,CMATRIX);
  425. % Solves the C-eqns and sets vector CVAL to the C-constant values;
  426. % CMATRIX is a list of matrix rows for C-eqns after Gaussian ;
  427. % elimination has been performed. CS2SOLVE is a list of the remaining;
  428. % C's to evaluate and CS2SUBST are the C's we have evaluated already.;
  429. IF NULL CMATRIX THEN NIL
  430. ELSE BEGIN SCALAR EQNN,CVAR,ALREADY,SUBSTLIST,TEMP,TEMP2;
  431. EQNN:=CAR CMATRIX;
  432. CVAR:=CAR CS2SOLVE;
  433. ALREADY:=NIL ./ 1; % The S.Q. nil ;
  434. SUBSTLIST:=CS2SUBST;
  435. % NOW SUBSTITUTE FOR PREVIOUSLY EVALUATED C'S:;
  436. WHILE NOT NULL SUBSTLIST DO
  437. << TEMP:=CAR SUBSTLIST;
  438. IF NOT NULL GETV(EQNN,TEMP) THEN
  439. ALREADY:=ADDSQ(ALREADY,MULTSQ(GETV(EQNN,TEMP) ./ 1,
  440. GETV(CVAL,TEMP)));
  441. SUBSTLIST:=CDR SUBSTLIST >>;
  442. % NOW SOLVE FOR THE C GIVEN BY CVAR (ANY REMAINING C'S ASSUMED ZERO);
  443. TEMP:=NEGSQ ADDSQ(GETV(EQNN,0) ./ 1,ALREADY);
  444. IF NOT NULL (TEMP2:=QUOTF(NUMR TEMP,GETV(EQNN,CVAR))) THEN
  445. TEMP:=TEMP2 ./ DENR TEMP
  446. ELSE TEMP:=MULTSQ(TEMP,INVSQ(GETV(EQNN,CVAR) ./ 1));
  447. IF NOT NULL NUMR TEMP THEN PUTV(CVAL,CVAR,
  448. RESIMP ROOTEXTRACTSQ SUBS2Q TEMP);
  449. BACKSUBST4CS(REVERSEWOC(CVAR . REVERSEWOC CS2SUBST),
  450. CDR CS2SOLVE,CDR CMATRIX)
  451. END;
  452. %**********************************************************************;
  453. % Routines to deal with linear equations for the constants C;
  454. %**********************************************************************;
  455. SYMBOLIC PROCEDURE CREATECMAP;
  456. %Sets LOGLIST to list of things of form (LOG C-constant f), where f is;
  457. % function linear in one of the z-variables and C-constant is in S.F.;
  458. % When creating these C-constant names, the CMAP is also set up and ;
  459. % returned as the result.;
  460. BEGIN SCALAR I,L,C;
  461. L:=LOGLIST;
  462. I:=1;
  463. WHILE NOT NULL L DO <<
  464. C:=(GENSYM1('C) . I) . C;
  465. I:=I+1;
  466. RPLACD(CAR L,((MKSP(CAAR C,1) .* 1) .+ NIL) . CDAR L);
  467. L:=CDR L >>;
  468. IF !*TRINT THEN PRINTC ("Constants Map" . C);
  469. RETURN C
  470. END;
  471. SYMBOLIC PROCEDURE SPREADC(EQNN,CVEC1,W);
  472. %SETS A VECTOR 'CVEC1' TO COEFFICIENTS OF C<I> IN EQNN;
  473. IF DOMAINP EQNN THEN PUTV(CVEC1,0,ADDF(GETV(CVEC1,0),
  474. !*F2POL !*MULTF!*(EQNN,W)))
  475. ELSE BEGIN SCALAR MV,T1,T2;
  476. SPREADC(RED EQNN,CVEC1,W);
  477. MV:=MVAR EQNN;
  478. T1:=ASSOC(MV,CMAP); %TESTS IF IT IS A C VAR;
  479. IF NOT NULL T1 THEN RETURN <<
  480. T1:=CDR T1; %LOC IN VECTOR FOR THIS C;
  481. IF NOT (TDEG LT EQNN=1) THEN INTERR "NOT LINEAR IN C EQN";
  482. T2:=ADDF(GETV(CVEC1,T1),!*MULTF!*(W,LC EQNN));
  483. PUTV(CVEC1,T1,!*F2POL T2) >>;
  484. T1:=((LPOW EQNN) .* 1) .+ NIL; %THIS MAIN VAR AS SF;
  485. SPREADC(LC EQNN,CVEC1,!*F2POL !*MULTF!*(W,T1))
  486. END;
  487. SYMBOLIC PROCEDURE PRINTSPREADC CVEC1;
  488. BEGIN
  489. FOR I:=0 : CCOUNT DO <<
  490. PRIN2 I;
  491. PRINTC ":";
  492. PRINTSF(GETV(CVEC1,I)) >>;
  493. PRINTC "END OF PRINTSPREADC OUTPUT"
  494. END;
  495. %SYMBOLIC PROCEDURE PRINTVECSQ CVEC;
  496. %% PRINT CONTENTS OF CVEC WHICH CONTAINS S.Q.'S (NOT S.F.'S);
  497. %% STARTS FROM CELL 1 NOT 0 AS ABOVE ROUTINE (PRINTSPREADC);
  498. % BEGIN
  499. % FOR I:=1 : CCOUNT DO <<
  500. % PRIN2 I;
  501. % PRINTC ":";
  502. % IF NULL GETV(CVEC,I) THEN PRINTC "0"
  503. % ELSE PRINTSQ(GETV(CVEC,I)) >>;
  504. % PRINTC "END OF PRINTVECSQ OUTPUT"
  505. % END;
  506. ENDMODULE;
  507. MODULE CUBEROOT;
  508. EXPORTS CUBEROOTDF;
  509. IMPORTS CONTENTSMV,GCDF,!*MULTF!*,NROOTN,PARTIALDIFF,PRINTDF,QUOTF,VP2,
  510. MKSP,MK!*SQ,DOMAINP;
  511. %CUBE-ROOT OF STANDARD FORMS;
  512. SYMBOLIC PROCEDURE CUBEROOTSQ A;
  513. CUBEROOTF NUMR A ./ CUBEROOTF DENR A;
  514. SYMBOLIC PROCEDURE CUBEROOTF P;
  515. BEGIN SCALAR IP,QP;
  516. IF NULL P THEN RETURN NIL;
  517. IP:=CUBEROOTF1 P;
  518. QP:=CDR IP;
  519. IP:=CAR IP; %RESPECTABLE AND NASTY PARTS OF THE CUBEROOT;
  520. IF ONEP QP THEN RETURN IP; %EXACT ROOT FOUND;
  521. QP:=LIST('EXPT,PREPF QP,'(QUOTIENT 1 3));
  522. CUBEROOTFLAG:=T; %SYMBOLIC CUBE-ROOT INTRODUCED;
  523. QP:=(MKSP(QP,1).* 1) .+ NIL;
  524. RETURN !*F2POL !*MULTF!*(IP,QP)
  525. END;
  526. SYMBOLIC PROCEDURE CUBEROOTF1 P;
  527. %RETURNS A . B WITH P=A**2*B;
  528. %does this need power reduction??;
  529. IF DOMAINP P THEN NROOTN(P,3)
  530. ELSE BEGIN SCALAR CO,PPP,G,PG;
  531. CO:=CONTENTSMV(P,MVAR P,NIL); %CONTENTS OF P;
  532. PPP:=QUOTF(P,CO); %PRIMITIVE PART;
  533. %NOW CONSIDER PPP=P1*P2**2*P3**3*P4**4*...;
  534. CO:=CUBEROOTF1(CO); %PROCESS CONTENTS VIA RECURSION;
  535. G:=GCDF(PPP,PARTIALDIFF(PPP,MVAR PPP));
  536. %G=P2*P3**2*P4**3*...;
  537. IF NOT DOMAINP G THEN <<
  538. PG:=QUOTF(PPP,G);
  539. %PG=P1*P2*P3*P4*...;
  540. G:=GCDF(G,PARTIALDIFF(G,MVAR G));
  541. % G=G3*G4**2*G5**3*...;
  542. G:=GCDF(G,PG)>>; %A TRIPLE FACTOR OF PPP;
  543. IF DOMAINP G THEN PG:=1 . PPP
  544. ELSE <<
  545. PG:=QUOTF(PPP,!*MULTF!*(G,!*MULTF!*(G,G))); %WHAT'S LEFT;
  546. PG:=CUBEROOTF1(!*F2POL PG); %SPLIT THAT UP;
  547. RPLACA(PG,!*MULTF!*(CAR PG,G))>>;
  548. %PUT IN THE THING FOUND HERE;
  549. RPLACA(PG,!*F2POL !*MULTF!*(CAR PG,CAR CO));
  550. RPLACD(PG,!*F2POL !*MULTF!*(CDR PG,CDR CO));
  551. RETURN PG
  552. END;
  553. ENDMODULE;
  554. MODULE DEPEND;
  555. EXPORTS DEPENDSPL,DEPENDSP,INVOLVESQ,INVOLVSF;
  556. IMPORTS TAYLORP,DOMAINP;
  557. SYMBOLIC PROCEDURE DEPENDSP(X,V);
  558. IF NULL V THEN T
  559. ELSE IF ATOM X THEN IF X EQ V THEN X ELSE NIL
  560. ELSE IF CAR X = '!*SQ
  561. THEN INVOLVESQ(CADR X,V)
  562. ELSE IF TAYLORP X
  563. THEN IF V EQ TAYLORVARIABLE THEN TAYLORVARIABLE ELSE NIL
  564. ELSE BEGIN
  565. SCALAR W;
  566. IF X=V THEN RETURN V;
  567. % CHECK IF A PREFIX FORM EXPRESSION DEPENDS ON THE VARIABLE V;
  568. % NOTE THAT THIS ASSUMES THE FORM X IS IN NORMAL PREFIX NOTATION;
  569. W := X; % preserve the dependency;
  570. X:=CDR X; % READY TO RECURSIVELY CHECK ARGUMENTS;
  571. SCAN: IF NULL X THEN RETURN NIL; % NO DEPENDENCY FOUND;
  572. IF DEPENDSP(CAR X,V) THEN RETURN W;
  573. X:=CDR X;
  574. GO TO SCAN
  575. END;
  576. SYMBOLIC PROCEDURE TAYLORP U; NIL; %dummy for now;
  577. SYMBOLIC PROCEDURE INVOLVESQ(SQ,TERM);
  578. INVOLVESF(NUMR SQ,TERM) OR INVOLVESF(DENR SQ,TERM);
  579. SYMBOLIC PROCEDURE INVOLVESF(SF,TERM);
  580. IF DOMAINP SF OR NULL SF
  581. THEN NIL
  582. ELSE IF DEPENDSP(MVAR SF,TERM)
  583. THEN T
  584. ELSE INVOLVESF(LC SF,TERM) OR
  585. INVOLVESF(RED SF,TERM);
  586. ENDMODULE;
  587. MODULE DF2Q;
  588. EXPORTS DF2Q;
  589. IMPORTS ADDF,GCDF,MKSP,!*MULTF!*,QUOTF;
  590. COMMENT This module converts distributed forms to standard forms.
  591. We assume that results already have reduced powers, so
  592. that no power substitution is necessary;
  593. %TRIAL REPLACEMENT FOR DF2Q;
  594. SYMBOLIC PROCEDURE DF2Q P;
  595. % Converts distributed form P to standard quotient;
  596. BEGIN SCALAR N,D,GG,W;
  597. IF NULL P THEN RETURN NIL ./ 1;
  598. D:=DENR LC P;
  599. W:=RED P;
  600. WHILE NOT NULL W DO <<
  601. GG:=GCDF(D,DENR LC W); %GET DENOMINATOR OF ANSWER...;
  602. D:=!*MULTF!*(D,QUOTF(DENR LC W,GG));
  603. %..AS LCM OF DENOMS IN INPUT;
  604. W:=RED W >>;
  605. N:=NIL; %PLACE TO BUILD NUMERATOR OF ANSWER;
  606. WHILE NOT NULL P DO <<
  607. N:=ADDF(N,!*MULTF!*(XL2F(LPOW P,ZLIST,INDEXLIST),
  608. !*MULTF!*(NUMR LC P,QUOTF(D,DENR LC P))));
  609. P:=RED P >>;
  610. RETURN N ./ D
  611. END;
  612. SYMBOLIC PROCEDURE XL2F(L,Z,IL);
  613. % L is an exponent list from a D.F., Z is the Z-list,
  614. % IL is the list of indices.
  615. % Value is L converted to standard form. ;
  616. IF NULL Z THEN 1
  617. ELSE IF CAR L=0 THEN XL2F(CDR L,CDR Z,CDR IL)
  618. ELSE IF NOT ATOM CAR L THEN
  619. BEGIN SCALAR TEMP;
  620. IF CAAR L=0 THEN TEMP:= CAR IL
  621. ELSE TEMP:=LIST('PLUS,CAR IL,CAAR L);
  622. TEMP:=MKSP(LIST('EXPT,CAR Z,TEMP),1);
  623. RETURN !*MULTF!*(((TEMP .* 1) .+ NIL),
  624. XL2F(CDR L,CDR Z,CDR IL))
  625. END
  626. % ELSE IF MINUSP CAR L THEN ;
  627. % MULTSQ(INVSQ (((MKSP(CAR Z,-CAR L) .* 1) .+ NIL)), ;
  628. % XL2F(CDR L,CDR Z,CDR IL)) ;
  629. ELSE !*MULTF!*((MKSP(CAR Z,CAR L) .* 1) .+ NIL,
  630. XL2F(CDR L,CDR Z,CDR IL));
  631. ENDMODULE;
  632. MODULE DISTRIB;
  633. EXPORTS DFPRINTFORM,MULTBYARBPOWERS,NEGDF,QUOTDFCONST,SUB1IND,VP1,
  634. VP2,PLUSDF,MULTDF,MULTDFCONST,ORDDF;
  635. IMPORTS INTERR,ADDSQ,NEGSQ,EXPTSQ,SIMP,DOMAINP,MK!*SQ,ADDF,
  636. MULTSQ,INVSQ,MINUSP,MKSP,SUB1;
  637. %***********************************************************************
  638. % ROUTINES FOR MANIPULATING DISTRIBUTED FORMS.
  639. % NOTE:
  640. % THE EXPRESSIONS LT,RED,LC,LPOW HAVE BEEN USED ON DISTRIBUTED
  641. % FORMS AS THE LATTER'S STRUCTURE IS SUFFICIENTLY SIMILAR TO
  642. % S.F.'S. HOWEVER LC DF IS A S.Q. NOT A S.F. AND LPOW DF IS A
  643. % LIST OF THE EXPONENTS OF THE VARIABLES. THIS ALSO MAKES
  644. % LT DF DIFFERENT. RED DF IS D.F. AS EXPECTED.
  645. %**********************************************************************;
  646. SYMBOLIC PROCEDURE PLUSDF(U,V);
  647. % U and V are D.F.'s. Value is D.F. for U+V;
  648. IF NULL U THEN V
  649. ELSE IF NULL V THEN U
  650. ELSE IF LPOW U=LPOW V THEN
  651. (LAMBDA(X,Y); IF NULL NUMR X THEN Y ELSE (LPOW U .* X) .+ Y)
  652. (ADDSQ(LC U,LC V),PLUSDF(RED U,RED V))
  653. ELSE IF ORDDF(LPOW U,LPOW V) THEN LT U .+ PLUSDF(RED U,V)
  654. ELSE (LT V) .+ PLUSDF(U,RED V);
  655. SYMBOLIC PROCEDURE ORDDF(U,V);
  656. % U and V are the LPOW of a D.F. - i.e. the list of exponents ;
  657. % Value is true if LPOW U '>' LPOW V and false otherwise ;
  658. IF NULL U THEN IF NULL V THEN INTERR "ORDDF = CASE"
  659. ELSE INTERR "ORDDF V LONGER THAN U"
  660. ELSE IF NULL V THEN INTERR "ORDDF U LONGER THAN V"
  661. ELSE IF EXPTCOMPARE(CAR U,CAR V) THEN T
  662. ELSE IF EXPTCOMPARE(CAR V,CAR U) THEN NIL
  663. ELSE ORDDF(CDR U,CDR V);
  664. SYMBOLIC PROCEDURE EXPTCOMPARE(X,Y);
  665. IF ATOM X THEN IF ATOM Y THEN X>Y ELSE NIL
  666. ELSE IF ATOM Y THEN T
  667. ELSE CAR X > CAR Y;
  668. SYMBOLIC PROCEDURE NEGDF U;
  669. IF NULL U THEN NIL
  670. ELSE (LPOW U .* NEGSQ LC U) .+ NEGDF RED U;
  671. SYMBOLIC PROCEDURE MULTDF(U,V);
  672. % U and V are D.F.'s. Value is D.F. for U*V;
  673. % reduces squares of square-roots as it goes;
  674. IF NULL U OR NULL V THEN NIL
  675. ELSE BEGIN SCALAR Y;
  676. %use (a+b)*(c+d) = (a*c) + a*(c+d) + b*(c+d);
  677. Y:=MULTERM(LT U,LT V); %leading terms;
  678. Y:=PLUSDF(Y,MULTDF(RED U,V));
  679. Y:=PLUSDF(Y,MULTDF((LT U) .+ NIL,RED V));
  680. RETURN Y
  681. END;
  682. SYMBOLIC PROCEDURE MULTERM(U,V);
  683. %multiply two terms to give a D.F.;
  684. BEGIN SCALAR COEF;
  685. COEF:= SUBS2Q MULTSQ(CDR U,CDR V); %coefficient part;
  686. RETURN MULTDFCONST(COEF,MULPOWER(CAR U,CAR V))
  687. END;
  688. SYMBOLIC PROCEDURE MULPOWER(U,V);
  689. % u and v are exponent lists. multiply corresponding forms;
  690. BEGIN SCALAR R,S;
  691. R:=ADDEXPTSDF(U,V);
  692. IF NOT NULL SQRTLIST THEN S:=REDUCEROOTS(R,ZLIST);
  693. R:=(R .* (1 ./ 1)) .+ NIL;
  694. IF NOT (S=NIL) THEN R:=MULTDF(R,S);
  695. RETURN R
  696. END;
  697. SYMBOLIC PROCEDURE REDUCEROOTS(R,ZL);
  698. BEGIN SCALAR S;
  699. WHILE NOT NULL R DO <<
  700. IF EQCAR(CAR ZL,'SQRT) THEN
  701. S:=TRYREDUCTION(R,CAR ZL,S);
  702. R:=CDR R; ZL:=CDR ZL >>;
  703. RETURN S
  704. END;
  705. SYMBOLIC PROCEDURE TRYREDUCTION(R,VAR,S);
  706. BEGIN SCALAR X;
  707. X:=CAR R; %CURRENT EXPONENT;
  708. IF NOT ATOM X THEN << R:=X; X:=CAR R >>; %NUMERIC PART;
  709. IF (X=0) OR (X=1) THEN RETURN S; %NO REDUCTION POSSIBLE;
  710. X:=DIVIDE(X,2);
  711. RPLACA(R,CDR X); %REDUCE EXPONENT AS REDORDED;
  712. X:=CAR X;
  713. VAR:=SIMP CADR VAR; %SQRT ARG AS A S Q;
  714. VAR:=EXPTSQ(VAR,X);
  715. X:=MULTDFCONST(1 ./ DENR VAR,F2DF NUMR VAR); %DISTRIBUTE;
  716. IF S=NIL THEN S:=X
  717. ELSE S:=MULTDF(S,X);
  718. RETURN S
  719. END;
  720. SYMBOLIC PROCEDURE ADDEXPTSDF(X,Y);
  721. % X and Y are LPOW's of D.F. Value is list of sum of exponents;
  722. IF NULL X THEN IF NULL Y THEN NIL ELSE INTERR "X TOO LONG"
  723. ELSE IF NULL Y THEN INTERR "Y TOO LONG"
  724. ELSE EXPTPLUS(CAR X,CAR Y).ADDEXPTSDF(CDR X,CDR Y);
  725. SYMBOLIC PROCEDURE EXPTPLUS(X,Y);
  726. IF ATOM X THEN IF ATOM Y THEN X+Y ELSE LIST (X+CAR Y)
  727. ELSE IF ATOM Y THEN LIST (CAR X +Y)
  728. ELSE INTERR "BAD EXPONENT SUM";
  729. SYMBOLIC PROCEDURE MULTDFCONST(X,U);
  730. % X is S.Q. not involving Z variables of D.F. U. Value is D.F.;
  731. % for X*U;
  732. IF (NULL U) OR (NULL NUMR X) THEN NIL
  733. ELSE LPOW U .* SUBS2Q MULTSQ(X,LC U) .+ MULTDFCONST(X,RED U);
  734. SYMBOLIC PROCEDURE F2DF P;
  735. % P is standard form. Value is P in D.F.;
  736. IF DOMAINP P THEN DFCONST(P ./ 1)
  737. ELSE IF MVAR P MEMBER ZLIST THEN
  738. PLUSDF(MULTDF(VP2DF(MVAR P,TDEG LT P,ZLIST),F2DF LC P),
  739. F2DF RED P)
  740. ELSE PLUSDF(MULTDFCONST(((LPOW P .* 1) .+ NIL) ./ 1,F2DF LC P),
  741. F2DF RED P);
  742. SYMBOLIC PROCEDURE VP1(VAR,DEGG,Z);
  743. % Takes VAR and finds it in Z (=list), raises it to power DEGG and puts;
  744. % the result in exponent list form for use in a distributed form.;
  745. IF NULL Z THEN INTERR "VAR NOT IN Z-LIST AFTER ALL"
  746. ELSE IF VAR=CAR Z THEN DEGG.VP2 CDR Z
  747. ELSE 0 . VP1(VAR,DEGG,CDR Z);
  748. SYMBOLIC PROCEDURE VP2 Z;
  749. % Makes exponent list of zeroes;
  750. IF NULL Z THEN NIL
  751. ELSE 0 . VP2 CDR Z;
  752. SYMBOLIC PROCEDURE VP2DF(VAR,EXPRN,Z);
  753. % Makes VAR**EXPRN into exponent list and then converts the resulting
  754. % power into a distributed form.
  755. % special care with square-roots;
  756. IF EQCAR(VAR,'SQRT) AND EXPRN>1 THEN
  757. MULPOWER(VP1(VAR,EXPRN,Z),VP2 Z)
  758. ELSE (VP1(VAR,EXPRN,Z) .* (1 ./ 1)) .+ NIL;
  759. SYMBOLIC PROCEDURE DFCONST Q;
  760. % Makes a distributed form from standard quotient constant Q;
  761. IF NUMR Q=NIL THEN NIL
  762. ELSE ((VP2 ZLIST) .* Q) .+ NIL;
  763. %DF2Q MOVED TO A SECTION OF ITS OWN;
  764. SYMBOLIC PROCEDURE DF2PRINTFORM P;
  765. %CONVERT TO A STANDARD FORM GOOD ENOUGH FOR PRINTING;
  766. IF NULL P THEN NIL
  767. ELSE BEGIN
  768. SCALAR MV,CO;
  769. MV:=XL2Q(LPOW P,ZLIST,INDEXLIST);
  770. IF MV=(1 ./ 1) THEN <<
  771. CO:=LC P;
  772. IF DENR CO=1 THEN RETURN ADDF(NUMR CO,
  773. DF2PRINTFORM RED P);
  774. CO:=MKSP(MK!*SQ CO,1);
  775. RETURN (CO .* 1) .+ DF2PRINTFORM RED P >>;
  776. CO:=LC P;
  777. IF NOT (DENR CO=1) THEN MV:=MULTSQ(MV,1 ./ DENR CO);
  778. MV:=MKSP(MK!*SQ MV,1) .* NUMR CO;
  779. RETURN MV .+ DF2PRINTFORM RED P
  780. END;
  781. SYMBOLIC PROCEDURE XL2Q(L,Z,IL);
  782. % L is an exponent list from a D.F., Z is the Z-list,
  783. % IL is the list of indices.
  784. % Value is L converted to standard quotient. ;
  785. IF NULL Z THEN 1 ./ 1
  786. ELSE IF CAR L=0 THEN XL2Q(CDR L,CDR Z,CDR IL)
  787. ELSE IF NOT ATOM CAR L THEN
  788. BEGIN SCALAR TEMP;
  789. IF CAAR L=0 THEN TEMP:= CAR IL
  790. ELSE TEMP:=LIST('PLUS,CAR IL,CAAR L);
  791. TEMP:=MKSP(LIST('EXPT,CAR Z,TEMP),1);
  792. RETURN MULTSQ(((TEMP .* 1) .+ NIL) ./ 1,
  793. XL2Q(CDR L,CDR Z,CDR IL))
  794. END
  795. ELSE IF MINUSP CAR L THEN
  796. MULTSQ(INVSQ (((MKSP(CAR Z,-CAR L) .* 1) .+ NIL) ./ 1),
  797. XL2Q(CDR L,CDR Z,CDR IL))
  798. ELSE MULTSQ(((MKSP(CAR Z,CAR L) .* 1) .+ NIL) ./ 1,
  799. XL2Q(CDR L,CDR Z,CDR IL));
  800. SYMBOLIC PROCEDURE MULTBYARBPOWERS U;
  801. % Multiplies the ordinary D.F., U, by arbitrary powers
  802. % of the z-variables;
  803. % i-1 j-1 k-1
  804. % i.e. x z z ... so result is D.F. with the exponent list
  805. % 1 2
  806. % appropriately altered to contain list elements instead of numeric
  807. % ones;
  808. IF NULL U THEN NIL
  809. ELSE ((ADDARBEXPTSDF LPOW U) .* LC U) .+ MULTBYARBPOWERS RED U;
  810. SYMBOLIC PROCEDURE ADDARBEXPTSDF X;
  811. % Adds the arbitrary powers to powers in exponent list, X, to produce
  812. % new exponent list. e.g. 3 -> (2) to represent x**3 now becoming:
  813. % 3 i-1 i+2
  814. % x * x = x . ;
  815. IF NULL X THEN NIL
  816. ELSE LIST EXPTPLUS(CAR X,-1) . ADDARBEXPTSDF CDR X;
  817. ENDMODULE;
  818. MODULE DIVIDE;
  819. EXPORTS FQUOTF,TESTDIVDF,DFQUOTDF;
  820. IMPORTS DF2Q,F2DF,GCDF,INTERR,MULTDF,NEGDF,PLUSDF,PRINTDF,PRINTSF,
  821. QUOTF,MULTSQ,INVSQ,NEGSQ;
  822. %EXACT DIVISION OF STANDARD FORMS TO GIVE A STANDARD QUOTIENT;
  823. %INTENDED FOR DIVIDING OUT KNOWN FACTORS AS PRODUCED BY THE;
  824. %INTEGRATION PROGRAM. HORRIBLE AND SLOW, I EXPECT!!;
  825. SYMBOLIC PROCEDURE DFQUOTDF(A,B);
  826. BEGIN SCALAR RESIDUE;
  827. IF (!*TRINT OR !*TRDIV) THEN <<
  828. PRINTC "DFQUOTDF CALLED ON ";
  829. PRINTDF A; PRINTDF B>>;
  830. A:=DFQUOTDF1(A,B);
  831. IF (!*TRINT OR !*TRDIV) THEN << PRINTC "QUOTIENT GIVEN AS ";
  832. PRINTDF A >>;
  833. IF NOT NULL RESIDUE THEN BEGIN
  834. SCALAR GRES,W;
  835. IF !*TRINT OR !*TRDIV THEN <<
  836. PRINTC "RESIDUE IN DFQUOTDF =";
  837. PRINTDF RESIDUE;
  838. PRINTC "WHICH SHOULD BE ZERO";
  839. W:=RESIDUE;
  840. GRES:=NUMR LC W; W:=RED W;
  841. WHILE NOT NULL W DO <<
  842. GRES:=GCDF(GRES,NUMR LC W);
  843. W:=RED W >>;
  844. PRINTC "I.E. THE FOLLOWING VANISHES";
  845. PRINTSF GRES>>;
  846. INTERR "NON-EXACT DIVISION DUE TO A LOG TERM"
  847. END;
  848. RETURN A
  849. END;
  850. SYMBOLIC PROCEDURE FQUOTF(A,B);
  851. % INPUT: A AND B STANDARD QUOTIENTS WITH (A/B) AN EXACT;
  852. % DIVISION WITH RESPECT TO THE VARIABLES IN ZLIST, ;
  853. % BUT NOT NECESSARILY OBVIOUSLY SO. THE 'NON-OBVIOUS' PROBLEMS;
  854. % WILL BE BECAUSE OF (E.G.) SQUARE-ROOT SYMBOLS IN B;
  855. % OUTPUT: STANDARD QUOTIENT FOR (A/B);
  856. % (PRINTS MESSAGE IF REMAINDER IS NOT 'CLEARLY' ZERO;
  857. % A MUST NOT BE ZERO;
  858. BEGIN SCALAR T1;
  859. IF NULL A THEN INTERR "A=0 IN FQUOTF";
  860. T1:=QUOTF(A,B); %TRY IT THE EASY WAY;
  861. IF NOT NULL T1 THEN RETURN T1 ./ 1; %OK;
  862. RETURN DF2Q DFQUOTDF(F2DF A,F2DF B)
  863. END;
  864. SYMBOLIC PROCEDURE DFQUOTDF1(A,B);
  865. BEGIN SCALAR Q;
  866. IF NULL B THEN INTERR "ATTEMPT TO DIVIDE BY ZERO";
  867. Q:=SQRTLIST; %REMOVE SQRTS FROM DENOMINATOR, MAYBE;
  868. WHILE NOT NULL Q DO BEGIN
  869. SCALAR CONJ;
  870. CONJ:=CONJSQRT(B,CAR Q); %CONJUGATE WRT GIVEN SQRT;
  871. IF NOT (B=CONJ) THEN <<
  872. A:=MULTDF(A,CONJ);
  873. B:=MULTDF(B,CONJ) >>;
  874. Q:=CDR Q END;
  875. Q:=DFQUOTDF2(A,B);
  876. RESIDUE:=REVERSEWOC RESIDUE;
  877. RETURN Q
  878. END;
  879. SYMBOLIC PROCEDURE DFQUOTDF2(A,B);
  880. %AS ABOVE BUT A AND B ARE DISTRIBUTED FORMS, AS IS THE RESULT;
  881. IF NULL A THEN NIL
  882. ELSE BEGIN SCALAR XD,LCD;
  883. XD:=XPDIFF(LPOW A,LPOW B);
  884. IF XD='FAILED THEN <<
  885. XD:=LT A; A:=RED A;
  886. RESIDUE:=XD .+ RESIDUE;
  887. RETURN DFQUOTDF2(A,B) >>;
  888. LCD:=SUBS2Q MULTSQ(LC A,INVSQ LC B);
  889. IF NULL NUMR LCD THEN RETURN DFQUOTDF2(RED A,B);
  890. LCD := XD .* LCD;
  891. XD:=PLUSDF(A,MULTDF(NEGDF (LCD .+ NIL),B));
  892. IF XD AND (LPOW XD = LPOW A
  893. OR XPDIFF(LPOW XD,LPOW B) = 'FAILED)
  894. THEN <<IF !*TRINT OR !*TRDIV
  895. THEN <<PRINTC "DFQUOTDF TROUBLE:"; PRINTDF XD>>;
  896. XD := ROOTEXTRACTDF XD;
  897. IF !*TRINT OR !*TRDIV THEN PRINTDF XD>>;
  898. RETURN LCD .+ DFQUOTDF2(XD,B)
  899. END;
  900. SYMBOLIC PROCEDURE ROOTEXTRACTDF U;
  901. IF NULL U THEN NIL
  902. ELSE BEGIN SCALAR V;
  903. V := RESIMP ROOTEXTRACTSQ LC U;
  904. RETURN IF NULL NUMR V THEN ROOTEXTRACTDF RED U
  905. ELSE (LPOW U .* V) .+ ROOTEXTRACTDF RED U
  906. END;
  907. SYMBOLIC PROCEDURE ROOTEXTRACTSQ U;
  908. IF NULL NUMR U THEN U
  909. ELSE ROOTEXTRACTF NUMR U ./ ROOTEXTRACTF DENR U;
  910. SYMBOLIC PROCEDURE ROOTEXTRACTF V;
  911. IF DOMAINP V THEN V
  912. ELSE BEGIN SCALAR U,R,C,X,P;
  913. U := MVAR V; P := LDEG V;
  914. R := ROOTEXTRACTF RED V;
  915. C := ROOTEXTRACTF LC V;
  916. IF NULL C THEN RETURN R
  917. ELSE IF ATOM U THEN RETURN (LPOW V .* C) .+ R
  918. ELSE IF CAR U EQ 'SQRT
  919. OR CAR U EQ 'EXPT AND EQCAR(CADDR U,'QUOTIENT)
  920. AND CAR CDADDR U = 1 AND NUMBERP CADR CDADDR U
  921. THEN <<P := DIVIDE(P,IF CAR U EQ 'SQRT THEN 2
  922. ELSE CADR CDADDR U);
  923. IF CAR P = 0
  924. THEN RETURN IF NULL C THEN R ELSE (LPOW V .* C) .+ R
  925. ELSE IF NUMBERP CADR U
  926. THEN <<C := MULTD(CADR U ** CAR P,C); P := CDR P>>
  927. ELSE <<X := SIMPEXPT LIST(CADR U,CAR P);
  928. IF DENR X = 1
  929. THEN <<C := MULTF(NUMR X,C); P := CDR P>>>>>>;
  930. RETURN IF P=0 THEN ADDF(C,R)
  931. ELSE IF NULL C THEN R
  932. ELSE ((U TO P) .* C) .+ R
  933. END;
  934. PUT('DF,'SIMPFN,'SIMPDF!*);
  935. SYMBOLIC PROCEDURE SIMPDF!* U;
  936. BEGIN SCALAR V,V1;
  937. V:=SIMPDF U;
  938. V1:=ROOTEXTRACTSQ V;
  939. IF NOT(V1=V) THEN RETURN RESIMP V1
  940. ELSE RETURN V
  941. END;
  942. SYMBOLIC PROCEDURE XPDIFF(A,B);
  943. %RESULT IS LIST A-B, OR 'FAILED' IF A MEMBER OF THIS WOULD BE NEGATIVE;
  944. IF NULL A THEN IF NULL B THEN NIL
  945. ELSE INTERR "B TOO LONG IN XPDIFF"
  946. ELSE IF NULL B THEN INTERR "A TOO LONG IN XPDIFF"
  947. ELSE IF CAR B>CAR A THEN 'FAILED
  948. ELSE (LAMBDA R;
  949. IF R='FAILED THEN 'FAILED
  950. ELSE (CAR A-CAR B) . R) (XPDIFF(CDR A,CDR B));
  951. SYMBOLIC PROCEDURE CONJSQRT(B,VAR);
  952. %SUBST(VAR=-VAR,B);
  953. IF NULL B THEN NIL
  954. ELSE CONJTERM(LPOW B,LC B,VAR) .+ CONJSQRT(RED B,VAR);
  955. SYMBOLIC PROCEDURE CONJTERM(XL,COEF,VAR);
  956. %DITTO BUT WORKING ON A TERM;
  957. IF INVOLVESP(XL,VAR,ZLIST) THEN XL .* NEGSQ COEF
  958. ELSE XL .* COEF;
  959. SYMBOLIC PROCEDURE INVOLVESP(XL,VAR,ZL);
  960. %CHECK IF EXPONENT LIST HAS NON-ZERO POWER FOR VARIABLE;
  961. IF NULL XL THEN INTERR "VAR NOT FOUND IN INVOLVESP"
  962. ELSE IF CAR ZL=VAR THEN (NOT ZEROP CAR XL)
  963. ELSE INVOLVESP(CDR XL,VAR,CDR ZL);
  964. ENDMODULE;
  965. MODULE DRIVER;
  966. EXPORTS INTEGRATESQ,SIMPINT,PURGE,SIMPINT1;
  967. IMPORTS ALGEBRAICCASE,ALGFNPL,FINDZVARS,GETVARIABLES,INTERR,PRINTSQ,
  968. TRANSCENDENTALCASE,VARSINLIST,KERNP,SIMPCAR,PREPSQ,MKSQ,SIMP,
  969. OPMTCH,FORMLNR;
  970. %FORM IS INT(EXPR,VAR,X1,X2,...);
  971. %MEANING IS INTEGRATE EXPR WRT VAR, GIVEN THAT THE RESULT MAY;
  972. %CONTAIN LOGS OF X1,X2,...;
  973. % X1, ETC ARE INTENDED FOR USE WHEN THE SYSTEM HAS TO BE HELPED;
  974. % IN THE CASE THAT EXPR IS ALGEBRAIC;
  975. SYMBOLIC PROCEDURE SIMPINT U;
  976. % Simplify an integral, links up with general prefix mode system;
  977. BEGIN SCALAR EXPRESSION,VARIABLE,TT,LOGLIST,W,!*GCD,!*MCD,!*EXP,
  978. !*PURERISCH,!*SQRT,!*STRUCTURE;
  979. % ARGUMENT IS A LIST OF TWO ELEMENTS, WHICH ARE PREFIX FORMS;
  980. % OF THE INTEGRAND AND VARIABLE OF INTEGRATION;
  981. !*GCD:=T;
  982. !*MCD:=T;
  983. !*EXP:=T;
  984. !*SQRT:=T;
  985. !*STRUCTURE := T;
  986. VARIABLE:=CDR U;
  987. EXPRESSION:=SIMPP CAR U; %CONVERT INTEGRAND INTO A SQ;
  988. IF NULL VARIABLE THEN GO TO NOTENOUGHARGS;
  989. W:=CDR VARIABLE;
  990. VARIABLE:= !*Q2K SIMPP CAR VARIABLE; %CONVERT VARIABLE;
  991. %NOW ARGUMENTS HAVE BEEN CHECKED. START WORK;
  992. LOGLIST:=MAPCAR(W,FUNCTION SIMPP);
  993. U:=ERRORSET('(INTEGRATESQ EXPRESSION VARIABLE LOGLIST),
  994. NIL,!*BACKTRACE);
  995. IF NOT ATOM U THEN RETURN CAR U; %INTEGRATION OK;
  996. RETURN SIMPINT1(EXPRESSION . VARIABLE.W);
  997. % LEAVE IT FORMAL & LINEARISED;
  998. NOTENOUGHARGS: INTERR "NOT ENOUGH ARGS FOR INT";
  999. TOOMANYARGS: INTERR "TOO MANY ARGS FOR INT"
  1000. END;
  1001. SYMBOLIC PROCEDURE SIMPP U;
  1002. %converts U to canonical form. Resimplifies if U is a *sq form;
  1003. IF EQCAR(U,'!*SQ) THEN RESIMP CADR U ELSE SIMP U;
  1004. PUT('INT,'SIMPFN,'SIMPINT);
  1005. SYMBOLIC PROCEDURE INTEGRATESQ(INTEGRAND,VAR,XLOGS);
  1006. BEGIN SCALAR VARLIST,ZLIST;
  1007. IF !*TRINT THEN <<
  1008. PRINTC "INTEGRAND IS...";
  1009. PRINTSQ INTEGRAND >>;
  1010. VARLIST:=GETVARIABLES INTEGRAND;
  1011. VARLIST:=VARSINLIST(XLOGS,VARLIST); %IN CASE MORE EXIST IN XLOGS;
  1012. ZLIST:=FINDZVARS(VARLIST,LIST VAR,VAR,NIL); %%IMPORTSANT KERNELS;
  1013. %the next section causes problems with nested exponentials or logs;
  1014. BEGIN SCALAR OLDZLIST;
  1015. WHILE OLDZLIST NEQ ZLIST DO <<
  1016. OLDZLIST:=ZLIST;
  1017. FOREACH ZZ IN OLDZLIST DO
  1018. ZLIST:=FINDZVARS(PSEUDODIFF(ZZ,VAR),ZLIST,VAR,T) >>
  1019. END;
  1020. IF !*TRINT THEN <<
  1021. PRINTC "WITH 'NEW' FUNCTIONS :";
  1022. PRINT ZLIST >>;
  1023. IF !*PURERISCH AND NOT ALLOWEDFNS ZLIST
  1024. THEN RETURN SIMPINT1 (INTEGRAND . VAR.NIL);
  1025. % IF IT IS NOT SUITABLE FOR RISCH;
  1026. VARLIST:=PURGE(ZLIST,VARLIST);
  1027. % NOW ZLIST IS LIST OF THINGS THAT DEPEND ON X, AND VARLIST IS LIST;
  1028. % OF CONSTANT KERNELS IN INTEGRAND;
  1029. RETURN TRANSCENDENTALCASE(INTEGRAND,VAR,XLOGS,ZLIST,VARLIST)
  1030. END;
  1031. SYMBOLIC PROCEDURE PSEUDODIFF(A,VAR);
  1032. IF ATOM A THEN NIL
  1033. ELSE IF CAR A MEMQ '(EXPT PLUS TIMES QUOTIENT LOG SQRT)
  1034. THEN BEGIN SCALAR AA,BB;
  1035. FOREACH ZZ IN CDR A DO <<
  1036. BB:=PSEUDODIFF(ZZ,VAR);
  1037. IF AA THEN AA:=BB . AA ELSE BB >>;
  1038. RETURN AA
  1039. END
  1040. ELSE LIST PREPSQ SIMPDF(LIST(A,VAR));
  1041. MKOP 'INT!*;
  1042. SYMBOLIC PROCEDURE SIMPINT1 U;
  1043. BEGIN SCALAR V,!*SQRT;
  1044. U := 'INT . PREPSQ CAR U . CDR U;
  1045. IF (V := FORMLNR U) NEQ U
  1046. THEN IF !*NOLNR THEN <<
  1047. V:= SIMP SUBST('INT!*,'INT,V);
  1048. RETURN REMAKESF NUMR V ./ REMAKESF DENR V>>
  1049. ELSE <<!*NOLNR:= NIL . !*NOLNR;
  1050. U:=ERRORSET(LIST('SIMP,MKQUOTE V),NIL,!*BACKTRACE);
  1051. IF PAIRP U THEN V:=CAR U;
  1052. !*NOLNR:= CDR !*NOLNR;
  1053. RETURN V>>;
  1054. RETURN IF (V := OPMTCH U) THEN SIMP V ELSE MKSQ(U,1)
  1055. END;
  1056. SYMBOLIC PROCEDURE REMAKESF U;
  1057. %remakes standard form U, substituting operator INT for INT!*;
  1058. IF DOMAINP U THEN U
  1059. ELSE ADDF(MULTPF(IF EQCAR(MVAR U,'INT!*)
  1060. THEN MKSP('INT . CDR MVAR U,LDEG U)
  1061. ELSE LPOW U,REMAKESF LC U),
  1062. REMAKESF RED U);
  1063. SYMBOLIC PROCEDURE ALLOWEDFNS U;
  1064. IF NULL U
  1065. THEN T
  1066. ELSE IF ATOM CAR U OR
  1067. FLAGP(CAAR U,'TRANSCENDENTAL)
  1068. THEN ALLOWEDFNS CDR U
  1069. ELSE NIL;
  1070. SYMBOLIC PROCEDURE PURGE(A,B);
  1071. IF NULL A THEN B
  1072. ELSE IF NULL B THEN NIL
  1073. ELSE PURGE(CDR A,DELETE(CAR A,B));
  1074. ENDMODULE;
  1075. MODULE D3D4;
  1076. EXPORTS CUBIC,QUARTIC;
  1077. IMPORTS COVECDF,CUBEROOTF,NTH,FORCEAZERO,MAKEPOLYDF,MULTDF,MULTDFCONST,
  1078. !*MULTF!*,NEGDF,PLUSDF,PRINTDF,PRINTSF,QUADRATIC,SQRTF,VP1,VP2,ADDF,
  1079. NEGF;
  1080. %SPLITTING OF CUBICS AND QUARTICS;
  1081. SYMBOLIC PROCEDURE CUBIC(POL,VAR,RES);
  1082. %SPLIT THE UNIVARIATE (WRT Z-VARS) CUBIC POL, AT LEAST IF A;
  1083. %CHANGE OF ORIGIN PUTS IT IN THE FORM (X-A)**3-B=0;
  1084. BEGIN SCALAR A,B,C,D,V,SHIFT,P,Q,DSC;
  1085. V:=COVECDF(POL,VAR,3);
  1086. SHIFT:=FORCEAZERO(V,3); %MAKE COEFF X**2 VANISH;
  1087. %ALSO CHECKS UNIVARIATE;
  1088. % IF SHIFT='FAILED THEN GO TO PRIME;
  1089. A:=GETV(V,3); B:=GETV(V,2); %=0, I HOPE!;
  1090. C:=GETV(V,1); D:=GETV(V,0);
  1091. IF !*TRINT THEN << PRINTC "CUBIC HAS COEFFICIENTS";
  1092. PRINTSF A; PRINTSF B;
  1093. PRINTSF C; PRINTSF D >>;
  1094. IF NOT NULL C THEN <<
  1095. PRINTC "CUBIC TOO HARD TO SPLIT";
  1096. GO TO EXIT >>;
  1097. A:=CUBEROOTF(A); %CAN'T EVER FAIL;
  1098. D:=CUBEROOTF(D);
  1099. IF !*TRINT THEN << PRINTC "CUBE ROOTS OF A AND D ARE";
  1100. PRINTSF A; PRINTSF D>>;
  1101. %NOW A*(X+SHIFT)+D IS A FACTOR OF POL;
  1102. %CREATE X+SHIFT IN P;
  1103. P:=(VP2 ZLIST .* SHIFT) .+ NIL;
  1104. P:=(VP1(VAR,1,ZLIST) .* (1 ./ 1)) .+ P; %(X+SHIFT);
  1105. B:=NIL;
  1106. B:=(VP2 ZLIST .* (D ./ 1)) .+ B;
  1107. B:=PLUSDF(B,MULTDFCONST(A ./ 1,P));
  1108. B:=MAKEPOLYDF B; %GET RID OF DENOMINATOR;
  1109. IF !*TRINT THEN << PRINTC "ONE FACTOR OF THE CUBIC IS";
  1110. PRINTDF B >>;
  1111. RES:=('LOG . B) . RES;
  1112. %NOW FORM THE (QUADRATIC) COFACTOR;
  1113. B:=(VP2 ZLIST .* (!*F2POL !*MULTF!*(D,D) ./ 1)) .+ NIL;
  1114. B:=PLUSDF(B,MULTDFCONST(NEGF !*F2POL !*MULTF!*(A,D) ./ 1,P));
  1115. B:=PLUSDF(B,MULTDFCONST(!*F2POL !*MULTF!*(A,A) ./ 1,
  1116. MULTDF(P,P)));
  1117. RETURN QUADRATIC(MAKEPOLYDF B,VAR,RES); %DEAL WITH WHAT IS LEFT;
  1118. PRIME:
  1119. PRINTC "THE FOLLOWING CUBIC DOES NOT SPLIT";
  1120. EXIT:
  1121. PRINTDF POL;
  1122. RETURN ('LOG . POL) . RES
  1123. END;
  1124. FLUID '(KNOWNDISCRIMSIGN);
  1125. SYMBOLIC PROCEDURE QUARTIC(POL,VAR,RES);
  1126. %SPLITS UNIVARIATE (WRT Z-VARS) QUARTICS THAT CAN BE WRITTEN;
  1127. %IN THE FORM (X-A)**4+B*(X-A)**2+C;
  1128. BEGIN SCALAR A,B,C,D,E,V,SHIFT,P,Q,P1,P2,DSC;
  1129. V:=COVECDF(POL,VAR,4);
  1130. SHIFT:=FORCEAZERO(V,4); %MAKE COEFF X**3 VANISH;
  1131. % IF SHIFT='FAILED THEN GO TO PRIME;
  1132. A:=GETV(V,4); B:=GETV(V,3); %=0, I HOPE!;
  1133. C:=GETV(V,2); D:=GETV(V,1);
  1134. E:=GETV(V,0);
  1135. IF !*TRINT THEN << PRINTC "QUARTIC HAS COEFFICIENTS";
  1136. PRINTSF A; PRINTSF B;
  1137. PRINTSF C; PRINTSF D;
  1138. PRINTSF E >>;
  1139. IF NOT NULL D THEN << PRINTC "QUARTIC TOO HARD TO SPLIT";
  1140. GO TO EXIT >>;
  1141. B:=C; C:=E; %SQUASH UP THE NOTATION;
  1142. IF KNOWNDISCRIMSIGN EQ 'NEGATIVE THEN GO TO COMPLEX;
  1143. DSC := !*F2POL ADDF(MULTF(B,B),MULTF(-4,MULTF(A,C)));
  1144. P2 := MINUSF C;
  1145. IF NOT P2 AND MINUSF DSC THEN GO TO COMPLEX;
  1146. P1 := NULL B OR MINUSF B;
  1147. IF NOT P1 THEN IF P2 THEN P1 := T ELSE P2 := T;
  1148. P1 := IF P1 THEN 'POSITIVE ELSE 'NEGATIVE;
  1149. P2 := IF P2 THEN 'NEGATIVE ELSE 'POSITIVE;
  1150. A := SQRTF A;
  1151. DSC := SQRTF DSC;
  1152. E := INVSQ(ADDF(A,A) ./ 1);
  1153. D := MULTSQ(ADDF(B,NEGF DSC) ./ 1,E);
  1154. E := MULTSQ(ADDF(B,DSC) ./ 1,E);
  1155. IF !*TRINT
  1156. THEN <<PRINTC "QUADRATIC FACTORS WILL HAVE COEFFICIENTS";
  1157. PRINTSF A; PRINT 0; PRINTSQ D;
  1158. PRINTC "OR"; PRINTSQ E>>;
  1159. P := (VP2 ZLIST .* SHIFT) .+ NIL;
  1160. P := (VP1(VAR,1,ZLIST) .* (1 ./ 1)) .+ P; %(X+SHIFT);
  1161. Q := MULTDF(P,P); %SQUARE OF SAME;
  1162. Q := MULTDFCONST(A ./ 1,Q);
  1163. P := PLUSDF(Q,(VP2 ZLIST .* D) .+ NIL);
  1164. Q := PLUSDF(Q,(VP2 ZLIST .* E) .+ NIL);
  1165. IF !*TRINT
  1166. THEN <<PRINTC "ALLOWING FOR CHANGE OF ORIGIN:";
  1167. PRINTDF P; PRINTDF Q>>;
  1168. KNOWNDISCRIMSIGN := P1;
  1169. RES := QUADRATIC(P,VAR,RES);
  1170. KNOWNDISCRIMSIGN := P2;
  1171. RES := QUADRATIC(Q,VAR,RES);
  1172. GO TO QUARTICDONE;
  1173. COMPLEX:
  1174. A:=SQRTF(A);
  1175. C:=SQRTF(C);
  1176. B:=ADDF(!*F2POL !*MULTF!*(2,!*MULTF!*(A,C)),NEGF B);
  1177. B:=SQRTF B;
  1178. %NOW A*(X+SHIFT)**2 (+/-) B*(X+SHIFT) + C IS A FACTOR;
  1179. IF !*TRINT
  1180. THEN << PRINTC "QUADRATIC FACTORS WILL HAVE COEFFICIENTS";
  1181. PRINTSF A; PRINTSF B; PRINTSF C>>;
  1182. P:=(VP2 ZLIST .* SHIFT) .+ NIL;
  1183. P:=(VP1(VAR,1,ZLIST) .* (1 ./ 1)) .+ P; %(X+SHIFT);
  1184. Q:=MULTDF(P,P); %SQUARE OF SAME;
  1185. P:=MULTDFCONST(B ./ 1,P);
  1186. Q:=MULTDFCONST(A ./ 1,Q);
  1187. Q:=PLUSDF(Q,(VP2 ZLIST .* (C ./ 1)) .+ NIL);
  1188. IF !*TRINT THEN <<
  1189. PRINTC "ALLOWING FOR CHANGE OF ORIGIN, P (+/-) Q WITH P,Q=";
  1190. PRINTDF P; PRINTDF Q>>;
  1191. %NOW P+Q AND P-Q ARE THE FACTORS OF THE QUARTIC;
  1192. KNOWNDISCRIMSIGN := 'NEGATIVE;
  1193. RES:=QUADRATIC(PLUSDF(Q,P),VAR,RES);
  1194. RES:=QUADRATIC(PLUSDF(Q,NEGDF P),VAR,RES);
  1195. QUARTICDONE:
  1196. KNOWNDISCRIMSIGN := NIL;
  1197. IF !*TRINT THEN PRINTC "QUARTIC DONE";
  1198. RETURN RES;
  1199. PRIME:
  1200. PRINTC "THE FOLLOWING QUARTIC DOES NOT SPLIT";
  1201. EXIT:
  1202. PRINTDF POL;
  1203. RETURN ('LOG . POL) . RES
  1204. END;
  1205. ENDMODULE;
  1206. MODULE FACTR;
  1207. EXPORTS INT!-FAC,VAR2DF;
  1208. IMPORTS CUBIC,DF2Q,F2DF,INTERR,MULTDF,PRINTDF,QUADRATIC,QUARTIC,UNIFAC,
  1209. UNIFORM,VP1,VP2,SUB1;
  1210. SYMBOLIC PROCEDURE INT!-FAC X;
  1211. %INPUT: PRIMITIVE, SQUARE-FREE POLYNOMIAL (S.FORM);
  1212. %OUTPUT:
  1213. % LIST OF 'FACTORS' WRT ZLIST;
  1214. % EACH ITEM IN THIS LIST IS EITHER;
  1215. % LOG . SQ;
  1216. % OR ATAN . SQ;
  1217. % AND THESE LOGS AND ARCTANS ARE ALL THAT IS NEEDED IN THE;
  1218. % INTEGRATION OF 1/(ARGUMENT);
  1219. BEGIN SCALAR RES,POL,DSET,VAR,DEGREE,VARS;
  1220. POL:=F2DF X; %CONVERT TO DISTRIBUTED FORM;
  1221. DSET:=DEGREESET(POL);
  1222. %NOW EXTRACT FACTORS OF THE FORM 'X' OR 'LOG(X)' ETC;
  1223. %THESE CORRESPOND TO ITEMS IN DSET WITH A NON-ZERO CDR;
  1224. BEGIN SCALAR ZL,DS;
  1225. ZL:=ZLIST; DS:=DSET;
  1226. WHILE NOT NULL DS DO <<
  1227. IF ONEP CDAR DS THEN <<
  1228. RES:=('LOG . VAR2DF(CAR ZL,1,ZLIST)) . RES;
  1229. %RECORD IN ANSWER;
  1230. POL:=MULTDF(VAR2DF(CAR ZL,-1,ZLIST),POL);
  1231. %DIVIDE OUT;
  1232. IF !*TRINT THEN << PRINTC "TRIVIAL FACTOR FOUND";
  1233. PRINTDF CDAR RES>>;
  1234. RPLACA(DS,SUB1 CAAR DS . CDAR DS) >>
  1235. ELSE IF NULL ZEROP CDAR DS THEN
  1236. INTERR "REPEATED TRIVIAL FACTOR IN ARG TO FACTOR";
  1237. ZL:=CDR ZL; DS:=CDR DS >>;
  1238. END; %SINGLE TERM FACTORS ALL REMOVED NOW;
  1239. DSET:=MAPCAR(DSET,FUNCTION CAR); %GET LOWER BOUNDS;
  1240. IF !*TRINT
  1241. THEN PRINTC ("UPPER BOUNDS OF REMAINING FACTORS ARE NOW: " .
  1242. DSET);
  1243. IF DSET=VP2 ZLIST THEN GO TO FINISHED; %THING LEFT IS CONSTANT;
  1244. BEGIN SCALAR DS,ZL;
  1245. VAR:=CAR ZLIST; DEGREE:=CAR DSET;
  1246. IF NOT ZEROP DEGREE THEN VARS:=VAR . VARS;
  1247. DS:=CDR DSET; ZL:=CDR ZLIST;
  1248. WHILE NOT NULL DS DO <<
  1249. IF NOT ZEROP CAR DS THEN <<
  1250. VARS:=CAR ZL . VARS;
  1251. IF ZEROP DEGREE OR DEGREE>CAR DS THEN <<
  1252. VAR:=CAR ZL; DEGREE:=CAR DS >> >>;
  1253. ZL:=CDR ZL; DS:=CDR DS >>
  1254. END;
  1255. % NOW VAR IS VARIABLE THAT THIS POLY INVOLVES TO LOWEST DEGREE;
  1256. % DEGREE IS THE DEGREE OF THE POLY IN SAME VARIABLE;
  1257. IF !*TRINT
  1258. THEN PRINTC ("BEST VAR IS " . VAR . "WITH EXPONENT " .
  1259. DEGREE);
  1260. IF ONEP DEGREE THEN <<
  1261. RES:=('LOG . POL) . RES; %CERTAINLY IRREDUCIBLE;
  1262. IF !*TRINT
  1263. THEN << PRINTC "THE FOLLOWING IS CERTAINLY IRREDUCIBLE";
  1264. PRINTDF POL>>;
  1265. GO TO FINISHED >>;
  1266. IF DEGREE=2 THEN <<
  1267. IF !*TRINT THEN << PRINTC "QUADRATIC";
  1268. PRINTDF POL>>;
  1269. RES:=QUADRATIC(POL,VAR,RES);
  1270. GO TO FINISHED >>;
  1271. DSET:=UNIFORM(POL,VAR);
  1272. IF NOT (DSET='FAILED) THEN <<
  1273. IF !*TRINT THEN << PRINTC "UNIVARIATE POLYNOMIAL";
  1274. PRINTDF POL >>;
  1275. RES:=UNIFAC(DSET,VAR,DEGREE,RES);
  1276. GO TO FINISHED >>;
  1277. IF NOT NULL CDR VARS THEN GO TO NASTY; %ONLY TRY UNIVARIATE NOW;
  1278. IF DEGREE=3 THEN <<
  1279. IF !*TRINT THEN << PRINTC "CUBIC";
  1280. PRINTDF POL>>;
  1281. RES:=CUBIC(POL,VAR,RES);
  1282. % IF !*OVERLAYMODE
  1283. % THEN EXCISE 'D3D4;
  1284. GO TO FINISHED >>;
  1285. IF DEGREE=4 THEN <<
  1286. IF !*TRINT THEN << PRINTC "QUARTIC";
  1287. PRINTDF POL>>;
  1288. RES:=QUARTIC(POL,VAR,RES);
  1289. % IF !*OVERLAYMODE
  1290. % THEN EXCISE 'D3D4;
  1291. GO TO FINISHED>>;
  1292. %ELSE ABANDON HOPE AND HAND BACK SOME RUBBISH.;
  1293. NASTY:
  1294. RES:=('LOG . POL) . RES;
  1295. PRINTC
  1296. "THE FOLLOWING POLYNOMIAL HAS NOT BEEN PROPERLY FACTORED";
  1297. PRINTDF POL;
  1298. GO TO FINISHED;
  1299. FINISHED: %RES IS A LIST OF D.F. S AS REQUIRED;
  1300. POL:=NIL; %CONVERT BACK TO STANDARD FORMS;
  1301. WHILE NOT NULL RES DO
  1302. BEGIN SCALAR TYPE,ARG;
  1303. TYPE:=CAAR RES; ARG:=CDAR RES;
  1304. ARG:=DF2Q ARG;
  1305. IF TYPE='LOG THEN RPLACD(ARG,1);
  1306. POL:=(TYPE . ARG) . POL;
  1307. RES:=CDR RES END;
  1308. RETURN POL
  1309. END;
  1310. SYMBOLIC PROCEDURE VAR2DF(VAR,N,ZLIST);
  1311. ((VP1(VAR,N,ZLIST) .* (1 ./ 1)) .+ NIL);
  1312. SYMBOLIC PROCEDURE DEGREESET POL;
  1313. %FINDS DEGREE BOUNDS FOR ALL VARS IN DISTRIBTED FORM POLY;
  1314. DEGREESUB(DBL LPOW POL,RED POL);
  1315. SYMBOLIC PROCEDURE DBL X;
  1316. % CONVERTS LIST OF X INTO LIST OF (X . X);
  1317. IF NULL X THEN NIL
  1318. ELSE (CAR X . CAR X) . DBL CDR X;
  1319. SYMBOLIC PROCEDURE DEGREESUB(CUR,POL);
  1320. % UPDATE DEGREE BOUNDS 'CUR' TO INCLUDE INFO ABOUT POL;
  1321. <<
  1322. WHILE NOT NULL POL DO <<
  1323. CUR:=DEGREESUB1(CUR,LPOW POL);
  1324. POL:=RED POL >>;
  1325. CUR >>;
  1326. SYMBOLIC PROCEDURE DEGREESUB1(CUR,NXT);
  1327. %MERGE INFORMATION FROM EXPONENT SET NEXT INTO CUR;
  1328. IF NULL CUR THEN NIL
  1329. ELSE DEGREESUB2(CAR CUR,CAR NXT) . DEGREESUB1(CDR CUR,CDR NXT);
  1330. SYMBOLIC PROCEDURE DEGREESUB2(TWO,ONE);
  1331. MAX(CAR TWO,ONE) . MIN(CDR TWO,ONE);
  1332. ENDMODULE;
  1333. MODULE IBASICS;
  1334. EXPORTS PARTIALDIFF,PRINTDF,PRINTSQ,RATIONALINTEGRATE,PRINTSF,INTERR;
  1335. IMPORTS DF2PRINTFORM,SQPRINT,VARSINSF,TERPRI!*,ADDSQ,MULTSQ,MULTD,MKSP;
  1336. %PRINT STANDARD QUOTIENT (RATIONAL FUNCTION);
  1337. % CRUDE EQUIVALENT TO PRINTSF NUMR U: "/": PRINTSF DENO U;
  1338. SYMBOLIC PROCEDURE PRINTSQ U;
  1339. BEGIN
  1340. TERPRI!*(T); %START ON A NEW LINE;
  1341. SQPRINT U; %LOGICAL PRINT ROUTINE;
  1342. TERPRI!*(T)
  1343. END;
  1344. % PRINT STANDARD FORM (POLYNOMIAL);
  1345. FLUID '(U!*); %NEEDED BECAUSE OF THE ERRORSET;
  1346. SYMBOLIC PROCEDURE PRINTSF U!*;
  1347. IF NULL U!* THEN PRINT 0
  1348. ELSE BEGIN SCALAR W;
  1349. W:=ERRORSET('(PROG NIL (TERPRI!* T)
  1350. (XPRINF U!* NIL NIL) (TERPRI!* T)),2,!*BACKTRACE);
  1351. IF NOT ATOM W THEN RETURN CAR W;
  1352. PRINTC "REDUCE PRINTING FAILED ON STANDARD FORM";
  1353. PRINT U!*;
  1354. TERPRI!*(T);
  1355. RETURN U!*
  1356. END;
  1357. UNFLUID '(U!*);
  1358. SYMBOLIC PROCEDURE PRINTDF U;
  1359. % PRINT DISTRIBUTED FORM VIA CHEAP CONVERSION TO REDUCE STRUCTURE;
  1360. BEGIN SCALAR !*GCD;
  1361. PRINTSF DF2PRINTFORM U;
  1362. END;
  1363. SYMBOLIC PROCEDURE INTERR MESS;
  1364. BEGIN
  1365. PRINTC "INTEGRATION PACKAGE ERROR";
  1366. PRINTC MESS;
  1367. ERROR1()
  1368. END;
  1369. SYMBOLIC PROCEDURE RATIONALINTEGRATE(X,VAR);
  1370. BEGIN SCALAR N,D;
  1371. N:=NUMR X; D:=DENR X;
  1372. IF NOT VAR MEMBER VARSINSF(D,NIL) THEN
  1373. RETURN SUBS2Q MULTSQ(POLYNOMIALINTEGRATE(N,VAR),1 ./ D);
  1374. INTERR "RATIONAL INTEGRATION NOT CODED YET"
  1375. END;
  1376. % INTEGRATE STANDARD FORM. RESULT IS STANDARD QUOTIENT;
  1377. SYMBOLIC PROCEDURE POLYNOMIALINTEGRATE(X,V);
  1378. IF NULL X THEN NIL ./ 1
  1379. ELSE IF ATOM X THEN ((MKSP(V,1) .* 1) .+ NIL) ./ 1
  1380. ELSE BEGIN SCALAR R;
  1381. R:=POLYNOMIALINTEGRATE(RED X,V); % DEAL WITH REDUCTUM;
  1382. IF V=MVAR X THEN BEGIN SCALAR DEGREE,NEWLT;
  1383. DEGREE:=1+TDEG LT X;
  1384. NEWLT:=((MKSP(V,DEGREE) .* LC X) .+ NIL) ./ 1; % UP EXPONENT;
  1385. R:=ADDSQ(MULTSQ(NEWLT,1 ./ DEGREE),R)
  1386. END
  1387. ELSE BEGIN SCALAR NEWTERM;
  1388. NEWTERM:=(((LPOW X) .* 1) .+ NIL) ./ 1;
  1389. NEWTERM:=MULTSQ(NEWTERM,POLYNOMIALINTEGRATE(LC X,V));
  1390. R:=ADDSQ(R,NEWTERM)
  1391. END;
  1392. RETURN SUBS2Q R
  1393. END;
  1394. % PARTIAL DIFFERENTIATION OF P WRT V - P IS S.F. AS IS RESULT;
  1395. SYMBOLIC PROCEDURE PARTIALDIFF(P,V);
  1396. IF ATOM P THEN NIL
  1397. ELSE
  1398. IF V=MVAR P THEN
  1399. (LAMBDA X; IF X=1 THEN LC P
  1400. ELSE ((MKSP(V,X-1) .* MULTD(X,LC P))
  1401. .+ PARTIALDIFF(RED P,V)))
  1402. (TDEG LT P)
  1403. ELSE
  1404. (LAMBDA X; IF NULL X THEN PARTIALDIFF(RED P,V)
  1405. ELSE ((LPOW P .* X) .+ PARTIALDIFF(RED P,V)))
  1406. (PARTIALDIFF(LC P,V));
  1407. PUT('PDIFF,'SIMPFN,'SIMPPDIFF);
  1408. ENDMODULE;
  1409. MODULE JPATCHES;
  1410. EXPORTS !*MULTF!*;
  1411. IMPORTS !*MULTF!*SQRT,SIMPSQRTI,RETIMES,MULTSQ,SIMPEXPT,INVSQ,MKSQ,XN,
  1412. FLATTEN,MKSPM,MKSP,EXPTF,SIMP,GCDN,ADDF,ORDOP,NONCOMP,MKSFPF,
  1413. MULTD,DOMAINP;
  1414. %SYMBOLIC PROCEDURE SIMPX1(U,M,N);
  1415. % %U,M AND N ARE PREFIX EXPRESSIONS;
  1416. % %VALUE IS THE STANDARD QUOTIENT EXPRESSION FOR U**(M/N);
  1417. % BEGIN SCALAR FLG,Z;
  1418. % IF NULL FRLIS!* OR NULL XN(FRLIS!*,FLATTEN (M . N))
  1419. % THEN GO TO A;
  1420. % EXPTP!* := T;
  1421. % RETURN !*K2Q LIST('EXPT,U,IF N=1 THEN M
  1422. % ELSE LIST('QUOTIENT,M,N));
  1423. % A: IF NUMBERP M AND FIXP M THEN GO TO E
  1424. % ELSE IF ATOM M THEN GO TO B
  1425. % ELSE IF CAR M EQ 'MINUS THEN GO TO MNS
  1426. % ELSE IF CAR M EQ 'PLUS THEN GO TO PLS
  1427. % ELSE IF CAR M EQ 'TIMES AND NUMBERP CADR M AND FIXP CADR M
  1428. % AND NUMBERP N
  1429. % THEN GO TO TMS;
  1430. % B: Z := 1;
  1431. % C: IF ATOM U AND NOT NUMBERP U THEN FLAG(LIST U,'USED!*);
  1432. % U := LIST('EXPT,U,IF N=1 THEN M ELSE LIST('QUOTIENT,M,N));
  1433. % IF NOT U MEMBER EXPTL!* THEN EXPTL!* := U . EXPTL!*;
  1434. % D: RETURN MKSQ(U,IF FLG THEN -Z ELSE Z); %U IS ALREADY IN LOWEST
  1435. % %TERMS;
  1436. % E: IF NUMBERP N AND FIXP N THEN GO TO INT;
  1437. % Z := M;
  1438. % M := 1;
  1439. % GO TO C;
  1440. % MNS: M := CADR M;
  1441. % IF !*MCD THEN RETURN INVSQ SIMPX1(U,M,N);
  1442. % FLG := NOT FLG;
  1443. % GO TO A;
  1444. % PLS: Z := 1 ./ 1;
  1445. % PL1: M := CDR M;
  1446. % IF NULL M THEN RETURN Z;
  1447. % Z := MULTSQ(SIMPEXPT LIST(U,
  1448. % LIST('QUOTIENT,IF FLG THEN LIST('MINUS,CAR M)
  1449. % ELSE CAR M,N)),
  1450. % Z);
  1451. % GO TO PL1;
  1452. % TMS: Z := GCDN(N,CADR M);
  1453. % N := N/Z;
  1454. % Z := CADR M/Z;
  1455. % M := RETIMES CDDR M;
  1456. % GO TO C;
  1457. % INT:Z := DIVIDE(M,N);
  1458. % IF CDR Z<0 THEN Z:= (CAR Z - 1) . (CDR Z+N);
  1459. % IF CDR Z=0
  1460. % THEN RETURN SIMPEXPT LIST(U,CAR Z);
  1461. % IF N=2 AND !*SQRT
  1462. % THEN RETURN MULTSQ(SIMPEXPT LIST(U,CAR Z),
  1463. % SIMPSQRTI U);
  1464. % RETURN MULTSQ(SIMPEXPT LIST(U,CAR Z),
  1465. % MKSQ(LIST('EXPT,U,LIST('QUOTIENT,1,N)),CDR Z))
  1466. % END;
  1467. ENDMODULE;
  1468. MODULE KRON;
  1469. EXPORTS LINFAC,QUADFAC;
  1470. IMPORTS EVALAT,LINETHROUGH,QUADTHROUGH,TESTDIV;
  1471. %KRONEKER FACTORIZATION FOR UNIVARIATE POLYS OVER THE INTEGERS;
  1472. %ONLY LINEAR AND QUADRATIC FACTORS ARE FOUND HERE;
  1473. SYMBOLIC PROCEDURE LINFAC(W);
  1474. TRYKR(W,'(0 1));
  1475. SYMBOLIC PROCEDURE QUADFAC(W);
  1476. TRYKR(W,'(-1 0 1));
  1477. SYMBOLIC PROCEDURE TRYKR(W,POINTS);
  1478. %LOOK FOR FACTOR OF W BY EVALUATION AT (POINTS) AND USE OF;
  1479. % INTERPOLATE. RETURN (FAC . COFAC) WITH FAC=NIL IF NONE;
  1480. %FOUND AND COFAC=NIL IF NOTHING WORTHWHILE IS LEFT;
  1481. BEGIN SCALAR VALUES,ATTEMPT;
  1482. IF NULL W THEN RETURN NIL . NIL;
  1483. IF (LENGTH POINTS > CAR W) THEN RETURN W . NIL;
  1484. %THAT SAYS IF W IS ALREADY TINY, IT IS ALREADY FACTORED;
  1485. VALUES:=MAPCAR(POINTS,FUNCTION (LAMBDA X;
  1486. EVALAT(W,X)));
  1487. IF !*TRINT THEN << PRINTC ("AT X= " . POINTS);
  1488. PRINTC ("P(X)= " . VALUES)>>;
  1489. IF 0 MEMBER VALUES THEN GO TO LUCKY; %(X-1) IS A FACTOR!;
  1490. VALUES:=MAPCAR(VALUES,FUNCTION ZFACTORS);
  1491. RPLACD(VALUES,MAPCAR(CDR VALUES,FUNCTION (LAMBDA Y;
  1492. APPEND(Y,MAPCAR(Y,FUNCTION MINUS)))));
  1493. IF !*TRINT THEN <<PRINTC "POSSIBLE FACTORS GO THROUGH SOME OF";
  1494. PRINT VALUES>>;
  1495. ATTEMPT:=SEARCH4FAC(W,VALUES,NIL);
  1496. IF NULL ATTEMPT THEN ATTEMPT:=NIL . W;
  1497. RETURN ATTEMPT;
  1498. LUCKY: %HERE (X-1) IS A FACTOR BECAUSE P(0) OR P(1) OR P(-1);
  1499. %VANISHED AND CASES P(0), P(-1) WILL HAVE BEEN REMOVED;
  1500. %ELSEWHERE;
  1501. ATTEMPT:='(1 1 -1); %THE FACTOR;
  1502. RETURN ATTEMPT . TESTDIV(W,ATTEMPT)
  1503. END;
  1504. SYMBOLIC PROCEDURE SEARCH4FAC(W,VALUES,CV);
  1505. %COMBINATORIAL SEARCH. CV GETS CURRENT SELECTED VALUE-SET;
  1506. %RETURNS NIL IF FAILS, ELSE FACTOR . COFACTOR;
  1507. IF NULL VALUES THEN TRYFACTOR(W,CV)
  1508. ELSE BEGIN SCALAR FF,Q;
  1509. FF:=CAR VALUES; %TRY ALL VALUES HERE;
  1510. LOOP: IF NULL FF THEN RETURN NIL; %NO FACTOR FOUND;
  1511. Q:=SEARCH4FAC(W,CDR VALUES,(CAR FF) . CV);
  1512. IF NULL Q THEN << FF:=CDR FF; GO TO LOOP>>;
  1513. RETURN Q
  1514. END;
  1515. SYMBOLIC PROCEDURE TRYFACTOR(W,CV);
  1516. %TESTS IF CV REPRESENTS A FACTOR OF W;
  1517. BEGIN SCALAR FF,Q;
  1518. IF NULL CDDR CV THEN FF:=LINETHROUGH(CADR CV,CAR CV)
  1519. ELSE FF:=QUADTHROUGH(CADDR CV,CADR CV,CAR CV);
  1520. IF FF='FAILED THEN RETURN NIL; %IT DOES NOT INTERPOLATE;
  1521. Q:=TESTDIV(W,FF);
  1522. IF Q='FAILED THEN RETURN NIL; %NOT A FACTOR;
  1523. RETURN FF . Q
  1524. END;
  1525. ENDMODULE;
  1526. MODULE LOWDEG;
  1527. EXPORTS FORCEAZERO,MAKEPOLYDF,QUADRATIC,COVECDF,EXPONENTDF;
  1528. IMPORTS DFQUOTDF,GCDF,INTERR,MINUSDFP,MULTDF,MULTDFCONST,!*MULTF!*,
  1529. NEGSQ,MINUSP,PRINTSQ,MULTSQ,INVSQ,PNTH,NTH,MKNILL,
  1530. NEGDF,PLUSDF,PRINTDF,PRINTSQ,QUOTF,SQRTDF,VAR2DF,VP2,ADDSQ,SUB1;
  1531. %SPLITTING OF LOW DEGREE POLYNOMIALS;
  1532. SYMBOLIC PROCEDURE COVECDF(POL,VAR,DEGREE);
  1533. %EXTRACT COEFFICIENTS OF POLYNOMIAL WRT VAR, GIVEN A DEGREE-BOUND
  1534. % DEGREE;
  1535. %RESUL IS A LISP VECTOR;
  1536. BEGIN SCALAR I,V,X,W;
  1537. W:=POL;
  1538. V:=MKVECT(DEGREE);
  1539. WHILE NOT NULL W DO <<
  1540. X:=EXPONENTOF(VAR,LPOW W,ZLIST);
  1541. IF (X<0) OR (X>DEGREE) THEN INTERR "BAD DEGREE IN COVECDF";
  1542. PUTV(V,X,LT W . GETV(V,X));
  1543. W:=RED W >>;
  1544. FOR I:=0:DEGREE DO PUTV(V,I,MULTDF(REVERSEWOC GETV(V,I),
  1545. VAR2DF(VAR,-I,ZLIST)));
  1546. RETURN V
  1547. END;
  1548. SYMBOLIC PROCEDURE QUADRATIC(POL,VAR,RES);
  1549. %ADD IN TO RES LOGS OR ARCTANS CORRESPONDING TO SPLITTING THE
  1550. % POLYNOMIAL;
  1551. % POL GIVEN THAT IT IS QUADRATIC WRT VAR;
  1552. %;
  1553. %DOES NOT ASSUME POL IS UNIVARIATE;
  1554. BEGIN SCALAR A,B,C,W,DISCRIM;
  1555. W:=COVECDF(POL,VAR,2);
  1556. A:=GETV(W,2); B:=GETV(W,1); C:=GETV(W,0);
  1557. % THAT SPLIT THE QUADRATIC UP TO FIND THE COEFFICIENTS A,B,C;
  1558. IF !*TRINT THEN << PRINTC "A="; PRINTDF A;
  1559. PRINTC "B="; PRINTDF B;
  1560. PRINTC "C="; PRINTDF C>>;
  1561. DISCRIM:=PLUSDF(MULTDF(B,B),
  1562. MULTDFCONST((-4) . 1,MULTDF(A,C)));
  1563. IF !*TRINT THEN << PRINTC "DISCRIMINANT IS";
  1564. PRINTDF DISCRIM>>;
  1565. IF NULL DISCRIM THEN INTERR "DISCRIM=0 IN QUADRATIC";
  1566. IF KNOWNDISCRIMSIGN
  1567. THEN <<IF KNOWNDISCRIMSIGN EQ 'NEGATIVE THEN GO TO ATANCASE>>
  1568. ELSE IF (NOT CLOGFLAG) AND (MINUSDFP DISCRIM)
  1569. THEN GO TO ATANCASE;
  1570. DISCRIM:=SQRTDF(DISCRIM);
  1571. IF DISCRIM='FAILED THEN GO TO NOFACTORS;
  1572. IF !*TRINT THEN << PRINTC "SQUARE-ROOT IS";
  1573. PRINTDF DISCRIM>>;
  1574. W:=VAR2DF(VAR,1,ZLIST);
  1575. W:=MULTDF(W,A);
  1576. B:=MULTDFCONST(1 ./ 2,B);
  1577. DISCRIM:=MULTDFCONST(1 ./ 2,DISCRIM);
  1578. W:=PLUSDF(W,B); %A*X+B/2;
  1579. A:=PLUSDF(W,DISCRIM); B:=PLUSDF(W,NEGDF(DISCRIM));
  1580. IF !*TRINT THEN << PRINTC "FACTORS ARE";
  1581. PRINTDF A; PRINTDF B>>;
  1582. RETURN ('LOG . A) . ('LOG . B) . RES;
  1583. ATANCASE:
  1584. DISCRIM:=SQRTDF NEGDF DISCRIM; %SQRT(4*A*C-B**2) THIS TIME!;
  1585. IF DISCRIM='FAILED THEN GO TO NOFACTORS; %SQRT DID NOT EXIST?;
  1586. RES := ('LOG . POL) . RES; %ONE PART OF THE ANSWER;
  1587. A:=MULTDF(A,VAR2DF(VAR,1,ZLIST));
  1588. A:=PLUSDF(B,MULTDFCONST(2 ./ 1,A));
  1589. A:=DFQUOTDF(A,DISCRIM); %ASSUMES DIVISION IS EXACT;
  1590. RETURN ('ATAN . A) . RES;
  1591. NOFACTORS:
  1592. PRINTC "THE FOLLOWING QUADRATIC DOES NOT SEEM TO FACTOR";
  1593. PRINTDF POL;
  1594. RETURN ('LOG . POL) . RES
  1595. END;
  1596. SYMBOLIC PROCEDURE EXPONENTOF(VAR,L,ZL);
  1597. IF NULL ZL THEN INTERR "VAR NOT FOUND IN EXPONENTOF"
  1598. ELSE IF VAR=CAR ZL THEN CAR L
  1599. ELSE EXPONENTOF(VAR,CDR L,CDR ZL);
  1600. SYMBOLIC PROCEDURE DF2SF A;
  1601. IF NULL A THEN NIL
  1602. ELSE IF ((NULL RED A) AND
  1603. (ONEP DENR LC A) AND
  1604. (LPOW A=VP2 ZLIST)) THEN NUMR LC A
  1605. ELSE INTERR "NASTY CUBIC OR QUARTIC";
  1606. SYMBOLIC PROCEDURE MAKEPOLYDF P;
  1607. %MULTIPLY DF BY LCM OF DENOMINATORS OF ALL COEFFICIENT DENOMINATORS;
  1608. BEGIN SCALAR H,W;
  1609. IF NULL(W:=P) THEN RETURN NIL; %POLY IS ZERO ALREADY;
  1610. H:=DENR LC W; %A GOOD START;
  1611. W:=RED W;
  1612. WHILE NOT NULL W DO <<
  1613. H:=QUOTF(!*MULTF!*(H,DENR LC W),GCDF(H,DENR LC W));
  1614. W:=RED W >>;
  1615. %H IS NOW LCM OF DENOMINATORS;
  1616. RETURN MULTDFCONST(!*F2POL H ./ 1,P)
  1617. END;
  1618. SYMBOLIC PROCEDURE FORCEAZERO(P,N);
  1619. %SHIFT POLYNOMIAL P SO THAT COEFF OF X**(N-1) VANISHES;
  1620. %RETURN THE AMOUNT OF THE SHIFT, UPDATE (VECTOR) P;
  1621. BEGIN SCALAR R,I,W;
  1622. FOR I:=0:N DO PUTV(P,I,DF2SF GETV(P,I)); %CONVERT TO POLYS;
  1623. R:=GETV(P,N-1);
  1624. IF NULL R THEN RETURN NIL ./ 1; %ALREADY ZERO;
  1625. R:= SUBS2Q MULTSQ(R ./ 1,INVSQ(!*MULTF!*(N,GETV(P,N)) ./ 1));
  1626. %THE SHIFT AMOUNT;
  1627. %NOW I HAVE TO SET P:=SUBST(X-R,X,P) AND THEN REDUCE TO SF AGAIN;
  1628. IF !*TRINT THEN << PRINTC "SHIFT IS BY ";
  1629. PRINTSQ R>>;
  1630. W:=MKVECT(N); %WORKSPACE VECTOR;
  1631. FOR I:=0:N DO PUTV(W,I,NIL ./ 1); %ZERO IT;
  1632. I:=N;
  1633. WHILE NOT MINUSP I DO <<
  1634. MULVECBYXR(W,NEGSQ R,N); %W:=(X-R)*W;
  1635. PUTV(W,0,ADDSQ(GETV(W,0),GETV(P,I) ./ 1));
  1636. I:=I-1 >>;
  1637. IF !*TRINT THEN << PRINTC "SQ SHIFTED POLY IS";
  1638. PRINT W>>;
  1639. FOR I:=0:N DO PUTV(P,I,GETV(W,I));
  1640. W:=DENR GETV(P,0);
  1641. FOR I:=1:N DO W:=QUOTF(!*MULTF!*(W,DENR GETV(P,I)),
  1642. GCDF(W,DENR GETV(P,I)));
  1643. FOR I:=0:N DO PUTV(P,I,NUMR SUBS2Q MULTSQ(GETV(P,I),W ./ 1));
  1644. W:=GETV(P,0);
  1645. FOR I:=1:N DO W:=GCDF(W,GETV(P,I));
  1646. IF NOT (W=1) THEN
  1647. FOR I:=0:N DO PUTV(P,I,QUOTF(GETV(P,I),W));
  1648. IF !*TRINT THEN << PRINTC "FINAL SHIFTED POLY IS ";
  1649. PRINT P>>;
  1650. RETURN R
  1651. END;
  1652. SYMBOLIC PROCEDURE MULVECBYXR(W,R,N);
  1653. %W IS A VECTOR REPRESENTING A POLY OF DEGREE N;
  1654. %MULTIPLY IT BY (X+R);
  1655. BEGIN SCALAR I,IM1;
  1656. I:=N;
  1657. IM1:=SUB1 I;
  1658. WHILE NOT MINUSP IM1 DO <<
  1659. PUTV(W,I,SUBS2Q ADDSQ(GETV(W,IM1),MULTSQ(R,GETV(W,I))));
  1660. I:=IM1; IM1:=SUB1 I >>;
  1661. PUTV(W,0,SUBS2Q MULTSQ(GETV(W,0),R));
  1662. RETURN W
  1663. END;
  1664. ENDMODULE;
  1665. MODULE REFORM;
  1666. EXPORTS LOGSTOSQ,SUBSTINULIST;
  1667. IMPORTS PREPSQ,MKSP,NTH,MULTSQ,ADDSQ,DOMAINP,INVSQ,PLUSDF;
  1668. SYMBOLIC PROCEDURE SUBSTINULIST ULIST;
  1669. % Substitutes for the C-constants in the values of the U's given in;
  1670. % ULIST. Result is a D.F.;
  1671. IF NULL ULIST THEN NIL
  1672. ELSE BEGIN SCALAR TEMP,LCU;
  1673. LCU:=LC ULIST;
  1674. TEMP:=EVALUATEUCONST NUMR LCU;
  1675. IF NULL NUMR TEMP THEN TEMP:=NIL
  1676. ELSE TEMP:=((LPOW ULIST) .*
  1677. SUBS2Q MULTSQ(TEMP,INVSQ(DENR LCU ./ 1))) .+ NIL;
  1678. RETURN PLUSDF(TEMP,SUBSTINULIST RED ULIST)
  1679. END;
  1680. SYMBOLIC PROCEDURE EVALUATEUCONST COEFFT;
  1681. % Substitutes for the C-constants into COEFFT (=S.F.). Result is S.Q.;
  1682. IF NULL COEFFT OR DOMAINP COEFFT THEN COEFFT ./ 1
  1683. ELSE BEGIN SCALAR TEMP;
  1684. IF NULL(TEMP:=ASSOC(MVAR COEFFT,CMAP)) THEN
  1685. TEMP:=(!*P2F LPOW COEFFT) ./ 1
  1686. ELSE TEMP:=GETV(CVAL,CDR TEMP);
  1687. TEMP:=MULTSQ(TEMP,EVALUATEUCONST(LC COEFFT));
  1688. RETURN SUBS2Q ADDSQ(TEMP,EVALUATEUCONST(RED COEFFT))
  1689. END;
  1690. SYMBOLIC PROCEDURE LOGSTOSQ;
  1691. % Converts LOGLIST to sum of the log terms as a S.Q.;
  1692. BEGIN SCALAR LGLST,LOGSQ,I,TEMP;
  1693. I:=1;
  1694. LGLST:=LOGLIST;
  1695. LOGSQ:=NIL ./ 1;
  1696. LOOP: IF NULL LGLST THEN RETURN LOGSQ;
  1697. TEMP:=CDDR CAR LGLST;
  1698. IF !*TRINT
  1699. THEN << PRINTC "Standard Form ARG FOR ADDITIONAL LOG ETC =";
  1700. PRINT TEMP >>;
  1701. IF NOT (CAAR LGLST='IDEN) THEN <<
  1702. TEMP:=PREPSQ TEMP; %CONVERT TO PREFIX FORM;
  1703. TEMP:=LIST(CAAR LGLST,TEMP); %FUNCTION NAME;
  1704. TEMP:=((MKSP(TEMP,1) .* 1) .+ NIL) ./ 1 >>;
  1705. TEMP:=MULTSQ(TEMP,GETV(CVAL,I));
  1706. LOGSQ:= SUBS2Q ADDSQ(TEMP,LOGSQ);
  1707. LGLST:=CDR LGLST;
  1708. I:=I+1;
  1709. GO TO LOOP
  1710. END;
  1711. ENDMODULE;
  1712. MODULE SIMPLOG;
  1713. EXPORTS SIMPLOG,SIMPLOGSQ;
  1714. IMPORTS QUOTF,PREPF,MKSP,SIMP!*,MULTSQ,SIMPTIMES,ADDSQ,MINUSF,NEGF,
  1715. ADDF,COMFAC,NEGSQ,MK!*SQ,CARX;
  1716. SYMBOLIC PROCEDURE SIMPLOG(EXXPR);
  1717. SIMPLOGI(CARX(EXXPR,'LOG));
  1718. SYMBOLIC PROCEDURE SIMPLOGI(SQ);
  1719. BEGIN
  1720. IF ATOM SQ
  1721. THEN GO TO SIMPLIFY;
  1722. IF CAR SQ EQ 'TIMES
  1723. THEN RETURN ADDSQ(SIMPLOGI CADR SQ,SIMPLOGI CADDR SQ);
  1724. IF CAR SQ EQ 'QUOTIENT
  1725. THEN RETURN ADDSQ(SIMPLOGI CADR SQ,
  1726. NEGSQ SIMPLOGI CADDR SQ);
  1727. IF CAR SQ EQ 'EXPT
  1728. THEN RETURN SIMPTIMES LIST(CADDR SQ,
  1729. MK!*SQ SIMPLOGI CADR SQ);
  1730. IF CAR SQ = '!*SQ
  1731. THEN RETURN SIMPLOGSQ CADR SQ;
  1732. SIMPLIFY:
  1733. SQ:=SIMP!* SQ;
  1734. RETURN SIMPLOGSQ SQ
  1735. END;
  1736. SYMBOLIC PROCEDURE SIMPLOGSQ SQ;
  1737. ADDSQ((SIMPLOG2 NUMR SQ),NEGSQ(SIMPLOG2 DENR SQ));
  1738. SYMBOLIC PROCEDURE SIMPLOG2(SF);
  1739. IF ATOM SF
  1740. THEN IF NULL SF
  1741. THEN REDERR "LOG 0 FORMED"
  1742. ELSE IF NUMBERP SF
  1743. THEN IF SF IEQUAL 1
  1744. THEN NIL ./ 1
  1745. ELSE IF SF IEQUAL 0
  1746. THEN REDERR "LOG 0 FORMED"
  1747. ELSE((MKSP(LIST('LOG,SF),1) .* 1) .+ NIL) ./ 1
  1748. ELSE FORMLOG(SF)
  1749. ELSE BEGIN
  1750. SCALAR FORM;
  1751. FORM:=COMFAC SF;
  1752. IF NOT NULL CAR FORM
  1753. THEN RETURN ADDSQ(FORMLOG(FORM .+ NIL),
  1754. SIMPLOG2 QUOTF(SF,FORM .+ NIL));
  1755. % WE HAVE KILLED COMMON POWERS;
  1756. FORM:=CDR FORM;
  1757. IF FORM NEQ 1
  1758. THEN RETURN ADDSQ(SIMPLOG2 FORM,
  1759. SIMPLOG2 QUOTF(SF,FORM));
  1760. % REMOVE A COMMON FACTOR FROM THE SF;
  1761. RETURN (FORMLOG SF)
  1762. END;
  1763. SYMBOLIC PROCEDURE FORMLOG(SF);
  1764. IF (NULL RED SF)
  1765. THEN IF EQCAR(MVAR SF,'EXPT)
  1766. THEN ADDSQ(SIMPLOG2 LC SF,
  1767. SUBS2Q MULTSQ(SIMPLOGI MVAR SF,SIMP!* LDEG SF))
  1768. ELSE IF (LC SF IEQUAL 1) AND (LDEG SF IEQUAL 1)
  1769. THEN ((MKSP(LIST('LOG,MVAR SF),1) .* 1) .+ NIL) ./ 1
  1770. ELSE ADDSQ(SIMPTIMES LIST(LIST('LOG,MVAR SF),LDEG SF),
  1771. SIMPLOG2 LC SF)
  1772. ELSE IF MINUSF SF
  1773. THEN ADDF((MKSP(LIST('LOG,-1),1) .* 1) .+ NIL,
  1774. FORMLOG2 NEGF SF) ./ 1
  1775. ELSE (FORMLOG2 SF) ./ 1;
  1776. SYMBOLIC PROCEDURE FORMLOG2 SF;
  1777. ((MKSP(LIST('LOG,PREPF SF),1) .* 1) .+ NIL);
  1778. ENDMODULE;
  1779. MODULE SIMPSQRT;
  1780. SYMBOLIC PROCEDURE SIMPSQRTSQ SQ;
  1781. (SIMPSQRT2 NUMR SQ) ./ (SIMPSQRT2 DENR SQ);
  1782. SYMBOLIC PROCEDURE SIMPSQRT2(SF);
  1783. IF ATOM SF
  1784. THEN IF NULL SF
  1785. THEN NIL
  1786. ELSE IF NUMBERP SF
  1787. THEN IF MINUSP SF
  1788. THEN !*F2POL !*MULTF!*(SIMPSQRT2 (-SF),
  1789. (MKSP(MKSQRT(-1),1) .* 1) .+ NIL)
  1790. ELSE BEGIN
  1791. SCALAR N;
  1792. N:=SQRT SF;
  1793. IF IDP N
  1794. THEN RETURN (MKSP(MKSQRT!* SF,1) .* 1) .+ NIL
  1795. ELSE RETURN N
  1796. END
  1797. ELSE FORMSQRT(SF)
  1798. ELSE BEGIN
  1799. SCALAR FORM;
  1800. FORM:=COMFAC SF;
  1801. IF NOT NULL CAR FORM
  1802. THEN RETURN !*F2POL !*MULTF!*(FORMSQRT(FORM .+ NIL),
  1803. SIMPSQRT2 QUOTF(SF,FORM .+ NIL));
  1804. % WE HAVE KILLED COMMON POWERS;
  1805. FORM:=CDR FORM;
  1806. IF FORM NEQ 1
  1807. THEN RETURN !*F2POL !*MULTF!*(SIMPSQRT2 FORM,
  1808. SIMPSQRT2 QUOTF(SF,FORM));
  1809. % REMOVE A COMMON FACTOR FROM THE SF;
  1810. RETURN FORMSQRT SF
  1811. END;
  1812. SYMBOLIC PROCEDURE FORMSQRT(SF);
  1813. %Is *F2POL really necessary here??;
  1814. IF (NULL RED SF)
  1815. THEN IF (LC SF IEQUAL 1) AND (LDEG SF IEQUAL 1)
  1816. THEN (MKSP(MKSQRT!* MVAR SF,1) .* 1) .+ NIL
  1817. ELSE !*F2POL
  1818. !*MULTF!*(NUMR SIMPEXPT(LIST(MKSQRT!* MVAR SF,LDEG SF)),
  1819. SIMPSQRT2 LC SF)
  1820. ELSE (MKSP(MKSQRT!* SF,1) .* 1) .+ NIL;
  1821. SYMBOLIC PROCEDURE MKSQRT!* U;
  1822. IF SFP U THEN MKSQRT !*F2A U ELSE MKSQRT U;
  1823. ALGEBRAIC;
  1824. % OPERATOR SQRT;
  1825. SYMBOLIC;
  1826. % DEFLIST ('((SQRT (((X) QUOTIENT (SQRT X) (TIMES 2 X))))),'DFN);
  1827. SYMBOLIC PROCEDURE SIMPSQRTI SQ;
  1828. BEGIN
  1829. IF ATOM SQ
  1830. THEN IF NUMBERP SQ
  1831. THEN RETURN (SIMPSQRT2 SQ) ./ 1
  1832. ELSE RETURN ((MKSP(MKSQRT SQ,1) .* 1) .+ NIL) ./ 1;
  1833. IF CAR SQ EQ 'TIMES
  1834. THEN RETURN SUBS2Q MULTSQ(SIMPSQRTI CADR SQ,SIMPSQRTI CADDR SQ);
  1835. IF CAR SQ EQ 'QUOTIENT
  1836. THEN RETURN SUBS2Q MULTSQ(SIMPSQRTI CADR SQ,
  1837. INVSQ SIMPSQRTI CADDR SQ);
  1838. IF CAR SQ EQ 'EXPT
  1839. THEN RETURN SIMPEXPT
  1840. LIST(MK!*SQ SIMPSQRTI CADR SQ,CADDR SQ);
  1841. IF CAR SQ = '!*SQ
  1842. THEN RETURN SIMPSQRTSQ CADR SQ;
  1843. RETURN SIMPSQRTSQ SIMP!* SQ
  1844. END;
  1845. ENDMODULE;
  1846. MODULE SOLVE;
  1847. EXPORTS SOLVE!-FOR!-U;
  1848. IMPORTS NTH,FINDPIVOT,GCDF,GENSYM1,MKVECT,INTERR,MULTDFCONST,
  1849. !*MULTF!*,NEGDF,ORDDF,PLUSDF,PRINTDF,PRINTSF,PRINTSPREADC,PRINTSQ,
  1850. QUOTF,PUTV,SPREADC,SUBST4ELIMINATEDCS,MKNILL,PNTH,DOMAINP,ADDF,
  1851. INVSQ,MULTSQ;
  1852. %***********************************************************************
  1853. % ROUTINES FOR SOLVING THE FINAL REDUCTION EQUATION:
  1854. %**********************************************************************;
  1855. SYMBOLIC PROCEDURE UTERM(POWU,RHS);
  1856. % Finds the contribution from RHS of reduction equation, of the;
  1857. % U-coefficient given by POWU. Result is in D.F.;
  1858. IF NULL RHS THEN NIL
  1859. ELSE BEGIN SCALAR COEF,POWER;
  1860. POWER:=ADDINDS(POWU,LPOW RHS);
  1861. COEF:=EVALUATECOEFFTS(NUMR LC RHS,POWU);
  1862. IF NULL COEF THEN RETURN UTERM(POWU,RED RHS);
  1863. COEF:=COEF ./ DENR LC RHS;
  1864. RETURN PLUSDF((POWER .* COEF) .+ NIL,UTERM(POWU,RED RHS))
  1865. END;
  1866. SYMBOLIC PROCEDURE SOLVE!-FOR!-U(RHS,LHS,ULIST);
  1867. % Solves the reduction eqn LHS = RHS. Returns list of U-coefficients;
  1868. % and their values (ULIST are those we have so far), and a list of;
  1869. % C-equations to be solved (CLIST are the eqns we have so far);
  1870. IF NULL LHS THEN ULIST
  1871. ELSE BEGIN SCALAR U,LPOWLHS;
  1872. LPOWLHS:=LPOW LHS;
  1873. BEGIN SCALAR LL,MM,CHGE; LL:=MAXORDER(RHS,ZLIST,0);
  1874. MM:=LORDER;
  1875. WHILE MM DO << IF CAR LL < CAR MM THEN
  1876. << CHGE:=T; RPLACA(MM,CAR LL) >>;
  1877. LL:=CDR LL; MM:=CDR MM >>;
  1878. IF !*TRINT AND CHGE THEN << PRINT ("Maxorder now ".LORDER) >>
  1879. END;
  1880. U:=PICKUPU(RHS,LPOW LHS,T);
  1881. IF NULL U THEN
  1882. << IF !*TRINT THEN << PRINTC "****** C-EQUATION TO SOLVE:";
  1883. PRINTSF NUMR LC LHS;
  1884. PRINTC " = 0";
  1885. PRINTC " ">>;
  1886. % Remove a zero constant from the lhs, rather than use
  1887. % Gauss Elim;
  1888. IF GAUSSELIMN(NUMR LC LHS,LT LHS) THEN
  1889. LHS:=SQUASHCONSTANTS(RED LHS)
  1890. ELSE LHS:=RED LHS >>
  1891. ELSE
  1892. << ULIST:=(CAR U .
  1893. SUBS2Q MULTSQ(COEFDF(LHS,LPOWLHS),INVSQ CDR U)).ULIST;
  1894. IF !*STATISTICS THEN !*NUMBER!*:=!*NUMBER!*+1;
  1895. IF !*TRINT THEN << PRINTC ("**** U(".CAR U);
  1896. PRINTC " =";
  1897. PRINTSQ MULTSQ(COEFDF(LHS,LPOWLHS),INVSQ CDR U);
  1898. PRINTC " ">>;
  1899. LHS:=PLUSDF(LHS,
  1900. NEGDF MULTDFCONST(CDAR ULIST,UTERM(CAR U,RHS))) >>;
  1901. IF !*TRINT THEN << PRINTC ".... LHS is now:";
  1902. PRINTDF LHS;
  1903. PRINTC " ">>;
  1904. RETURN SOLVE!-FOR!-U(RHS,LHS,ULIST)
  1905. END;
  1906. SYMBOLIC PROCEDURE SQUASHCONSTANTS(EXPRESS);
  1907. BEGIN SCALAR CONSTLST,II,XP,CL,SUBBY,CMT,XX;
  1908. CONSTLST:=REVERSE CMAP;
  1909. CMT:=CMATRIX;
  1910. XXX: XX:=CAR CMT; % Look at next row of Cmatrix;
  1911. CL:=CONSTLST; % and list of the names;
  1912. II:=1; % will become index of removed constant;
  1913. WHILE NOT GETV(XX,II) DO
  1914. << II:=II+1; CL:=CDR CL >>;
  1915. SUBBY:=CAAR CL; %II is now index, and SUBBY the name;
  1916. IF MEMBER(SUBBY,SILLIESLIST) THEN
  1917. <<CMT:=CDR CMT; GO TO XXX>>; %This loop must terminate;
  1918. % This is because at least one constant remains;
  1919. XP:=PREPSQ !*F2Q GETV(XX,0); % start to build up the answer;
  1920. CL:=CDR CL;
  1921. IF NOT (CCOUNT=II) THEN FOR JJ=II+1:CCOUNT DO <<
  1922. IF GETV(XX,JJ) THEN
  1923. XP:=LIST('PLUS,XP,
  1924. LIST('TIMES,CAAR CL,
  1925. PREPSQ !*F2Q GETV(XX,JJ)));
  1926. CL:=CDR CL >>;
  1927. XP:=LIST('QUOTIENT,LIST('MINUS,XP),
  1928. PREPSQ !*F2Q GETV(XX,II));
  1929. IF !*TRINT THEN << PRIN2 "Replace "; PRIN2 SUBBY;
  1930. PRIN2 " by "; PRINTSQ SIMP XP >>;
  1931. SILLIESLIST:=SUBBY . SILLIESLIST;
  1932. RETURN SUBDF(EXPRESS,XP,SUBBY)
  1933. END;
  1934. SYMBOLIC PROCEDURE CHECKU(ULIST,U);
  1935. % Checks that U is not already in ULIST - ie. that this u-coefficient;
  1936. % has not already been given a value;
  1937. IF NULL ULIST THEN NIL
  1938. ELSE IF (CAR U) = CAAR ULIST THEN T
  1939. ELSE CHECKU(CDR ULIST,U);
  1940. SYMBOLIC PROCEDURE CHECKU1(POWU,RHS);
  1941. %Checks that use of a particular U-term will not cause trouble;
  1942. %by introducing negative exponents into lhs when it is used;
  1943. BEGIN
  1944. TOP:
  1945. IF NULL RHS THEN RETURN NIL;
  1946. IF NEGIND(POWU,LPOW RHS) THEN
  1947. IF NOT NULL EVALUATECOEFFTS(NUMR LC RHS,POWU) THEN RETURN T;
  1948. RHS:=RED RHS;
  1949. GO TO TOP
  1950. END;
  1951. SYMBOLIC PROCEDURE NEGIND(PU,PR);
  1952. %check if substituting index values in power gives rise to -ve
  1953. % exponents;
  1954. IF NULL PU THEN NIL
  1955. ELSE IF (CAR PU+CAAR PR)<0 THEN T
  1956. ELSE NEGIND(CDR PU,CDR PR);
  1957. SYMBOLIC PROCEDURE EVALUATECOEFFTS(COEFFT,INDLIST);
  1958. % Substitutes the values of the i,j,k,...'s that appear in the S.F. ;
  1959. % COEFFT (=coefficient of r.h.s. of reduction equation). Result is S.F.;
  1960. IF NULL COEFFT OR DOMAINP COEFFT THEN
  1961. IF ZEROP COEFFT THEN NIL ELSE COEFFT
  1962. ELSE BEGIN SCALAR TEMP;
  1963. IF MVAR COEFFT MEMBER INDEXLIST THEN
  1964. TEMP:=VALUECOEFFT(MVAR COEFFT,INDLIST,INDEXLIST)
  1965. ELSE TEMP:=!*P2F LPOW COEFFT;
  1966. TEMP:=!*MULTF!*(TEMP,EVALUATECOEFFTS(LC COEFFT,INDLIST));
  1967. RETURN ADDF(!*F2POL TEMP,EVALUATECOEFFTS(RED COEFFT,INDLIST))
  1968. END;
  1969. SYMBOLIC PROCEDURE VALUECOEFFT(VAR,INDVALUES,INDLIST);
  1970. % Finds the value of VAR, which should be in INDLIST, given INDVALUES;
  1971. % - the corresponding values of INDLIST variables;
  1972. IF NULL INDLIST THEN INTERR "VALUECOEFFT - NO VALUE"
  1973. ELSE IF VAR EQ CAR INDLIST THEN
  1974. IF ZEROP CAR INDVALUES THEN NIL
  1975. ELSE CAR INDVALUES
  1976. ELSE VALUECOEFFT(VAR,CDR INDVALUES,CDR INDLIST);
  1977. SYMBOLIC PROCEDURE ADDINDS(POWU,POWRHS);
  1978. % Adds indices in POWU to those in POWRHS. Result is LPOW of D.F.;
  1979. IF NULL POWU THEN IF NULL POWRHS THEN NIL
  1980. ELSE INTERR "POWRHS TOO LONG"
  1981. ELSE IF NULL POWRHS THEN INTERR "POWU TOO LONG"
  1982. ELSE (CAR POWU + CAAR POWRHS).ADDINDS(CDR POWU,CDR POWRHS);
  1983. SYMBOLIC PROCEDURE PICKUPU(RHS,POWLHS,FLG);
  1984. % Picks up the 'lowest' U coefficient from RHS if it exists and returns;
  1985. % it in the form of LT of D.F.;
  1986. % returns NIL if no legal term in RHS can be found;
  1987. % POWLHS is the power we want to match (LPOW of D.F);
  1988. % and COEFFU is the list of previous coefficients that must be zero;
  1989. BEGIN SCALAR COEFFU,U;
  1990. PT:=RHS;
  1991. TOP:
  1992. IF NULL PT THEN RETURN NIL; %no term found - failed;
  1993. U:=NEXTU(LT PT,POWLHS); %check this term...;
  1994. IF NULL U THEN GO TO NOTTHISONE;
  1995. IF NOT TESTORD(CAR U,LORDER) THEN GO TO NEVERTHISONE;
  1996. IF NOT CHECKCOEFFTS(COEFFU,CAR U) THEN GO TO NOTTHISONE;
  1997. %that inhibited clobbering things already passed over;
  1998. IF CHECKU(ULIST,U) THEN GO TO NOTTHISONE;
  1999. %that avoided redefining a u value;
  2000. IF CHECKU1(CAR U,RHS) THEN GO TO NEVERTHISONE;
  2001. %avoid introduction of negative exponents;
  2002. IF FLG THEN
  2003. U:=PATCHUPTAN(LIST U,POWLHS,RED PT,RHS);
  2004. RETURN U;
  2005. NEVERTHISONE:
  2006. COEFFU:=(LC PT) . COEFFU;
  2007. NOTTHISONE:
  2008. PT:=RED PT;
  2009. GO TO TOP
  2010. END;
  2011. SYMBOLIC PROCEDURE PATCHUPTAN(U,POWLHS,RPT,RHS);
  2012. BEGIN
  2013. SCALAR UU,CC,DD,TANLIST,REDU,REDU1;
  2014. PT:=RPT;
  2015. WHILE PT DO <<
  2016. IF (UU:=PICKUPU(PT,POWLHS,NIL))
  2017. AND TESTORD(CAR UU,LORDER) THEN <<
  2018. % Nasty found, patch it up;
  2019. CC:=(GENSYM1('!C).CAAR U).CC;
  2020. % CC is an alist of constants;
  2021. IF !*TRINT THEN << PRINTC ("****** U(".CAAR U);
  2022. PRINTC " =";
  2023. PRINT CAAR CC >>;
  2024. REDU:=PLUSDF(REDU,
  2025. MULTDFCONST(!*K2Q CAAR CC,UTERM(CAAR U,RHS)));
  2026. U:=UU.U
  2027. >>;
  2028. IF PT THEN PT:=RED PT >>;
  2029. REDU1:=REDU;
  2030. WHILE REDU1 DO BEGIN SCALAR XX; XX:=CAR REDU1;
  2031. IF !*TRINT THEN << PRIN2 "Introduced RESIDUE "; PRINT XX >>;
  2032. IF (NOT TESTORD(CAR XX,LORDER)) THEN <<
  2033. IF !*TRINT THEN <<
  2034. PRINTSQ CDR XX; PRINTC " = 0" >>;
  2035. IF DD:=KILLSINGLES(CADR XX,CC) THEN <<
  2036. REDU:=SUBDF(REDU,0,CAR DD);
  2037. REDU1:=SUBDF(REDU1,0,CAR DD);
  2038. ULIST:=((CDR DD).(NIL ./ 1)).ULIST;
  2039. U:=RMVE(U,CDR DD);
  2040. CC:=PURGECONST(CC,DD) >>
  2041. ELSE REDU1:=CDR REDU1 >>
  2042. ELSE REDU1:=CDR REDU1 END;
  2043. FOREACH XX IN REDU DO <<
  2044. IF (NOT TESTORD(CAR XX,LORDER)) THEN <<
  2045. WHILE CC DO <<
  2046. ADDCTOMAP(CAAR CC);
  2047. ULIST:=((CDAR CC).(!*K2Q CAAR CC))
  2048. . ULIST;
  2049. IF !*STATISTICS
  2050. THEN !*NUMBER!*:=!*NUMBER!*+1;
  2051. CC:=CDR CC >>;
  2052. GAUSSELIMN(NUMR LC REDU,LT REDU)>> >>;
  2053. IF REDU THEN << WHILE CC DO << ADDCTOMAP(CAAR CC);
  2054. ULIST:=((CDAR CC).(!*K2Q CAAR CC)).ULIST;
  2055. IF !*STATISTICS THEN !*NUMBER!*:=!*NUMBER!*+1;
  2056. CC:=CDR CC >>;
  2057. LHS:=PLUSDF(LHS,NEGDF REDU) >>;
  2058. RETURN CAR U
  2059. END;
  2060. SYMBOLIC PROCEDURE KILLSINGLES(XX,CC);
  2061. IF ATOM XX THEN NIL
  2062. ELSE IF NOT (CDR XX EQ NIL) THEN NIL
  2063. ELSE BEGIN SCALAR DD;
  2064. DD:=ASSOC(CAAAR XX,CC);
  2065. IF DD THEN RETURN DD;
  2066. RETURN KILLSINGLES(CDAR XX,CC)
  2067. END;
  2068. SYMBOLIC PROCEDURE RMVE(L,X);
  2069. IF CAAR L=X THEN CDR L ELSE CONS(CAR L,RMVE(CDR L,X));
  2070. SYMBOLIC PROCEDURE SUBDF(A,B,C);
  2071. % SUBSTITUTE B FOR C INTO THE DF A;
  2072. % Used to get rid of silly constants introduced;
  2073. IF A=NIL THEN NIL ELSE
  2074. BEGIN SCALAR X;
  2075. X:=SUBF(NUMR LC A,LIST (C . B)) ;
  2076. IF X=(NIL . 1) THEN RETURN SUBDF(RED A,B,C)
  2077. ELSE RETURN PLUSDF(
  2078. LIST ((LPOW A).((CAR X).MULTF(CDR X,DENR LC A))),
  2079. SUBDF(RED A,B,C))
  2080. END;
  2081. SYMBOLIC PROCEDURE TESTORD(A,B);
  2082. % Test order of two DF's in recursive fashion;
  2083. IF NULL A THEN T
  2084. ELSE IF CAR A LEQ CAR B THEN TESTORD(CDR A,CDR B)
  2085. ELSE NIL;
  2086. SYMBOLIC PROCEDURE TANFROM(RHS,Z,NN);
  2087. % We notice that in all bad cases we have (j-num)tan**j...;
  2088. % Extract the num;
  2089. BEGIN SCALAR N,ZZ,R,RR;
  2090. R:=RHS;
  2091. N:=0; ZZ:=ZLIST;
  2092. WHILE CAR ZZ NEQ Z DO << N:=N+1; ZZ:=CDR ZZ >>;
  2093. WHILE R DO <<
  2094. RR:=CAAR R; % The list of powers;
  2095. FOR I=1:N DO RR:=CDR RR;
  2096. IF FIXP CAAR RR THEN IF CAAR RR>0 THEN <<
  2097. RR:=NUMR CDAR R;
  2098. IF NULL RED RR THEN RR:=NIL ./ 1
  2099. ELSE IF FIXP (RR:=QUOTF(RED RR,LC RR))
  2100. THEN RR:=-RR ELSE RR:=0>>;
  2101. IF ATOM RR THEN RETURN RR;
  2102. R:=CDR R >>;
  2103. IF NULL R THEN RETURN MAXFROM(LHS,NN)+1;
  2104. RETURN MAX(RR,MAXFROM(LHS,NN)+1)
  2105. END;
  2106. SYMBOLIC PROCEDURE COEFDF(Y,U);
  2107. IF Y=NIL THEN NIL
  2108. ELSE IF LPOW Y=U THEN LC Y
  2109. ELSE COEFDF(RED Y,U);
  2110. SYMBOLIC PROCEDURE PURGECONST(A,B);
  2111. % Remove a const from and expression. May be the same as DELETE?;
  2112. IF NULL A THEN NIL
  2113. ELSE IF CAR A=B THEN PURGECONST(CDR A,B)
  2114. ELSE CONS(CAR A,PURGECONST(CDR A,B));
  2115. SYMBOLIC PROCEDURE MAXORDER(RHS,Z,N);
  2116. % Find a limit on the order of terms, theis is ad hoc;
  2117. IF NULL Z THEN NIL
  2118. ELSE IF EQCAR(CAR Z,'SQRT) THEN
  2119. CONS(1,MAXORDER(RHS,CDR Z,N+1))
  2120. ELSE IF (ATOM CAR Z) OR (CAAR Z NEQ 'TAN) THEN
  2121. CONS(MAXFROM(LHS,N)+1,MAXORDER(RHS,CDR Z,N+1))
  2122. ELSE CONS(TANFROM(RHS,CAR Z,N),MAXORDER(RHS,CDR Z,N+1));
  2123. SYMBOLIC PROCEDURE MAXFROM(L,N);
  2124. % Largest order in the nth varable;
  2125. IF NULL L THEN 0
  2126. ELSE MAX(NTH(CAAR L,N+1),MAXFROM(CDR L,N));
  2127. SYMBOLIC PROCEDURE COPY U;
  2128. IF ATOM U THEN U
  2129. ELSE CONS(COPY CAR U,COPY CDR U);
  2130. SYMBOLIC PROCEDURE ADDCTOMAP CC;
  2131. BEGIN
  2132. SCALAR NCVAL;
  2133. CCOUNT:=CCOUNT+1;
  2134. NCVAL:=MKVECT(CCOUNT);
  2135. FOR I=0:(CCOUNT-1) DO PUTV(NCVAL,I,GETV(CVAL,I));
  2136. PUTV(NCVAL,CCOUNT,NIL ./ 1);
  2137. CVAL:=NCVAL;
  2138. CMAP:=(CC . CCOUNT).CMAP;
  2139. IF !*TRINT THEN << PRIN2 "Constant Map CHANGED TO "; PRINT CMAP >>;
  2140. CMATRIX:=MAPCAR(CMATRIX,FUNCTION ADDTOVECTOR);
  2141. END;
  2142. SYMBOLIC PROCEDURE ADDTOVECTOR V;
  2143. BEGIN SCALAR VV;
  2144. VV:=MKVECT(CCOUNT);
  2145. FOR I=0:(CCOUNT-1) DO PUTV(VV,I,GETV(V,I));
  2146. PUTV(VV,CCOUNT,NIL);
  2147. RETURN VV
  2148. END;
  2149. SYMBOLIC PROCEDURE CHECKCOEFFTS(CL,INDV);
  2150. % checks to see that the coefficients in CL (coefficient list - S.Q.s);
  2151. % are zero when the i,j,k,... are given values in INDV (LPOW of;
  2152. % D.F.). if so the result is true else NIL=false;
  2153. IF NULL CL THEN T
  2154. ELSE BEGIN SCALAR RES;
  2155. RES:=EVALUATECOEFFTS(NUMR CAR CL,INDV);
  2156. IF NOT(NULL RES OR RES=0) THEN RETURN NIL
  2157. ELSE RETURN CHECKCOEFFTS(CDR CL,INDV)
  2158. END;
  2159. SYMBOLIC PROCEDURE NEXTU(LTRHS,POWLHS);
  2160. % picks out the appropriate U coefficients for term: LTRHS to match the;
  2161. % powers of the z-variables given in POWLHS (= exponent list of D.F.). ;
  2162. % return this coefficient in form LT of D.F. If U coefficient does;
  2163. % not exist then result is NIL. If it is multiplied by a zero then;
  2164. % result is NIL;
  2165. IF NULL LTRHS THEN NIL
  2166. ELSE BEGIN SCALAR INDLIST,UCOEFFT;
  2167. INDLIST:=SUBTRACTINDS(POWLHS,CAR LTRHS,NIL);
  2168. IF NULL INDLIST THEN RETURN NIL;
  2169. UCOEFFT:=EVALUATECOEFFTS(NUMR CDR LTRHS,INDLIST);
  2170. IF NULL UCOEFFT OR UCOEFFT=0 THEN RETURN NIL;
  2171. RETURN INDLIST .* (UCOEFFT ./ DENR CDR LTRHS)
  2172. END;
  2173. SYMBOLIC PROCEDURE SUBTRACTINDS(POWLHS,L,SOFAR);
  2174. % subtract the indices in list L from those in POWLHS to find;
  2175. % appropriate values for i,j,k,... when equating coefficients of terms;
  2176. % on lhs of reduction eqn. SOFAR is the resulting value list we;
  2177. % have constructed so far. if any i,j,k,... value is -ve then result;
  2178. % is NIL;
  2179. IF NULL L THEN REVERSEWOC SOFAR
  2180. ELSE IF ((CAR POWLHS)-(CAAR L))<0 THEN NIL
  2181. ELSE SUBTRACTINDS(CDR POWLHS,CDR L,
  2182. ((CAR POWLHS)-(CAAR L)) . SOFAR);
  2183. SYMBOLIC PROCEDURE GAUSSELIMN(EQUATION,TOKILL);
  2184. % Performs Gaussian elimination on the matrix for the c-equations;
  2185. % as each c-equation is found. EQUATION is the next one to deal with;
  2186. BEGIN SCALAR NEWROW,PIVOT;
  2187. IF ZEROP CCOUNT THEN GO TO NOWAY; %FAILURE;
  2188. NEWROW:=MKVECT(CCOUNT);
  2189. SPREADC(EQUATION,NEWROW,1);
  2190. SUBST4ELIMINATEDCS(NEWROW,REVERSE ORDEROFELIM,REVERSE CMATRIX);
  2191. PIVOT:=FINDPIVOT NEWROW;
  2192. IF NULL PIVOT THEN GO TO NOPIVOTFOUND;
  2193. ORDEROFELIM:=PIVOT . ORDEROFELIM;
  2194. NEWROW:=MAKEPRIM NEWROW; %REMOVE HCF FROM NEW EQUATION;
  2195. CMATRIX:=NEWROW . CMATRIX;
  2196. % IF !*TRINT THEN PRINTSPREADC NEWROW;
  2197. RETURN T;
  2198. NOPIVOTFOUND:
  2199. IF NULL GETV(NEWROW,0) THEN <<
  2200. IF !*TRINT THEN PRINTC "Already included";
  2201. RETURN NIL>>; %EQUATION WAS 0=0;
  2202. NOWAY:
  2203. BADPART:=TOKILL . BADPART; %NON-INTEGRABLE TERM;
  2204. IF !*TRINT THEN PRINTC "Inconsistent";
  2205. RETURN NIL
  2206. END;
  2207. SYMBOLIC PROCEDURE MAKEPRIM ROW;
  2208. BEGIN SCALAR I,G;
  2209. G:=GETV(ROW,0);
  2210. FOR I:=1:CCOUNT DO G:=GCDF(G,GETV(ROW,I));
  2211. IF G NEQ 1 THEN
  2212. FOR I:=0:CCOUNT DO PUTV(ROW,I,QUOTF(GETV(ROW,I),G));
  2213. FOR I := 0:CCOUNT DO
  2214. <<G := GETV(ROW,I);
  2215. IF G AND NOT DOMAINP G
  2216. THEN PUTV(ROW,I,NUMR RESIMP((ROOTEXTRACTF G) ./ 1))>>;
  2217. RETURN ROW
  2218. END;
  2219. ENDMODULE;
  2220. MODULE SQRTF;
  2221. EXPORTS MINUSDFP,SQRTDF,NROOTN,DOMAINP,MINUSF;
  2222. IMPORTS CONTENTSMV,GCDF,INTERR,!*MULTF!*,PARTIALDIFF,PRINTDF,QUOTF,
  2223. SIMPSQRT2,VP2;
  2224. %SQUARE-ROOT OF STANDARD FORMS;
  2225. SYMBOLIC PROCEDURE MINUSDFP A;
  2226. %TEST SIGN OF LEADING COEDD OF D.F;
  2227. IF NULL A THEN INTERR "MINUSDFP 0 ILLEGAL"
  2228. ELSE MINUSF NUMR LC A;
  2229. SYMBOLIC PROCEDURE SQRTDF L;
  2230. %TAKES SQUARE ROOT OF D.F.;
  2231. IF NULL L THEN NIL
  2232. ELSE IF NOT NULL RED L THEN 'FAILED
  2233. ELSE BEGIN SCALAR C;
  2234. IF LPOW L=VP2 ZLIST THEN GO TO OK;
  2235. PRINTC "SQRTDF NOT COMPLETE";
  2236. PRINTDF L;
  2237. RETURN 'FAILED;
  2238. OK: RETURN (LPOW L .* SQRTSQ LC L) .+ NIL
  2239. END;
  2240. SYMBOLIC PROCEDURE SQRTSQ A;
  2241. SQRTF NUMR A ./ SQRTF DENR A;
  2242. SYMBOLIC PROCEDURE SQRTF P;
  2243. BEGIN SCALAR IP,QP;
  2244. IF NULL P THEN RETURN NIL;
  2245. IP:=SQRTF1 P;
  2246. QP:=CDR IP;
  2247. IP:=CAR IP; %RESPECTABLE AND NASTY PARTS OF THE SQRT;
  2248. IF ONEP QP THEN RETURN IP; %EXACT ROOT FOUND;
  2249. QP:=SIMPSQRT2 QP;
  2250. RETURN !*F2POL !*MULTF!*(IP,QP)
  2251. END;
  2252. SYMBOLIC PROCEDURE SQRTF1 P;
  2253. %RETURNS A . B WITH P=A**2*B;
  2254. IF DOMAINP P THEN NROOTN(P,2)
  2255. ELSE BEGIN SCALAR CO,PP,G,PG;
  2256. CO:=CONTENTSMV(P,MVAR P,NIL); %CONTENTS OF P;
  2257. PP:=QUOTF(P,CO); %PRIMITIVE PART;
  2258. CO:=SQRTF1(CO); %PROCESS CONTENTS VIA RECURSION;
  2259. G:=GCDF(PP,PARTIALDIFF(PP,MVAR PP));
  2260. PG:=QUOTF(PP,G);
  2261. G:=GCDF(G,PG); %A REPEATED FACTOR OF PP;
  2262. IF G=1 THEN PG:=1 . PP
  2263. ELSE <<
  2264. PG:= !*F2POL QUOTF(PP,!*MULTF!*(G,G)); %WHAT IS STILL LEFT;
  2265. PG:=SQRTF1(PG); %SPLIT THAT UP;
  2266. RPLACA(PG,!*MULTF!*(CAR PG,G))>>;
  2267. %PUT IN THE THING FOUND HERE;
  2268. RPLACA(PG,!*F2POL !*MULTF!*(CAR PG,CAR CO));
  2269. RPLACD(PG,!*F2POL !*MULTF!*(CDR PG,CDR CO));
  2270. RETURN PG
  2271. END;
  2272. % NROOTN removed as in REDUCE base;
  2273. ENDMODULE;
  2274. MODULE TDIFF;
  2275. EXPORTS !-!-SIMPDF;
  2276. IMPORTS SIMPCAR,KERNP,DIFFSQ,PREPSQ,MSGPRI;
  2277. FLAG('(!-!-SIMPDF),'LOSE);
  2278. %TDF(EXPR,VAR) DIFFERENTIATES BUT WITH TIMING SERVICE;
  2279. SYMBOLIC PROCEDURE !-!-SIMPDF U;
  2280. %U IS A LIST OF FORMS, THE FIRST AN EXPRESSION AND THE REMAINDER
  2281. %KERNELS AND NUMBERS.
  2282. %VALUE IS DERIVATIVE OF FIRST FORM WRT REST OF LIST;
  2283. BEGIN SCALAR V,X,Y,TT;
  2284. TT := TIME(); %start the clock;
  2285. V := CDR U;
  2286. U := SIMPCAR U;
  2287. A: IF NULL V OR NULL NUMR U THEN GO TO EXIT;
  2288. X := IF NULL Y OR Y=0 THEN SIMPCAR V ELSE Y;
  2289. IF NULL KERNP X THEN GO TO E;
  2290. X := CAAAAR X;
  2291. V := CDR V;
  2292. IF NULL V THEN GO TO C;
  2293. Y := SIMPCAR V;
  2294. IF NULL NUMR Y THEN GO TO D
  2295. ELSE IF NOT DENR Y=1 OR NOT NUMBERP NUMR Y THEN GO TO C;
  2296. Y := CAR Y;
  2297. V := CDR V;
  2298. B: IF Y=0 THEN GO TO A;
  2299. U := DIFFSQ(U,X);
  2300. Y := Y-1;
  2301. GO TO B;
  2302. C: U := DIFFSQ(U,X);
  2303. GO TO A;
  2304. D: Y := NIL;
  2305. V := CDR V;
  2306. GO TO A;
  2307. EXIT:
  2308. PRINT LIST('TIME,TIME()-TT);
  2309. RETURN U;
  2310. E: MSGPRI("DIFFERENTIATION WRT",PREPSQ X,"NOT ALLOWED",NIL,T)
  2311. END;
  2312. PUT('TDF,'SIMPFN,'!-!-SIMPDF);
  2313. ENDMODULE;
  2314. MODULE TIDYSQRT;
  2315. EXPORTS SQRT2TOP;
  2316. %GENERAL TIDYING UP ABOUT SQUARE ROOTS;
  2317. %SYMBOLIC PROCEDURE TIDYSQRTDF A;
  2318. % IF NULL A THEN NIL
  2319. % ELSE BEGIN SCALAR TT,R;
  2320. % TT:=TIDYSQRT LC A;
  2321. % R:=TIDYSQRTDF RED A;
  2322. % IF NULL NUMR TT THEN RETURN R;
  2323. % RETURN ((LPOW A) .* TT) .+ R
  2324. % END;
  2325. %
  2326. %SYMBOLIC PROCEDURE TIDYSQRT Q;
  2327. % BEGIN SCALAR NN,DD;
  2328. % NN:=TIDYSQRTF NUMR Q;
  2329. % IF NULL NN THEN NIL ./ 1; %ANSWER IS ZERO;
  2330. % DD:=TIDYSQRTF DENR Q;
  2331. % RETURN MULTSQ(NN,INVSQ DD)
  2332. % END;
  2333. %
  2334. %
  2335. %SYMBOLIC PROCEDURE TIDYSQRTF P;
  2336. %%INPUT - STANDARD FORM;
  2337. %%OUTPUT - STANDARD QUOTIENT;
  2338. %% SIMPLIFIES SQRT(A)**N WITH N>1;
  2339. % IF DOMAINP P THEN P ./ 1
  2340. % ELSE BEGIN SCALAR V,W;
  2341. % V:=LPOW P;
  2342. % IF CAR V='I THEN V:=MKSP('(SQRT -1),CDR V); %I->SQRT(-1);
  2343. % IF EQCAR(CAR V,'SQRT) AND NOT ONEP CDR V THEN BEGIN SCALAR X;
  2344. % %HERE WE HAVE A REDUCTION TO APPLY;
  2345. % X:=DIVIDE(CDR V,2); %HALVE EXPONENT;
  2346. % W:=EXPTSQ(SIMP CADAR V,CAR X); %RATIONAL PART OF ANSWER;
  2347. % IF NOT ZEROP CDR X THEN W:=MULTSQ(W,
  2348. % ((MKSP(CAR V,1) .* 1) .+ NIL) ./ 1);
  2349. % %THE NEXT LINE ALLOWS FOR THE HORRORS OF NESTED SQRTS;
  2350. % W:=TIDYSQRT W
  2351. % END
  2352. % ELSE W:=((V .* 1) .+ NIL) ./ 1;
  2353. % V:=MULTSQ(W,TIDYSQRTF LC P);
  2354. % RETURN ADDSQ(V,TIDYSQRTF RED P)
  2355. % END;
  2356. %
  2357. %
  2358. %MOVE SQRTS IN A SQ TO THE NUMERATOR;
  2359. SYMBOLIC PROCEDURE MULTOUTDENR Q;
  2360. BEGIN SCALAR N,D,ROOT,CONJ;
  2361. N:=NUMR Q;
  2362. D:=DENR Q;
  2363. LOOP:ROOT:=FINDSQUAREROOT D; %SEARCH DENOM;
  2364. IF NULL ROOT THEN RETURN (N . D);
  2365. %NOTHING TO BE DONE;
  2366. CONJ:=CONJUGATEWRT(D,ROOT);
  2367. N:=!*F2POL !*MULTF!*(N,CONJ);
  2368. D:=!*F2POL !*MULTF!*(D,CONJ);
  2369. GO TO LOOP
  2370. END;
  2371. SYMBOLIC PROCEDURE SQRT2TOP Q;
  2372. BEGIN
  2373. SCALAR N,D;
  2374. N:=MULTOUTDENR Q;
  2375. D:=DENR N;
  2376. N:=NUMR N;
  2377. IF D EQ DENR Q
  2378. THEN RETURN Q;%NO CHANGE;
  2379. IF D IEQUAL 1
  2380. THEN RETURN (N ./ 1);
  2381. Q:=GCDCOEFFSOFSQRTS N;
  2382. IF Q IEQUAL 1
  2383. THEN IF MINUSF D
  2384. THEN RETURN (NEGF N ./ NEGF D)
  2385. ELSE RETURN (N ./ D);
  2386. Q:=GCDF(Q,D);
  2387. N:=QUOTF(N,Q);
  2388. D:=QUOTF(D,Q);
  2389. IF MINUSF D
  2390. THEN RETURN (NEGF N ./ NEGF D)
  2391. ELSE RETURN (N ./ D)
  2392. END;
  2393. %SYMBOLIC PROCEDURE DENRSQRT2TOP Q;
  2394. %BEGIN
  2395. % SCALAR N,D;
  2396. % N:=MULTOUTDENR Q;
  2397. % D:=DENR N;
  2398. % N:=NUMR N;
  2399. % IF D EQ DENR Q
  2400. % THEN RETURN D; %NO CHANGES;
  2401. % IF D IEQUAL 1
  2402. % THEN RETURN 1;
  2403. % Q:=GCDCOEFFSOFSQRTS N;
  2404. % IF Q IEQUAL 1
  2405. % THEN RETURN D;
  2406. % Q:=GCDF(Q,D);
  2407. % IF Q IEQUAL 1
  2408. % THEN RETURN D
  2409. % ELSE RETURN QUOTF(D,Q)
  2410. % END;
  2411. SYMBOLIC PROCEDURE FINDSQUAREROOT P;
  2412. %LOCATE A SQRT SYMBOL IN POLY P;
  2413. IF DOMAINP P THEN NIL
  2414. ELSE BEGIN SCALAR W;
  2415. W:=MVAR P; %CHECK MAIN VAR FIRST;
  2416. IF ATOM W
  2417. THEN RETURN NIL; %WE HAVE PASSED ALL SQRTS;
  2418. IF EQCAR(W,'SQRT) THEN RETURN W;
  2419. W:=FINDSQUAREROOT LC P;
  2420. IF NULL W THEN W:=FINDSQUAREROOT RED P;
  2421. RETURN W
  2422. END;
  2423. SYMBOLIC PROCEDURE CONJUGATEWRT(P,VAR);
  2424. % VAR -> -VAR IN FORM P;
  2425. IF DOMAINP P THEN P
  2426. ELSE IF MVAR P=VAR THEN BEGIN
  2427. SCALAR X,C,R;
  2428. X:=TDEG LT P; %DEGREE;
  2429. C:=LC P; %COEFFICIENT;
  2430. R:=RED P; %REDUCTUM;
  2431. X:=REMAINDER(X,2); %NOW JUST 0 OR 1;
  2432. IF X=1 THEN C:=NEGF C; %-COEFFICIENT;
  2433. RETURN (LPOW P .* C) .+ CONJUGATEWRT(R,VAR) END
  2434. ELSE IF ORDOP(VAR,MVAR P) THEN P
  2435. ELSE (LPOW P .* CONJUGATEWRT(LC P,VAR)) .+
  2436. CONJUGATEWRT(RED P,VAR);
  2437. SYMBOLIC PROCEDURE GCDCOEFFSOFSQRTS U;
  2438. IF ATOM U
  2439. THEN IF NUMBERP U AND MINUSP U
  2440. THEN -U
  2441. ELSE U
  2442. ELSE IF EQCAR(MVAR U,'SQRT)
  2443. THEN BEGIN
  2444. SCALAR V;
  2445. V:=GCDCOEFFSOFSQRTS LC U;
  2446. IF V IEQUAL 1
  2447. THEN RETURN V
  2448. ELSE RETURN GCDF(V,GCDCOEFFSOFSQRTS RED U)
  2449. END
  2450. ELSE BEGIN
  2451. SCALAR ROOT;
  2452. ROOT:=FINDSQUAREROOT U;
  2453. IF NULL ROOT
  2454. THEN RETURN U;
  2455. U:=MAKEMAINVAR(U,ROOT);
  2456. ROOT:=GCDCOEFFSOFSQRTS LC U;
  2457. IF ROOT IEQUAL 1
  2458. THEN RETURN 1
  2459. ELSE RETURN GCDF(ROOT,GCDCOEFFSOFSQRTS RED U)
  2460. END;
  2461. ENDMODULE;
  2462. MODULE TRCASE;
  2463. EXPORTS TRANSCENDENTALCASE;
  2464. IMPORTS BACKSUBST4CS,COUNTZ,CREATECMAP,CREATEINDICES,DF2Q,DFNUMR,
  2465. DIFFLOGS,FSDF,FACTORLISTLIST,FINDSQRTS,FINDTRIALDIVS,GCDF,MKVECT,
  2466. INTERR,LOGSTOSQ,MERGIN,MULTBYARBPOWERS,!*MULTF!*,MULTSQFREE,
  2467. PRINTDF,PRINTFACTORS,PRINTSQ,QUOTF,RATIONALINTEGRATE,PUTV,
  2468. SIMPINT1,SOLVE!-FOR!-U,SQFREE,SQMERGE,SQRT2TOP,SUBSTINULIST,TRIALDIV,
  2469. MERGEIN,NEGSQ,ADDSQ,F2DF,MKNILL,PNTH,INVSQ,MULTSQ,DOMAINP,MK!*SQ,
  2470. MKSP,PRETTYPRINT,PREPSQ;
  2471. FLUID '(DENBAD VAR XLOGS); % For the ERRORSET below;
  2472. SYMBOLIC
  2473. PROCEDURE TRANSCENDENTALCASE(INTEGRAND,VAR,XLOGS,ZLIST,VARLIST);
  2474. BEGIN SCALAR DIVLIST,W,JHD!-CONTENT,CONTENT,PRIM,SQFR,DFU,INDEXLIST,
  2475. % JHD!-CONTENT is local, while CONTENT is free (set in SQFREE);
  2476. SILLIESLIST,ORIGINALORDER,ORIGINALLHS,WRONGWAY,
  2477. SQRTLIST,TANLIST,LOGLIST,DFLOGS,EPRIM,DFUN,UNINTEGRAND,
  2478. SQRTFLAG,BADPART,RHS,LHS,GCDQ,CMAP,CVAL,ORDEROFELIM,CMATRIX;
  2479. SCALAR CUBEROOTFLAG,CCOUNT,DENOMINATOR,RESULT,DENBAD;
  2480. GENSYMCOUNT:=0;
  2481. INTEGRAND:=SQRT2TOP INTEGRAND; % Move the sqrts to the numerator;
  2482. IF !*TRINT THEN << PRINTC "EXTENSION VARIABLES Z<I> ARE";
  2483. PRINT ZLIST>>;
  2484. IF !*RATINTSPECIAL AND NULL CDR ZLIST THEN
  2485. RETURN RATIONALINTEGRATE(INTEGRAND,VAR);
  2486. % *** NOW UNNORMALIZE INTEGRAND, MAYBE *** ;
  2487. BEGIN SCALAR W,Z,GG;
  2488. GG:=1;
  2489. FOREACH Z IN ZLIST DO <<
  2490. W:=DIFFSQ(SIMP Z,VAR);
  2491. GG:=MULTF(GG,QUOTF(DENR W,GCDF(DENR W,GG))) >>;
  2492. GG:=QUOTF(GG,GCDF(GG,DENR INTEGRAND));
  2493. UNINTEGRAND:=(MULTF(GG,NUMR INTEGRAND)
  2494. ./ MULTF(GG,DENR INTEGRAND));
  2495. IF !*TRINT THEN <<
  2496. PRINTC "UNNORMALIZED INTEGRAND =";
  2497. PRINTSQ UNINTEGRAND >> END;
  2498. DIVLIST:=FINDTRIALDIVS ZLIST;
  2499. %ALSO PUTS SOME THINGS ON LOGLIST SOMETIMES;
  2500. % IF !*TRINT THEN << PRINTC "EXPONENTIALS AND TANS TO TRY DIVIDING:";
  2501. % PRINT DIVLIST>>;
  2502. SQRTLIST:=FINDSQRTS ZLIST;
  2503. % IF !*TRINT THEN << PRINTC "SQUARE-ROOT Z-VARIABLES";
  2504. % PRINT SQRTLIST >>;
  2505. DIVLIST:=TRIALDIV(DENR UNINTEGRAND,DIVLIST);
  2506. % IF !*TRINT THEN << PRINTC "DIVISORS:";
  2507. % PRINT CAR DIVLIST;
  2508. % PRINT CDR DIVLIST>>;
  2509. %N.B. THE NEXT LINE ALSO SETS 'CONTENT' AS A FREE VARIABLE;
  2510. % Since SQFREE may be used later, we copy it into JHD!-CONTENT;
  2511. PRIM:=SQFREE(CDR DIVLIST,ZLIST);
  2512. JHD!-CONTENT:=CONTENT;
  2513. PRINTFACTORS(PRIM,NIL);
  2514. EPRIM:=SQMERGE(COUNTZ CAR DIVLIST,PRIM,NIL);
  2515. PRINTFACTORS(EPRIM,T);
  2516. % IF !*TRINT THEN << TERPRI();
  2517. % PRINTSF DENOMINATOR;
  2518. % TERPRI();
  2519. % PRINTC "...CONTENT IS:";
  2520. % PRINTSF JHD!-CONTENT>>;
  2521. SQFR:=MULTSQFREE EPRIM;
  2522. % IF !*TRINT THEN << PRINTC "...SQFR IS:";
  2523. % SUPERPRINT SQFR>>;
  2524. INDEXLIST:=CREATEINDICES ZLIST;
  2525. % IF !*TRINT THEN << PRINTC "...INDICES ARE:";
  2526. % SUPERPRINT INDEXLIST>>;
  2527. DFU:=DFNUMR(VAR,CAR DIVLIST);
  2528. % IF !*TRINT THEN << TERPRI();
  2529. % PRINTC "************ DERIVATIVE OF U IS:";
  2530. % PRINTSQ DFU>>;
  2531. LOGLIST:=APPEND(LOGLIST,FACTORLISTLIST (PRIM,NIL));
  2532. LOGLIST:=MERGEIN(XLOGS,LOGLIST);
  2533. LOGLIST:=MERGEIN(TANLIST,LOGLIST);
  2534. CMAP:=CREATECMAP();
  2535. CCOUNT:=LENGTH CMAP;
  2536. IF !*TRINT THEN << PRINTC "LOGLIST ";
  2537. PRINT LOGLIST >>;
  2538. DFLOGS:=DIFFLOGS(LOGLIST,DENR UNINTEGRAND,VAR);
  2539. IF !*TRINT THEN << PRINTC "************ 'DERIVATIVE' OF LOGS IS:";
  2540. PRINTSQ DFLOGS>>;
  2541. DFLOGS:=ADDSQ((NUMR UNINTEGRAND) ./ 1,NEGSQ DFLOGS);
  2542. % Put everything in reduction eqn over common denominator: ;
  2543. GCDQ:=GCDF(DENR DFLOGS,DENR DFU);
  2544. DFUN:= !*F2POL !*MULTF!*(NUMR DFU,
  2545. DENBAD:=QUOTF(DENR DFLOGS,GCDQ));
  2546. DENBAD:=!*MULTF!*(DENR DFU,DENBAD);
  2547. DENBAD:= !*F2POL !*MULTF!*(DENR UNINTEGRAND,DENBAD);
  2548. DFLOGS:= !*F2POL !*MULTF!*(NUMR DFLOGS,QUOTF(DENR DFU,GCDQ));
  2549. DFU:=DFUN;
  2550. % Now DFU and DFLOGS are S.F.s;
  2551. RHS:=MULTBYARBPOWERS F2DF DFU;
  2552. IF !*TRINT THEN << PRINTC "Distributed Form of U is:";
  2553. PRINTDF RHS>>;
  2554. LHS:=F2DF DFLOGS;
  2555. IF !*TRINT THEN << PRINTC "Distributed Form of l.h.s. is:";
  2556. PRINTDF LHS;
  2557. TERPRI()>>;
  2558. CVAL:=MKVECT(CCOUNT);
  2559. FOR I:=0 : CCOUNT DO PUTV(CVAL,I,NIL ./ 1);
  2560. LORDER:=MAXORDER(RHS,ZLIST,0);
  2561. ORIGINALORDER:=LORDER;
  2562. ORIGINALLHS:=LHS;
  2563. IF !*TRINT THEN << PRINTC "Maximum order determined as ";
  2564. PRINT LORDER >>;
  2565. IF !*STATISTICS THEN << !*NUMBER!*:=0;
  2566. !*SPSIZE!*:=1;
  2567. FOREACH XX IN LORDER DO
  2568. !*SPSIZE!*:=!*SPSIZE!* * (XX+1) >>;
  2569. % That calculates the largest U that can appear;
  2570. DFUN:=SOLVE!-FOR!-U(RHS,LHS,NIL);
  2571. BACKSUBST4CS(NIL,ORDEROFELIM,CMATRIX);
  2572. % IF !*TRINT THEN IF NOT (CCOUNT=0) THEN PRINTVECSQ CVAL;
  2573. IF !*STATISTICS THEN << PRIN2 !*NUMBER!*; PRIN2 " used out of ";
  2574. PRINTC !*SPSIZE!* >>;
  2575. BADPART:=SUBSTINULIST BADPART;
  2576. %SUBSTITUTE FOR C<I> STILL IN BADPART;
  2577. DFUN:=DF2Q SUBSTINULIST DFUN;
  2578. % IF !*TRINT THEN SUPERPRINT DFUN;
  2579. RESULT:= SUBS2Q MULTSQ(DFUN,INVSQ(DENOMINATOR ./ 1));
  2580. RESULT:= SUBS2Q MULTSQ(RESULT,INVSQ(JHD!-CONTENT ./ 1));
  2581. % IF !*TRINT THEN SUPERPRINT RESULT;
  2582. DFLOGS:=LOGSTOSQ();
  2583. IF NOT NULL NUMR DFLOGS
  2584. THEN RESULT:=ADDSQ(RESULT,DFLOGS);
  2585. IF !*TRINT THEN << SUPERPRINT RESULT;
  2586. TERPRI();
  2587. PRINTC
  2588. "*****************************************************";
  2589. PRINTC
  2590. "************ THE INTEGRAL IS : **********************";
  2591. PRINTC
  2592. "*****************************************************";
  2593. TERPRI();
  2594. PRINTSQ RESULT;
  2595. TERPRI()>>;
  2596. IF NOT NULL BADPART THEN <<
  2597. IF !*TRINT THEN PRINTC "PLUS A BAD PART";
  2598. LHS:=BADPART;
  2599. LORDER:=MAXORDER(RHS,ZLIST,0);
  2600. WHILE LORDER DO <<
  2601. IF CAR LORDER > CAR ORIGINALORDER THEN
  2602. WRONGWAY:=T;
  2603. LORDER:=CDR LORDER;
  2604. ORIGINALORDER:=CDR ORIGINALORDER >>;
  2605. DFUN:=DF2Q BADPART;
  2606. IF !*TRINT
  2607. THEN <<PRINTSQ DFUN; PRINTC "DENBAD = "; PRINTSF DENBAD>>;
  2608. DFUN:= SUBS2Q MULTSQ(DFUN,INVSQ(DENBAD ./ 1));
  2609. IF WRONGWAY THEN << RESULT:= NIL ./ 1; DFUN:=INTEGRAND >>;
  2610. IF ROOTCHECKP(UNINTEGRAND,VAR) THEN
  2611. RETURN SIMPINT1(INTEGRAND . VAR.NIL)
  2612. ELSE IF !*PURERISCH OR ALLOWEDFNS ZLIST THEN
  2613. DFUN:=SIMPINT1 (DFUN . VAR.NIL)
  2614. ELSE << !*PURERISCH:=T;
  2615. IF !*TRINT
  2616. THEN <<PRINTC " [Transforming ..."; PRINTSQ DFUN>>;
  2617. DENBAD:=TRANSFORM(DFUN,VAR);
  2618. IF DENBAD=DFUN
  2619. THEN DFUN:=SIMPINT1(DFUN . VAR.NIL)
  2620. ELSE <<DENBAD:=ERRORSET('(INTEGRATESQ DENBAD VAR XLOGS),
  2621. NIL,!*BACKTRACE);
  2622. IF NOT ATOM DENBAD THEN DFUN:=UNTAN CAR DENBAD
  2623. ELSE DFUN:=SIMPINT1(DFUN . VAR.NIL) >> >>;
  2624. IF !*TRINT THEN PRINTSQ DFUN;
  2625. IF !*FAILHARD THEN INTERR "FAILHARD SWITCH SET";
  2626. RESULT:=ADDSQ(RESULT,DFUN) >>;
  2627. % IF !*OVERLAYMODE
  2628. % THEN EXCISE TRANSCODE;
  2629. RETURN SQRT2TOP RESULT
  2630. END;
  2631. %UNFLUID '(DFUN VAR XLOGS);
  2632. ENDMODULE;
  2633. MODULE HALFANGLE;
  2634. EXPORTS HALFANGLE,UNTAN;
  2635. SYMBOLIC PROCEDURE TRANSFORM(U,X);
  2636. % Transform the SQ U to remove the 'bad' functions sin, cos, cot etc
  2637. % in favor of half angles;
  2638. HALFANGLE(U,X);
  2639. % Rest of this page is due to Harrington;
  2640. %PROCEDURES FOR CONVERSION TO HALF ANGLE TANGENTS;
  2641. % SOME NEWRED PROCEDURES THAT IM USED TO;
  2642. SYMBOLIC PROCEDURE QUOTQQ(U1,V1);
  2643. MULTSQ(U1, INVSQ(V1));
  2644. SYMBOLIC PROCEDURE !*SUBTRQ(U1,V1);
  2645. ADDSQ(U1, NEGSQ(V1));
  2646. SYMBOLIC PROCEDURE !*INT2QM(U1);
  2647. IF U1=0 THEN NIL . 1 ELSE U1 . 1;
  2648. SYMBOLIC PROCEDURE HALFANGLE(R,X);
  2649. % TOP LEVEL PROCEDURE FOR CONVERTING;
  2650. % R IS A RATIONAL EXPRESSION TO BE CONVERTED,
  2651. % X THE INTEGRATION VARIABLE;
  2652. % A RATIONAL EXPRESSION IS RETURNED;
  2653. QUOTQQ(HFAGLF(NUMR(R),X), HFAGLF(DENR(R),X));
  2654. SYMBOLIC PROCEDURE HFAGLF(P,X);
  2655. % CONVERTING POLYNOMIALS, A RATIONAL EXPRESSION IS RETURNED;
  2656. IF DOMAINP(P) THEN !*F2Q(P)
  2657. ELSE SUBS2Q ADDSQ(MULTSQ(EXPTSQ(HFAGLK(MVAR(P),X), LDEG(P)),
  2658. HFAGLF(LC(P),X)),
  2659. HFAGLF(RED(P),X));
  2660. SYMBOLIC PROCEDURE HFAGLK(K,X);
  2661. % CONVERTING KERNELS, A RATIONAL EXPRESSION IS RETURNED;
  2662. BEGIN
  2663. SCALAR KT;
  2664. IF ATOM K OR NOT MEMBER(X,FLATTEN(CDR(K))) THEN RETURN !*K2Q K;
  2665. K := CAR(K) . HFAGLARGS(CDR(K), X);
  2666. KT := SIMP LIST('TAN, LIST('QUOTIENT, CADR(K), 2));
  2667. RETURN IF CAR(K) = 'SIN
  2668. THEN QUOTQQ(MULTSQ(!*INT2QM(2),KT), ADDSQ(!*INT2QM(1),
  2669. EXPTSQ(KT,2)))
  2670. ELSE IF CAR(K) = 'COS
  2671. THEN QUOTQQ(!*SUBTRQ(!*INT2QM(1), EXPTSQ(KT,2)), ADDSQ(!*INT2QM(1),
  2672. EXPTSQ(KT,2)))
  2673. ELSE IF CAR(K) = 'TAN
  2674. THEN QUOTQQ(MULTSQ(!*INT2QM(2),KT), !*SUBTRQ(!*INT2QM(1),
  2675. EXPTSQ(KT,2)))
  2676. ELSE IF CAR(K) = 'SINH THEN
  2677. QUOTQQ(!*SUBTRQ(EXPTSQ(!*K2Q('EXPT.('E. CDR K)),2),
  2678. !*INT2QM(1)), MULTSQ(!*INT2QM(2), !*K2Q('EXPT . ('E . CDR(K)))))
  2679. ELSE IF CAR(K) = 'COSH THEN
  2680. QUOTQQ(ADDSQ(EXPTSQ(!*K2Q('EXPT.('E. CDR K)),2),
  2681. !*INT2QM(1)), MULTSQ(!*INT2QM(2), !*K2Q('EXPT . ('E . CDR(K)))))
  2682. ELSE IF CAR(K) = 'TANH THEN
  2683. QUOTQQ(!*SUBTRQ(EXPTSQ(!*K2Q('EXPT.('E. CDR K)),2),
  2684. !*INT2QM(1)), ADDSQ(EXPTSQ(!*K2Q ('EXPT.('E.CDR(K))),2),
  2685. !*INT2QM(1)))
  2686. ELSE !*K2Q(K); % ADDITIONAL TRANSFORMATION MIGHT BE ADDED HERE;
  2687. END;
  2688. SYMBOLIC PROCEDURE HFAGLARGS(L,X);
  2689. %CONVERSION OF ARGUMENT LIST;
  2690. IF NULL L THEN NIL
  2691. ELSE PREPSQ(HFAGLK(CAR(L),X)) . HFAGLARGS(CDR(L), X);
  2692. SYMBOLIC PROCEDURE UNTANF X;
  2693. BEGIN SCALAR Y,Z,W;
  2694. IF DOMAINP X THEN RETURN X . 1;
  2695. Y := MVAR X;
  2696. IF EQCAR(Y,'INT) THEN ERROR(99,NIL); %assume all is hopeless;
  2697. Z := LDEG X;
  2698. W := 1 . 1;
  2699. Y :=
  2700. IF ATOM Y THEN !*K2Q Y
  2701. ELSE IF CAR Y EQ 'TAN
  2702. THEN IF REMAINDER(Z,2)=0
  2703. THEN <<Z := Z/2;
  2704. SIMP LIST('QUOTIENT,
  2705. LIST('PLUS,
  2706. LIST('MINUS,
  2707. LIST('COS,
  2708. 'TIMES
  2709. . (2 . CDR Y))),
  2710. 1),LIST('PLUS,
  2711. LIST('COS,
  2712. 'TIMES
  2713. . (2 . CDR Y)),
  2714. 1))>>
  2715. ELSE IF Z=1
  2716. THEN SIMP LIST('QUOTIENT,
  2717. LIST('PLUS,
  2718. LIST('MINUS,
  2719. LIST('COS,
  2720. 'TIMES . (2 . CDR Y))),
  2721. 1),LIST('SIN,
  2722. 'TIMES . (2 . CDR Y)))
  2723. ELSE <<Z := (Z - 1)/2;
  2724. W :=
  2725. SIMP LIST('QUOTIENT,
  2726. LIST('PLUS,
  2727. LIST('MINUS,
  2728. LIST('COS,
  2729. 'TIMES
  2730. . (2 . CDR Y))),
  2731. 1),LIST('SIN,
  2732. 'TIMES
  2733. . (2 . CDR Y)));
  2734. SIMP LIST('QUOTIENT,
  2735. LIST('PLUS,
  2736. LIST('MINUS,
  2737. LIST('COS,
  2738. 'TIMES
  2739. . (2 . CDR Y))),
  2740. 1),LIST('PLUS,
  2741. LIST('COS,
  2742. 'TIMES
  2743. . (2 . CDR Y)),
  2744. 1))>>
  2745. ELSE SIMP Y;
  2746. RETURN ADDSQ(MULTSQ(MULTSQ(EXPTSQ(Y,Z),UNTANF LC X),W),
  2747. UNTANF RED X)
  2748. END;
  2749. SYMBOLIC PROCEDURE UNTANLIST(Y);
  2750. IF NULL Y THEN NIL ELSE (PREPSQ (UNTAN(SIMP CAR Y)) . UNTANLIST(CDR Y));
  2751. SYMBOLIC PROCEDURE UNTAN(X);
  2752. COMMENT EXPECTS X TO BE CANONICAL QUOTIENT;
  2753. BEGIN SCALAR Y;
  2754. Y:=COSSQCHK SINSQRDCHK MULTSQ(UNTANF(NUMR X), INVSQ UNTANF(DENR X));
  2755. RETURN IF LENGTH FLATTEN Y>LENGTH FLATTEN X THEN X ELSE Y
  2756. END;
  2757. SYMBOLIC PROCEDURE SINSQRDCHK(X);
  2758. MULTSQ(SINSQCHKF(NUMR X), INVSQ SINSQCHKF(DENR X));
  2759. SYMBOLIC PROCEDURE SINSQCHKF(X);
  2760. BEGIN
  2761. SCALAR Y,Z,W;
  2762. IF DOMAINP X THEN RETURN X . 1;
  2763. Y := MVAR X;
  2764. Z := LDEG X;
  2765. W := 1 . 1;
  2766. Y := IF EQCAR(Y,'SIN) THEN IF REMAINDER(Z,2) = 0
  2767. THEN <<Z := QUOTIENT(Z,2);
  2768. SIMP LIST('PLUS,1,LIST('MINUS,
  2769. LIST('EXPT,('COS . CDR(Y)),2)))>>
  2770. ELSE IF Z = 1 THEN !*K2Q Y
  2771. ELSE << Z := QUOTIENT(DIFFERENCE(Z,1),2); W := !*K2Q Y;
  2772. SIMP LIST('PLUS,1,LIST('MINUS,
  2773. LIST('EXPT,('COS . CDR(Y)),2)))>>
  2774. ELSE !*K2Q Y;
  2775. RETURN ADDSQ(MULTSQ(MULTSQ(EXPTSQ(Y,Z),SINSQCHKF(LC X)),W),
  2776. SINSQCHKF(RED X));
  2777. END;
  2778. SYMBOLIC PROCEDURE COSSQCHKF(X);
  2779. BEGIN
  2780. SCALAR Y,Z,W,X1,X2;
  2781. IF DOMAINP X THEN RETURN X . 1;
  2782. Y := MVAR X;
  2783. Z := LDEG X;
  2784. W := 1 . 1;
  2785. X1 := COSSQCHKF(LC X);
  2786. X2 := COSSQCHKF(RED X);
  2787. X := ADDSQ(MULTSQ(!*P2Q LPOW X,X1),X2);
  2788. Y := IF EQCAR(Y,'COS) THEN IF REMAINDER(Z,2) = 0
  2789. THEN <<Z := QUOTIENT(Z,2);
  2790. SIMP LIST('PLUS,1,LIST('MINUS,
  2791. LIST('EXPT,('SIN . CDR(Y)),2)))>>
  2792. ELSE IF Z = 1 THEN !*K2Q Y
  2793. ELSE << Z := QUOTIENT(DIFFERENCE(Z,1),2); W := !*K2Q Y;
  2794. SIMP LIST('PLUS,1,LIST('MINUS,
  2795. LIST('EXPT,('SIN . CDR(Y)),2)))>>
  2796. ELSE !*K2Q Y;
  2797. Y := ADDSQ(MULTSQ(MULTSQ(EXPTSQ(Y,Z),W),X1),X2);
  2798. RETURN IF LENGTH(Y) > LENGTH(X) THEN X ELSE Y;
  2799. END;
  2800. SYMBOLIC PROCEDURE COSSQCHK(X);
  2801. BEGIN
  2802. SCALAR GCD1;
  2803. GCD1 := !*GCD;
  2804. !*GCD := T;
  2805. X := MULTSQ(COSSQCHKF(NUMR X), INVSQ COSSQCHKF(DENR X));
  2806. !*GCD := GCD1;
  2807. RETURN X;
  2808. END;
  2809. SYMBOLIC PROCEDURE LROOTCHK(L,X);
  2810. % CHECKS EACH MEMBER OF LIST L FOR A ROOT;
  2811. IF NULL L THEN NIL ELSE KROOTCHK(CAR L, X) OR LROOTCHK(CDR L, X);
  2812. SYMBOLIC PROCEDURE KROOTCHK(F,X);
  2813. % CHECKS A KERNEL TO SEE IF IT IS A ROOT;
  2814. IF ATOM F THEN NIL
  2815. ELSE IF CAR(F) = 'SQRT
  2816. AND MEMBER(X, FLATTEN CDR F) THEN T
  2817. ELSE IF CAR(F) = 'EXPT
  2818. AND NOT ATOM CADDR(F)
  2819. AND CAADDR(F) = 'QUOTIENT
  2820. AND MEMBER(X, FLATTEN CADR F) THEN T
  2821. ELSE LROOTCHK(CDR F, X);
  2822. SYMBOLIC PROCEDURE ROOTCHK1P(F,X);
  2823. % CHECKS POLYNOMIAL FOR A ROOT;
  2824. IF DOMAINP F THEN NIL
  2825. ELSE KROOTCHK(MVAR F,X) OR ROOTCHK1P(LC F, X) OR ROOTCHK1P(RED F, X);
  2826. SYMBOLIC PROCEDURE ROOTCHECKP(F,X);
  2827. % CHECKS RATIONAL (STANDARD QUOTIENT) FOR A ROOT;
  2828. ROOTCHK1P(NUMR F, X) OR ROOTCHK1P(DENR F, X);
  2829. ENDMODULE;
  2830. MODULE TRIALDIV;
  2831. EXPORTS COUNTZ,FINDSQRTS,FINDTRIALDIVS,PRINTFACTORS,TRIALDIV,SIMP,MKSP;
  2832. IMPORTS !*MULTF!*,PRINTSF,QUOTF;
  2833. SYMBOLIC PROCEDURE COUNTZ DL;
  2834. % DL is a list of S.F.s;
  2835. BEGIN SCALAR S,N,RL;
  2836. LOOP2: IF NULL DL THEN RETURN ARRANGELISTZ RL;
  2837. N:=1;
  2838. LOOP1: N:=N+1;
  2839. S:=CAR DL;
  2840. DL:=CDR DL;
  2841. IF NOT NULL DL AND (S EQ CAR DL) THEN
  2842. GO TO LOOP1
  2843. ELSE RL:=(S.N).RL;
  2844. GO TO LOOP2
  2845. END;
  2846. SYMBOLIC PROCEDURE ARRANGELISTZ D;
  2847. BEGIN SCALAR N,S,RL,R;
  2848. N:=1;
  2849. IF NULL D THEN RETURN RL;
  2850. LOOPD: IF (CDAR D)=N THEN S:=(CAAR D).S
  2851. ELSE R:=(CAR D).R;
  2852. D:=CDR D;
  2853. IF NOT NULL D THEN GO TO LOOPD;
  2854. D:=R;
  2855. RL:=S.RL;
  2856. S:=NIL;
  2857. R:=NIL;
  2858. N:=N+1;
  2859. IF NOT NULL D THEN GO TO LOOPD;
  2860. RETURN REVERSEWOC RL
  2861. END;
  2862. SYMBOLIC PROCEDURE PRINTFACTORS(W,PRDENOM);
  2863. % W is a list of factors to each power. If PRDENOM is true ;
  2864. % this prints denominator of answer, else prints square-free ;
  2865. % decomposition. ;
  2866. BEGIN SCALAR I,WX;
  2867. I:=1;
  2868. IF PRDENOM THEN <<
  2869. DENOMINATOR:=1;
  2870. IF !*TRINT
  2871. THEN PRINTC "DENOMINATOR OF 1ST PART OF ANSWER IS:";
  2872. IF NOT NULL W THEN W:=CDR W >>;
  2873. LOOPX: IF W=NIL THEN RETURN;
  2874. IF !*TRINT THEN PRINTC ("FACTORS OF MULTIPLICITY".I);
  2875. WX:=CAR W;
  2876. WHILE NOT NULL WX DO <<
  2877. IF !*TRINT THEN PRINTSF CAR WX;
  2878. FOR J:=1 : I DO
  2879. DENOMINATOR:= !*F2POL !*MULTF!*(CAR WX,DENOMINATOR);
  2880. %this call of F2POL is probably not necessary??;
  2881. WX:=CDR WX >>;
  2882. I:=I+1;
  2883. W:=CDR W;
  2884. GO TO LOOPX
  2885. END;
  2886. SYMBOLIC PROCEDURE FINDTRIALDIVS ZL;
  2887. %ZL IS LIST OF KERNELS FOUND IN INTEGRAND. RESULT IS A LIST;
  2888. %GIVING THINGS TO BE TREATED SPECIALLY IN THE INTEGRATION;
  2889. %VIZ: EXPS AND TANS;
  2890. %RESULT IS LIST OF FORM ((A . B) ...);
  2891. % WITH A A KERNEL AND CAR A=EXPT OR TAN;
  2892. % AND B A STANDARD FORM FOR EITHER EXPT OR (1+TAN**2);
  2893. BEGIN SCALAR DLISTS1,ARGS1;
  2894. WHILE NOT NULL ZL DO <<
  2895. IF EXPORTAN CAR ZL THEN <<
  2896. IF CAAR ZL='TAN
  2897. THEN << ARGS1:=(MKSP(CAR ZL,2) .* 1) .+ 1;
  2898. TANLIST:=(ARGS1 ./ 1) . TANLIST>>
  2899. ELSE ARGS1:=!*K2F CAR ZL;
  2900. DLISTS1:=(CAR ZL . ARGS1) . DLISTS1>>;
  2901. ZL:=CDR ZL >>;
  2902. RETURN DLISTS1
  2903. END;
  2904. SYMBOLIC PROCEDURE EXPORTAN DL;
  2905. IF ATOM DL THEN NIL
  2906. ELSE BEGIN
  2907. % EXTRACT EXP OR TAN FNS FROM THE Z-LIST;
  2908. IF EQ(CAR DL,'TAN) THEN RETURN T;
  2909. NXT: IF NOT EQ(CAR DL,'EXPT) THEN RETURN NIL;
  2910. DL:=CADR DL;
  2911. IF ATOM DL THEN RETURN T;
  2912. GO TO NXT
  2913. END;
  2914. SYMBOLIC PROCEDURE FINDSQRTS Z;
  2915. BEGIN SCALAR R;
  2916. WHILE NOT NULL Z DO <<
  2917. IF EQCAR(CAR Z,'SQRT) THEN R:=(CAR Z) . R;
  2918. Z:=CDR Z >>;
  2919. RETURN R
  2920. END;
  2921. SYMBOLIC PROCEDURE TRIALDIV(X,DL);
  2922. BEGIN SCALAR QLIST,Q;
  2923. WHILE NOT NULL DL DO
  2924. IF NOT NULL(Q:=QUOTF(X,CDAR DL)) THEN <<
  2925. IF (CAAAR DL='TAN) AND NOT EQCAR(QLIST,CDAR DL) THEN
  2926. LOGLIST:=('IDEN . SIMP CADR CAAR DL) . LOGLIST;
  2927. %TAN FIDDLE!;
  2928. QLIST:=(CDAR DL).QLIST;
  2929. X:=Q >>
  2930. ELSE DL:=CDR DL;
  2931. RETURN QLIST.X
  2932. END;
  2933. ENDMODULE;
  2934. MODULE UNIFAC;
  2935. EXPORTS EVALAT,LINETHROUGH,QUADTHROUGH,TESTDIV,UNIFAC,ZFACTORS;
  2936. IMPORTS CUBIC,LINFAC,PRINTDF,QUADFAC,QUADRATIC,QUARTIC,VP1,ZFACTOR,
  2937. GCD,MINUSP,PRETTYPRINT;
  2938. %UNIVARIATE FACTORIZATION FOR INTEGRATION;
  2939. SYMBOLIC PROCEDURE ZFACTORS N;
  2940. %PRODUCES A LIST OF ALL (POSITIVE) INTEGER FACTORS OF THE ;
  2941. %INTEGER N;
  2942. IF N=0 THEN LIST 0
  2943. ELSE IF (N:=ABS N)=1 THEN LIST 1
  2944. ELSE COMBINATIONTIMES ZFACTOR N;
  2945. SYMBOLIC PROCEDURE ZFACTOR N;
  2946. % INPUT N A POSITIVE INTEGER;
  2947. % OUTPUT A LIST ((PRIME . EXPONENT) ...) GIVING FACTORS OF N;
  2948. BEGIN SCALAR FL,Q,W,C;
  2949. C:=0; %MULTIPLICITY;
  2950. TRY2: Q:=DIVIDE(N,2); %PULL OUT FACTORS OF 2;
  2951. IF ZEROP CDR Q THEN <<
  2952. C:=C+1;
  2953. N:=CAR Q;
  2954. GO TO TRY2 >>;
  2955. IF NOT ZEROP C THEN FL:=(2 . C) . FL;
  2956. W:=3; C:=0;
  2957. TRYW: Q:=DIVIDE(N,W);
  2958. IF ZEROP CDR Q THEN <<
  2959. C:=C+1;
  2960. N:=CAR Q;
  2961. GO TO TRYW >>;
  2962. IF NOT ZEROP C THEN FL:=(W . C) . FL;
  2963. IF REMAINDER(W,3)=1 THEN W:=W+4
  2964. ELSE W:=W+2;
  2965. C:=0;
  2966. IF NOT ((W*W)>N) THEN GO TO TRYW;
  2967. IF NOT ONEP N THEN FL:=(N . 1) . FL;
  2968. RETURN FL
  2969. END;
  2970. SYMBOLIC PROCEDURE COMBINATIONTIMES FL;
  2971. IF NULL FL THEN LIST 1
  2972. ELSE BEGIN SCALAR N,C,RES,PR;
  2973. N:=CAAR FL; C:=CDAR FL;
  2974. PR:=COMBINATIONTIMES CDR FL;
  2975. WHILE NOT MINUSP C DO <<
  2976. RES:=PUTIN(EXPT(N,C),PR,RES);
  2977. C:=C-1 >>;
  2978. RETURN RES
  2979. END;
  2980. SYMBOLIC PROCEDURE PUTIN(N,L,W);
  2981. IF NULL L THEN W
  2982. ELSE PUTIN(N,CDR L,(N*CAR L) . W);
  2983. SYMBOLIC PROCEDURE UNIFAC(POL,VAR,DEGREE,RES);
  2984. BEGIN SCALAR W,Q,C;
  2985. W:=POL;
  2986. IF !*TRINT THEN SUPERPRINT W;
  2987. %NOW TRY LOOKING FOR LINEAR FACTORS;
  2988. TRYLIN: Q:=LINFAC(W);
  2989. IF NULL CAR Q THEN GO TO NOMORELIN;
  2990. RES := ('LOG . BACK2DF(CAR Q,VAR)) . RES;
  2991. W:=CDR Q;
  2992. GO TO TRYLIN;
  2993. NOMORELIN:
  2994. Q:=QUADFAC(W);
  2995. IF NULL CAR Q THEN GO TO NOMOREQUAD;
  2996. RES := QUADRATIC(BACK2DF(CAR Q,VAR),VAR,RES);
  2997. W:=CDR Q;
  2998. GO TO NOMORELIN;
  2999. NOMOREQUAD:
  3000. IF NULL W THEN RETURN RES; %ALL DONE;
  3001. DEGREE:=CAR W; %DEGREE OF WHAT IS LEFT;
  3002. C:=BACK2DF(W,VAR);
  3003. IF DEGREE=3 THEN RES:=CUBIC(C,VAR,RES)
  3004. ELSE IF DEGREE=4 THEN RES:=QUARTIC(C,VAR,RES)
  3005. ELSE IF ZEROP REMAINDER(DEGREE,2) AND
  3006. PAIRP (Q := HALFPOWER CDDR W)
  3007. THEN <<W := (DEGREE/2) . (CADR W . Q);
  3008. W := UNIFAC(W,VAR,CAR W,NIL);
  3009. RES := PLUCKFACTORS(W,VAR,RES)>>
  3010. ELSE <<
  3011. PRINTC "THE FOLLOWING HAS NOT BEEN SPLIT";
  3012. PRINTDF C;
  3013. RES:=('LOG . C) . RES>>;
  3014. RETURN RES
  3015. END;
  3016. SYMBOLIC PROCEDURE HALFPOWER W;
  3017. IF NULL W THEN NIL
  3018. ELSE IF CAR W=0
  3019. THEN (LAMBDA R;
  3020. IF R EQ 'FAILED THEN R ELSE CADR W . R) HALFPOWER CDDR W
  3021. ELSE 'FAILED;
  3022. SYMBOLIC PROCEDURE PLUCKFACTORS(W,VAR,RES);
  3023. BEGIN SCALAR S,P,Q,R,KNOWNDISCRIMSIGN;
  3024. WHILE W DO
  3025. <<P := CAR W;
  3026. IF CAR P EQ 'ATAN THEN NIL
  3027. ELSE IF CAR P EQ 'LOG
  3028. THEN <<Q := DOUBLEPOWER CDR P . Q;
  3029. %PRIN2 "Q="; %PRINTDF CAR Q;
  3030. >>
  3031. ELSE INTERR "BAD FORM";
  3032. W := CDR W>>;
  3033. WHILE Q DO
  3034. <<P := CAR Q;
  3035. IF CAAAR P=4
  3036. THEN <<KNOWNDISCRIMSIGN := 'NEGATIVE;
  3037. RES := QUARTIC(P,VAR,RES);
  3038. KNOWNDISCRIMSIGN := NIL>>
  3039. ELSE IF CAAAR P=2
  3040. THEN RES := QUADRATIC(P,VAR,RES)
  3041. ELSE RES := ('LOG . P) . RES;
  3042. Q := CDR Q>>;
  3043. RETURN RES
  3044. END;
  3045. SYMBOLIC PROCEDURE DOUBLEPOWER R;
  3046. IF NULL R THEN NIL
  3047. ELSE (LIST(2*CAAAR R) . CDAR R) . DOUBLEPOWER CDR R;
  3048. SYMBOLIC PROCEDURE BACK2DF(P,V);
  3049. %UNDO THE EFFECT OF UNIFORM;
  3050. BEGIN SCALAR R,N;
  3051. N:=CAR P;
  3052. P:=CDR P;
  3053. WHILE NOT MINUSP N DO <<
  3054. IF NOT ZEROP CAR P THEN R:=
  3055. (VP1(V,N,ZLIST) .* (CAR P ./ 1)) .+ R;
  3056. P:=CDR P;
  3057. N:=N-1 >>;
  3058. RETURN REVERSEWOC R
  3059. END;
  3060. SYMBOLIC PROCEDURE EVALAT(P,N);
  3061. %EVALUATE POLYNOMIAL AT INTEGER POINT N;
  3062. BEGIN SCALAR R;
  3063. R:=0;
  3064. P:=CDR P;
  3065. WHILE NOT NULL P DO <<
  3066. R:=N*R+CAR P;
  3067. P:=CDR P >>;
  3068. RETURN R
  3069. END;
  3070. SYMBOLIC PROCEDURE TESTDIV(A,B);
  3071. % QUOTIENT A/B OR FAILED;
  3072. BEGIN SCALAR Q;
  3073. Q:=TESTDIV1(CDR A,CAR A,CDR B,CAR B);
  3074. IF Q='FAILED THEN RETURN Q;
  3075. RETURN (CAR A-CAR B) . Q
  3076. END;
  3077. SYMBOLIC PROCEDURE TESTDIV1(A,DA,B,DB);
  3078. IF DA<DB THEN BEGIN
  3079. CHECK0: IF NULL A THEN RETURN NIL
  3080. ELSE IF NOT ZEROP CAR A THEN RETURN 'FAILED;
  3081. A:=CDR A;
  3082. GO TO CHECK0
  3083. END
  3084. ELSE BEGIN SCALAR Q;
  3085. Q:=DIVIDE(CAR A,CAR B);
  3086. IF ZEROP CDR Q THEN Q:=CAR Q
  3087. ELSE RETURN 'FAILED;
  3088. A:=TESTDIV1(AMBQ(CDR A,CDR B,Q),DA-1,B,DB);
  3089. IF A='FAILED THEN RETURN A;
  3090. RETURN Q . A
  3091. END;
  3092. SYMBOLIC PROCEDURE AMBQ(A,B,Q);
  3093. % A-B*Q WITH Q AN INTEGER;
  3094. IF NULL B THEN A
  3095. ELSE ((CAR A)-(CAR B)*Q) . AMBQ(CDR A,CDR B,Q);
  3096. SYMBOLIC PROCEDURE LINETHROUGH(Y0,Y1);
  3097. BEGIN SCALAR A;
  3098. A:=Y1-Y0;
  3099. IF ZEROP A THEN RETURN 'FAILED;
  3100. IF A<0 THEN <<A:=-A; Y0:=-Y0 >>;
  3101. IF ONEP GCDN(A,Y0) THEN RETURN LIST(1,A,Y0);
  3102. RETURN 'FAILED
  3103. END;
  3104. SYMBOLIC PROCEDURE QUADTHROUGH(YM1,Y0,Y1);
  3105. BEGIN SCALAR A,B,C;
  3106. A:=DIVIDE(YM1+Y1,2);
  3107. IF ZEROP CDR A THEN A:=(CAR A)-Y0
  3108. ELSE RETURN 'FAILED;
  3109. IF ZEROP A THEN RETURN 'FAILED; %LINEAR THINGS ALREADY DONE;
  3110. C:=Y0;
  3111. B:=DIVIDE(Y1-YM1,2);
  3112. IF ZEROP CDR B THEN B:=CAR B
  3113. ELSE RETURN 'FAILED;
  3114. IF NOT ONEP GCDN(A,GCD(B,C)) THEN RETURN 'FAILED;
  3115. IF A<0 THEN <<A:=-A; B:=-B; C:=-C>>;
  3116. RETURN LIST(2,A,B,C)
  3117. END;
  3118. ENDMODULE;
  3119. MODULE UNIFORM;
  3120. EXPORTS UNIFORM;
  3121. IMPORTS EXPONENTOF;
  3122. SYMBOLIC PROCEDURE UNIFORM(P,V);
  3123. %CONVERT FROM D.F. IN ONE VARIABLE (V) TO A SIMPLE LIST OF;
  3124. %COEFFS (WITH DEGREE CONSED ONTO FRONT);
  3125. %FAILS IF COEFFICIENTS ARE NOT ALL SIMPLE INTEGERS;
  3126. IF NULL P THEN 0 . (0 . NIL)
  3127. ELSE BEGIN SCALAR A,B,C,D;
  3128. A:=EXPONENTOF(V,LPOW P,ZLIST);
  3129. B:=LC P;
  3130. IF NOT ONEP DENR B THEN RETURN 'FAILED;
  3131. B:=NUMR B;
  3132. IF NULL B THEN B:=0
  3133. ELSE IF NOT NUMBERP B THEN RETURN 'FAILED;
  3134. IF A=0 THEN RETURN A . (B . NIL); %CONSTANT TERM;
  3135. C:=UNIFORM(RED P,V);
  3136. IF C='FAILED THEN RETURN 'FAILED;
  3137. D:=CAR C;
  3138. C:=CDR C;
  3139. D:=D+1;
  3140. WHILE NOT (A=D) DO <<
  3141. C:=0 . C;
  3142. D:=D+1>>;
  3143. RETURN A . (B . C)
  3144. END;
  3145. ENDMODULE;
  3146. MODULE MAKEVARS;
  3147. EXPORTS GETVARIABLES,VARSINLIST,VARSINSQ,VARSINSF,FINDZVARS,
  3148. CREATEINDICES,MERGEIN;
  3149. IMPORTS DEPENDSP,UNION;
  3150. % Note that 'i' is already maybe committed for sqrt(-1);
  3151. %also 'l' and 'o' are not used as the print badly on certain;
  3152. %terminals etc and may lead to confusion;
  3153. !*GENSYMLIST!* := '(! j ! k ! l ! m ! n ! o ! p ! q ! r ! s
  3154. ! t ! u ! v ! w ! x ! y ! z);
  3155. %MAPC(!*GENSYMLIST!*,FUNCTION REMOB); %REMOB protection;
  3156. SYMBOLIC PROCEDURE VARSINLIST(L,VL);
  3157. %L IS A LIST OF S.Q. - FIND ALL VARIABLES MENTIONED;
  3158. %GIVEN THAL VL IS A LIST ALREADY KNOWN ABOUT;
  3159. BEGIN WHILE NOT NULL L DO <<
  3160. VL:=VARSINSF(NUMR CAR L,VARSINSF(DENR CAR L,VL));
  3161. L:=CDR L >>;
  3162. RETURN VL
  3163. END;
  3164. SYMBOLIC PROCEDURE GETVARIABLES SQ;
  3165. VARSINSF(NUMR SQ,VARSINSF(DENR SQ,NIL));
  3166. SYMBOLIC PROCEDURE VARSINSF(FORM,L);
  3167. IF ATOM FORM THEN L
  3168. ELSE BEGIN
  3169. WHILE NOT ATOM FORM DO <<
  3170. L:=VARSINSF(LC FORM,UNION(L,LIST MVAR FORM));
  3171. FORM:=RED FORM >>;
  3172. RETURN L
  3173. END;
  3174. SYMBOLIC PROCEDURE FINDZVARS(VL,ZL,VAR,FLG);
  3175. BEGIN SCALAR V;
  3176. % VL is the crude list of variables found in the original integrand;
  3177. % ZL must have merged into it all EXP, LOG etc terms from this;
  3178. % If FLG is true then ignore DF as a function;
  3179. SCAN: IF NULL VL THEN RETURN ZL;
  3180. V:=CAR VL; % NEXT VARIABLE;
  3181. VL:=CDR VL;
  3182. % at present items get put onto ZL if they are non-atomic;
  3183. % and they depend on the main variable. The arguments of;
  3184. % functions are decomposed by recursive calls to findzvar;
  3185. %give up if V has been declared dependent on other things;
  3186. IF ASSOC(V,DEPL!*) THEN ERROR1()
  3187. ELSE IF NOT ATOM V AND (NOT V MEMBER ZL) AND DEPENDSP(V,VAR)
  3188. THEN IF CAR V MEMQ '(TIMES QUOTIENT PLUS MINUS DIFFERENCE INT)
  3189. OR (((CAR V) EQ 'EXPT) AND FIXP CADDR V)
  3190. THEN
  3191. ZL:=FINDZVARS(CDR V,ZL,VAR,FLG)
  3192. ELSE IF FLG AND CAR V='DF THEN
  3193. << !*PURERISCH:=T; RETURN ZL >> % TRY AND STOP IT;
  3194. ELSE ZL:=V.FINDZVARS(CDR V,ZL,VAR,FLG);
  3195. % SCAN ARGUMENTS OF FN;
  3196. GO TO SCAN
  3197. END;
  3198. SYMBOLIC PROCEDURE CREATEINDICES ZL;
  3199. % Produces a list of unique indices, each associated with a ;
  3200. % different Z-variable;
  3201. REVERSEWOC CRINDEX1(ZL,!*GENSYMLIST!*);
  3202. SYMBOLIC PROCEDURE CRINDEX1(ZL,GL);
  3203. BEGIN IF NULL ZL THEN RETURN NIL;
  3204. IF NULL GL THEN << GL:=LIST GENSYM1 'i; %new symbol needed;
  3205. NCONC(!*GENSYMLIST!*,GL) >>;
  3206. RETURN (CAR GL) . CRINDEX1(CDR ZL,CDR GL) END;
  3207. SYMBOLIC PROCEDURE RMEMBER(A,B);
  3208. IF NULL B THEN NIL
  3209. ELSE IF A=CDAR B THEN CAR B
  3210. ELSE RMEMBER(A,CDR B);
  3211. SYMBOLIC PROCEDURE MERGEIN(DL,LL);
  3212. %ADJOIN LOGS OF THINGS IN DL TO EXISTING LIST LL;
  3213. IF NULL DL THEN LL
  3214. ELSE IF RMEMBER(CAR DL,LL) THEN MERGEIN(CDR DL,LL)
  3215. ELSE MERGEIN(CDR DL,('LOG . CAR DL) . LL);
  3216. ENDMODULE;
  3217. MODULE VECTOR;
  3218. EXPORTS MKIDENM,MKVEC2,MKVEC;
  3219. IMPORTS MKNILL,PNTH;
  3220. SYMBOLIC PROCEDURE MKVEC(L);
  3221. BEGIN
  3222. SCALAR V,I;
  3223. V:=MKVECT(-1+LENGTH L);
  3224. I:=0;
  3225. WHILE L DO <<
  3226. PUTV(V,I,(CAR L) ./ 1);
  3227. I:=I+1;
  3228. L:=CDR L >>;
  3229. RETURN V
  3230. END;
  3231. ENDMODULE;
  3232. END;