crutil.red 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045
  1. %********************************************************************
  2. module utilities$
  3. %********************************************************************
  4. % Routines for finding leading derivatives and others
  5. % Author: Andreas Brand
  6. % 1990 1994
  7. % Updates by Thomas Wolf
  8. %
  9. % $Id: crutil.red,v 1.23 1998/06/25 18:20:43 tw Exp tw $
  10. %
  11. %%%%%%%%%%%%%%%%%%%%%%%%%
  12. % properties of pde's %
  13. %%%%%%%%%%%%%%%%%%%%%%%%%
  14. symbolic procedure drop_dec_with(de1,de2,rl)$
  15. % drop de1 from the 'dec_with or 'dec_with_rl list of de2
  16. begin scalar a,b,c$
  17. a:=if rl then get(de2,'dec_with_rl)
  18. else get(de2,'dec_with)$
  19. for each b in a do <<
  20. b:=delete(de1,b);
  21. if length b>1 then c:=cons(b,c);
  22. >>;
  23. if rl then put(de2,'dec_with_rl,c)
  24. else put(de2,'dec_with ,c)
  25. end$
  26. symbolic procedure add_dec_with(f,de1,de2,rl)$
  27. % add (f de1) to 'dec_with or 'dec_with_rl of de2
  28. begin scalar a,b$
  29. a:=if rl then get(de2,'dec_with_rl)
  30. else get(de2,'dec_with)$
  31. b:=assoc(f,a)$
  32. a:=delete(b,a)$
  33. if b then b:=cons(f,cons(de1,cdr b))
  34. else b:=list(f,de1)$
  35. if rl then put(de2,'dec_with_rl,cons(b,a))
  36. else put(de2,'dec_with ,cons(b,a))$
  37. end$
  38. symbolic procedure add_both_dec_with(f,de1,de2,rl)$
  39. % add (f de1) to 'dec_with or 'dec_with_rl of de2 and
  40. % add (f de2) to 'dec_with or 'dec_with_rl of de1
  41. begin
  42. add_dec_with(f,de1,de2,rl)$
  43. add_dec_with(f,de2,de1,rl)$
  44. end$
  45. symbolic procedure drop_rl_with(de1,de2)$
  46. % drop de1 from the 'rl_with list of de2
  47. put(de2,'rl_with,delete(de1,get(de2,'rl_with)))$
  48. symbolic procedure add_rl_with(de1,de2)$
  49. % add de1 to 'rl_with of de2 and vice versa
  50. <<put(de2,'rl_with,cons(de1,get(de2,'rl_with)))$
  51. put(de1,'rl_with,cons(de2,get(de1,'rl_with)))>>$
  52. symbolic procedure prevent_simp(v,de1,de2)$
  53. % it is df(de1,v) = de2
  54. % add dec_with such that de2
  55. % will not be simplified to 0=0
  56. begin scalar a,b$
  57. a:=get(de1,'fcts)$
  58. for each b in a do if member(v,fctargs(b)) then
  59. <<add_dec_with(b,de2,de1,nil);add_dec_with(b,de2,de1,t)>>;
  60. a:=get(de2,'fcts)$
  61. for each b in a do if member(v,fctargs(b)) then
  62. <<add_dec_with(b,de1,de2,nil);add_dec_with(b,de1,de2,t)>>;
  63. end$
  64. symbolic procedure termread$
  65. begin scalar val, !*echo; % Don't re-echo tty input
  66. rds nil; wrs nil$ % Switch I/O to terminal
  67. val := read()$
  68. if ifl!* then rds cadr ifl!*$ % Resets I/O streams
  69. if ofl!* then wrs cdr ofl!*$
  70. history_:=cons(val,history_)$
  71. return val
  72. end$
  73. symbolic procedure termxread$
  74. begin scalar val, !*echo; % Don't re-echo tty input
  75. rds nil; wrs nil$ % Switch I/O to terminal
  76. val := xread(nil)$
  77. if ifl!* then rds cadr ifl!*$ % Resets I/O streams
  78. if ofl!* then wrs cdr ofl!*$
  79. history_:=cons(compress(append(explode val,list('$))),history_)$
  80. return val
  81. end$
  82. symbolic procedure mkeqlist(vallist,ftem,vl,flaglist,simp_flag,orderl)$
  83. % make a list of equations
  84. % vallist: list of expressions
  85. % ftem: list of functions
  86. % vl: list of variables
  87. % flaglist: list of flags
  88. % orderl: list of orderings where the equations are valid
  89. begin scalar l1$
  90. for each a in vallist do
  91. l1:=eqinsert(mkeq(a,ftem,vl,flaglist,simp_flag,orderl),l1)$
  92. return l1
  93. end$
  94. symbolic procedure mkeq(val,ftem,vl,flaglist,simp_flag,orderl)$
  95. % make a new equation
  96. % val: expression
  97. % ftem: list of functions
  98. % vl: list of variables
  99. % flaglist: list of flags
  100. % orderl: list of orderings where the equation is valid
  101. begin scalar s$
  102. s:=mkid(eqname_,nequ_)$
  103. nequ_:=add1 nequ_$
  104. setprop(s,nil)$
  105. for each a in flaglist do flag(list s,a)$
  106. if not update(s,val,ftem,vl,simp_flag,orderl) then
  107. <<nequ_:=sub1 nequ_$
  108. setprop(s,nil)$
  109. s:=nil>>$
  110. return s
  111. end$
  112. symbolic procedure update(equ,val,ftem,vl,simp_flag,orderl)$
  113. % update the properties of a pde
  114. % equ: pde
  115. % val: expression
  116. % ftem: list of functions
  117. % vl: list of variables
  118. % orderl: list of orderings where the equation is valid
  119. begin scalar l$
  120. if val and not zerop val then <<
  121. ftem:=reverse union(smemberl(ftem,val),nil)$
  122. put(equ,'terms,no_of_terms(val))$
  123. if simp_flag then <<
  124. % the following test to avoid factorizing big equations
  125. val:=if get(equ,'terms)>max_factor % get(equ,'starde)
  126. then simplifypde(val,ftem,nil)
  127. else simplifypde(val,ftem,t)$
  128. if val and not zerop val then <<
  129. ftem:=reverse union(smemberl(ftem,val),nil)$
  130. put(equ,'terms,no_of_terms(val))$
  131. >>
  132. >>$
  133. >>$
  134. if val and not zerop val then <<
  135. put(equ,'val,val)$
  136. put(equ,'fcts,ftem)$
  137. for each v in vl do
  138. if not my_freeof(val,v) then l:=cons(v,l)$
  139. vl:=reverse l$
  140. put(equ,'vars,vl)$
  141. put(equ,'nvars,length vl)$
  142. put(equ,'level,level_)$
  143. put(equ,'derivs,sort_derivs(all_deriv_search(val,ftem),ftem,vl))$
  144. put(equ,'fcteval_lin,nil)$
  145. put(equ,'fcteval_nca,nil)$
  146. put(equ,'fcteval_nli,nil)$
  147. % put(equ,'terms,no_of_terms(val))$
  148. put(equ,'length,pdeweight(val,ftem))$
  149. put(equ,'printlength,delength val)$
  150. put(equ,'rational,nil)$
  151. put(equ,'nonrational,nil)$
  152. put(equ,'allvarfcts,nil)$
  153. put(equ,'orderings,orderl)$ % Orderings !
  154. for each f in reverse ftem do
  155. if rationalp(val,f) then
  156. <<put(equ,'rational,cons(f,get(equ,'rational)))$
  157. if fctlength f=get(equ,'nvars) then
  158. put(equ,'allvarfcts,cons(f,get(equ,'allvarfcts)))>>
  159. else put(equ,'nonrational,cons(f,get(equ,'nonrational)))$
  160. % put(equ,'degrees, % too expensive
  161. % if linear_pr then cons(1,for each l in get(equ,'rational)
  162. % collect (l . 1))
  163. % else fct_degrees(val,get(equ,'rational)) )$
  164. put(equ,'starde,stardep(ftem,vl))$
  165. if (l:=get(equ,'starde)) then
  166. <<%remflag1(equ,'to_eval)$
  167. remflag1(equ,'to_int)$
  168. if simp_flag and (zerop cdr l) then flag1(equ,'to_sep)$
  169. % remflag1(equ,'to_diff)
  170. >>
  171. else remflag1(equ,'to_gensep)$
  172. if get(equ,'starde) and
  173. (zerop cdr get(equ,'starde) or (get(equ,'length)<=gensep_))
  174. then % remflag1(equ,'to_decoup)
  175. else remflag1(equ,'to_sep)$
  176. if get(equ,'nonrational) then
  177. <<%remflag1(equ,'to_decoup)$
  178. if not freeoflist(get(equ,'allvarfcts),get(equ,'nonrational)) then
  179. remflag1(equ,'to_eval)>>$
  180. % if not get(equ,'allvarfcts) then remflag1(equ,'to_eval)$
  181. if (not get(equ,'rational)) or
  182. ((l:=get(equ,'starde)) and (cdr l = 0)) then remflag1(equ,'to_eval)$
  183. if homogen_ then
  184. <<for each f in get(equ,'fcts) do val:=subst(0,f,val)$
  185. if not zerop reval reval val then
  186. <<contradiction_:=t$
  187. terpri()$
  188. write "Contradiction in ",equ,
  189. "!!! PDE has to be homogeneous!!!">> >>$
  190. remprop(equ,'full_int)$
  191. return equ
  192. >>
  193. end$
  194. symbolic procedure fct_degrees(pv,ftem)$
  195. % ftem are to be the rational functions
  196. begin
  197. scalar f,l,ll,h,degs$
  198. if den pv then pv:=num pv$
  199. for each f in ftem do <<
  200. l:=gensym()$
  201. ll:=cons((f . l),ll)$
  202. pv:=subst({'TIMES,l,f},f,pv)$
  203. >>$
  204. pv:=reval pv$
  205. for each l in ll do <<
  206. degs:=cons((car l . deg(pv,cdr l)),degs)$
  207. >>;
  208. h:=cdar ll$
  209. for each l in cdr ll do pv:=subst(h,cdr l,pv)$
  210. pv:=reval pv$
  211. return cons(deg(pv,h),degs)
  212. end$
  213. symbolic procedure pde_degree(pv,ftem)$
  214. % ftem are to be the rational functions
  215. begin
  216. scalar f,h$
  217. if den pv neq 1 then pv:=num pv$
  218. h:=gensym()$
  219. for each f in ftem do pv:=subst({'TIMES,h,f},f,pv)$
  220. pv:=reval pv$
  221. return deg(pv,h)
  222. end$
  223. symbolic procedure dfsubst_update(f,der,equ)$
  224. % miniml update of some properties of a pde
  225. % equ: pde
  226. % der: derivative
  227. % f: f new function
  228. begin scalar l$
  229. for each d in get(equ,'derivs) do
  230. if not member(cadr der,car d) then l:=cons(d,l)
  231. else
  232. <<l:=cons(cons(cons(f,df_int(cdar d,cddr der)),cdr d),l)$
  233. put(equ,'val,
  234. subst(reval cons('DF,caar l),reval cons('DF,car d),
  235. get(equ,'val)))>>$
  236. put(equ,'fcts,subst(f,cadr der,get(equ,'fcts)))$
  237. put(equ,'allvarfcts,subst(f,cadr der,get(equ,'allvarfcts)))$
  238. if get(equ,'allvarfcts) then flag(list equ,'to_eval)$
  239. % This would reactivate equations which resulted due to
  240. % substitution of derivative by a function.
  241. % 8.March 98: change again: the line 3 lines above has been reactivated
  242. put(equ,'rational,subst(f,cadr der,get(equ,'rational)))$
  243. put(equ,'nonrational,subst(f,cadr der,get(equ,'nonrational)))$
  244. put(equ,'derivs,sort_derivs(l,get(equ,'fcts),get(equ,'vars)))$
  245. return equ
  246. end$
  247. symbolic procedure eqinsert(s,l)$
  248. % l is a sorted list
  249. if not (s or get(s,'val)) or zerop get(s,'length) or member(s,l) then l
  250. else if not l then list s
  251. else begin scalar l1,n$
  252. % if print_ and tr_main then
  253. % <<terpri()$write "inserting ",s," in the pde list: ">>$
  254. l1:=proddel(s,l)$
  255. if car l1 then
  256. <<n:=get(s,'length)$
  257. l:=cadr l1$
  258. l1:=nil$
  259. % if print_ and tr_main then write s," is inserted."$
  260. while l and (n>get(car l,'length)) do
  261. <<l1:=cons(car l,l1)$
  262. l:=cdr l>>$
  263. l1:=append(reverse l1,cons(s,l))$
  264. >>
  265. else if l1 then l1:=cadr l1 % or reverse of it
  266. else l1:=l$
  267. return l1$
  268. end$
  269. symbolic procedure not_included(a,b)$
  270. % Are all elements of a also in b? If yes then return nil else t
  271. % This could be done with setdiff(a,b), only setdiff
  272. % copies expressions and needs extra memory whereas here we only
  273. % want to know one bit (included or not)
  274. begin scalar c$
  275. c:=t;
  276. while a and c do <<
  277. c:=b;
  278. while c and ((car a) neq (car c)) do c:=cdr c;
  279. % if c=nil then car a is not in b
  280. a:=cdr a;
  281. >>;
  282. return if c then nil
  283. else t
  284. end$
  285. symbolic procedure proddel(s,l)$
  286. % delete all pdes from l with s as factor
  287. % delete s if it is a consequence of any known pde from l
  288. begin scalar l1,l2,l3,n,lnew,go_on$
  289. if pairp(lnew:=get(s,'val)) and (car lnew='TIMES) then lnew:=cdr lnew
  290. else lnew:=list lnew$
  291. n:=length lnew$
  292. go_on:=t$
  293. while l do << % while l and go_on do << % in case one wants to stop if s
  294. % is found to be a consequence of l
  295. if pairp(l1:=get(car l,'val)) and (car l1='TIMES) then l1:=cdr l1
  296. else l1:=list l1$
  297. if n<length l1 then % s has less factors than car l
  298. if not_included(lnew,l1) then
  299. l2:=cons(car l,l2) % car l is not a consequ. of s
  300. else
  301. <<l3:=cons(car l,l3); % car l is a consequ. of s
  302. setprop(car l,nil)
  303. >>
  304. else <<
  305. if null not_included(l1,lnew) then % s is a consequence of car l
  306. <<if print_ and tr_main then
  307. <<terpri()$write s," is a consequence of ",car l,".">>$
  308. % l2:=append(reverse l,l2);
  309. % one could stop here but continuation can still be useful
  310. go_on:=nil$
  311. >>$
  312. % else
  313. l2:=cons(car l,l2)$
  314. >>;
  315. l:=cdr l
  316. >>$
  317. if print_ and tr_main and l3 then <<
  318. terpri()$listprint l3$
  319. if cdr l3 then write " are consequences of ",s
  320. else write " is a consequence of ",s
  321. >>$
  322. if null go_on then <<setprop(s,nil);s:=nil>>$
  323. return list(s,reverse l2)$
  324. end$
  325. symbolic procedure myprin2l(l,trenn)$
  326. if l then
  327. <<if pairp l then
  328. while l do
  329. <<write car l$
  330. l:=cdr l$
  331. if l then write trenn>>
  332. else write l>>$
  333. symbolic procedure typeeq(s)$
  334. % print equation
  335. if get(s,'printlength)>print_ then begin scalar a,b$
  336. write "expr. with ",(a:=get(s,'terms))," terms"$
  337. if a neq (b:=get(s,'length)) then write", ",b," factors"$
  338. write" in "$
  339. myprin2l(get(s,'fcts),", ")$
  340. terpri()$
  341. end else
  342. mathprint list('EQUAL,0,get(s,'val))$
  343. symbolic procedure typeeqlist(l)$
  344. % print equations and its property lists
  345. <<terpri()$
  346. for each s in l do
  347. <<%terpri()$
  348. write s," : "$ typeeq(s)$%terpri()$
  349. % write s," : weight = ",get(s,'length),", "$
  350. % if print_ and (get(s,'printlength)>print_) then
  351. % <<write "expr. with ",get(s,'terms)," terms in "$
  352. % myprin2l(get(s,'fcts),", ")$
  353. % terpri()>>
  354. % else
  355. % mathprint list('EQUAL,0,get(s,'val))$
  356. if print_all then
  357. <<
  358. write " fcts : ",get(s,'fcts)$
  359. terpri()$write " vars : ",get(s,'vars)$
  360. terpri()$write " nvars : ",get(s,'nvars)$
  361. terpri()$write " derivs : ",get(s,'derivs)$
  362. terpri()$write " terms : ",get(s,'terms)$
  363. terpri()$write " length : ",get(s,'length)$
  364. terpri()$write " printlength: ",get(s,'printlength)$
  365. terpri()$write " level : ",get(s,'level)$
  366. terpri()$write " allvarfcts : ",get(s,'allvarfcts)$
  367. terpri()$write " rational : ",get(s,'rational)$
  368. terpri()$write " nonrational: ",get(s,'nonrational)$
  369. terpri()$write " degrees : ",get(s,'degrees)$
  370. terpri()$write " starde : ",get(s,'starde)$
  371. terpri()$write " fcteval_lin: ",get(s,'fcteval_lin)$
  372. terpri()$write " fcteval_nca: ",get(s,'fcteval_nca)$
  373. terpri()$write " fcteval_nli: ",get(s,'fcteval_nli)$
  374. terpri()$write " rl_with : ",get(s,'rl_with)$
  375. terpri()$write " dec_with : ",get(s,'dec_with)$
  376. terpri()$write " dec_with_rl: ",get(s,'dec_with_rl)$
  377. terpri()$write " dec_info : ",get(s,'dec_info)$
  378. terpri()$write " to_int : ",flagp(s,'to_int)$
  379. terpri()$write " to_sep : ",flagp(s,'to_sep)$
  380. terpri()$write " to_gensep : ",flagp(s,'to_gensep)$
  381. terpri()$write " to_decoup : ",flagp(s,'to_decoup)$
  382. terpri()$write " to_drop : ",flagp(s,'to_drop)$
  383. terpri()$write " to_eval : ",flagp(s,'to_eval)$
  384. terpri()$write " not_to_eval: ",get(s,'not_to_eval)$
  385. terpri()$write " used_ : ",flagp(s,'used_)$
  386. terpri()$write " orderings : ",get(s,'orderings)$
  387. terpri()>>
  388. >> >>$
  389. symbolic procedure rationalp(p,f)$
  390. % tests if p is rational in f and its derivatives
  391. not pairp p
  392. or
  393. ((car p='QUOTIENT) and
  394. polyp(cadr p,f) and polyp(caddr p,f))
  395. or
  396. ((car p='EQUAL) and
  397. rationalp(cadr p,f) and rationalp(caddr p,f))
  398. or
  399. polyp(p,f)$
  400. symbolic procedure ratexp(p,ftem)$
  401. if null ftem then t
  402. else if rationalp(p,car ftem) then ratexp(p,cdr ftem)
  403. else nil$
  404. symbolic procedure polyp(p,f)$
  405. % tests if p is a polynomial in f and its derivatives
  406. % p: expression
  407. % f: function
  408. if my_freeof(p,f) then t
  409. else
  410. begin scalar a$
  411. if atom p then a:=t
  412. else
  413. if member(car p,list('EXPT,'PLUS,'MINUS,'TIMES,'QUOTIENT,'DF)) then
  414. % erlaubte Funktionen
  415. <<if (car p='PLUS) or (car p='TIMES) then
  416. <<p:=cdr p$
  417. while p do
  418. if a:=polyp(car p,f) then p:=cdr p
  419. else p:=nil>>
  420. else if (car p='MINUS) then
  421. a:=polyp(cadr p,f)
  422. else if (car p='QUOTIENT) then
  423. <<if freeof(caddr p,f) then a:=polyp(cadr p,f)>>
  424. else if car p='EXPT then % Exponent
  425. <<if (fixp caddr p) then
  426. if caddr p>0 then a:=polyp(cadr p,f)>>
  427. else if car p='DF then % Ableitung
  428. if (cadr p=f) or freeof(cadr p,f) then a:=t>>
  429. else a:=(p=f)$
  430. return a
  431. end$
  432. symbolic procedure starp(ft,n)$
  433. % yields T if all functions from ft have less than n arguments
  434. begin scalar b$
  435. while not b and ft do % searching a fct of all vars
  436. if fctlength car ft=n then b:=t
  437. else ft:=cdr ft$
  438. return not b
  439. end$
  440. symbolic procedure stardep(ftem,vl)$
  441. % yields: nil, if a function (from ftem) in p depends
  442. % on all variables (from vl)
  443. % cons(v,n) otherweise, with v being the list of variables
  444. % which occur in a minimal number of n functions
  445. begin scalar b,v,n$
  446. if starp(ftem,length vl) then
  447. <<n:=sub1 length ftem$
  448. while vl do % searching var.s on which depend a
  449. % minimal number of functions
  450. <<if n> (b:=for each h in ftem sum
  451. if member(car vl,fctargs h) then 1
  452. else 0)
  453. then
  454. <<n:=b$ % a new minimum
  455. v:=list car vl>>
  456. else if b=n then v:=cons(car vl,v)$
  457. vl:=cdr vl>> >>$
  458. return if v then cons(v,n) % on each varible from v depend n
  459. % functions
  460. else nil
  461. end$
  462. symbolic operator parti_fn$
  463. symbolic procedure parti_fn(fl,el)$
  464. % fl ... alg. list of functions, el ... alg. list of equations
  465. % partitions fl such that all functions that are somehow dependent on
  466. % each other through equations in el are grouped in lists,
  467. % returns alg. list of these lists
  468. begin
  469. scalar f1,f2,f3,f4,f5,e1,e2;
  470. fl:=cdr fl;
  471. el:=cdr el;
  472. while fl do <<
  473. f1:=nil; % f1 is the sublist of functions depending on each other
  474. f2:=list car fl; % f2 ... func.s to be added to f1, not yet checked
  475. fl:=cdr fl;
  476. while f2 and fl do <<
  477. f3:=car f2; f2:=cdr f2;
  478. f1:=cons(f3,f1);
  479. for each f4 in
  480. % smemberl will be all functions not registered yet that occur in
  481. % an equation in which the function f3 occurs
  482. smemberl(fl, % fl ... the remaining functions not known yet to depend
  483. <<e1:=nil; % equations in which f3 occurs
  484. for each e2 in el do
  485. if smember(f3,e2) then e1:=cons(e2,e1);
  486. e1
  487. >>
  488. ) do <<
  489. f2:=cons(f4,f2);
  490. fl:=delete(f4,fl)
  491. >>
  492. >>;
  493. if f2 then f1:=append(f1,f2);
  494. f5:=cons(cons('LIST,f1),f5)
  495. >>;
  496. return cons('LIST,f5)
  497. end$
  498. %%%%%%%%%%%%%%%%%%%%%%%%%
  499. % leading derivatives %
  500. %%%%%%%%%%%%%%%%%%%%%%%%%
  501. symbolic procedure listrel(a,b,l)$
  502. % a>=b w.r.t list l; e.g. l='(a b c) -> a>=a, b>=c
  503. member(b,member(a,l))$
  504. %symbolic procedure abs_dfrel(p,q,ftem,vl)$
  505. symbolic procedure abs_dfrel(p,q,vl)$
  506. % the relation "p is a lower derivative than q" (total deg. ord.)
  507. % p,q : derivatives or functions from ftem
  508. % ftem : list of fcts
  509. % vl : list of vars
  510. begin scalar a$
  511. return
  512. if lex_ then dfrel1(p,q,vl) else
  513. if zerop (a:=absdeg(cdar p)-absdeg(cdar q)) then dfrel1(p,q,vl)
  514. else a<0$
  515. end$
  516. %%symbolic procedure lower_lderiv(p,q,ftem,vl)$
  517. %symbolic procedure lower_lderiv(p,q,vl)$
  518. %% the relation "p has a lower (absolute) derivative than q"
  519. %if abs_ld_deriv(p) and abs_ld_deriv(q) then
  520. %% abs_dfrel(car get(p,'derivs),car get(q,'derivs),ftem,vl)
  521. % abs_dfrel(car get(p,'derivs),car get(q,'derivs),vl)
  522. %else if abs_ld_deriv(q) then t$
  523. symbolic procedure mult_derivs(a,b)$
  524. % multiplies deriv. of a and b
  525. % a,b list of derivs of the form ((fct var1 n1 ...).pow)
  526. begin scalar l$
  527. return
  528. if not b then a
  529. else if not a then b
  530. else
  531. <<
  532. for each s in a do
  533. for each r in b do
  534. if car s=car r then l:=union(list cons(car r,plus(cdr r,cdr s)),l)
  535. else l:=union(list(r,s),l)$
  536. l>>$
  537. end$
  538. symbolic procedure all_deriv_search(p,ftem)$
  539. % yields all derivatives occuring polynomially in a pde p
  540. begin scalar a$
  541. if not pairp p then
  542. <<if member(p,ftem) then a:=list cons(list p,1)>>
  543. else
  544. <<if member(car p,'(PLUS QUOTIENT EQUAL)) then
  545. for each q in cdr p do
  546. a:=union(all_deriv_search(q,ftem),a)
  547. else if car p='MINUS then a:=all_deriv_search(cadr p,ftem)
  548. else if car p='TIMES then
  549. for each q in cdr p do
  550. a:=mult_derivs(all_deriv_search(q,ftem),a)
  551. else if (car p='EXPT) and numberp caddr p then
  552. for each b in all_deriv_search(cadr p,ftem) do
  553. <<if numberp cdr b then
  554. a:=cons(cons(car b,times(caddr p,cdr b)),a)>>
  555. else if (car p='DF) and member(cadr p,ftem) then a:=list cons(cdr p,1)
  556. >>$
  557. return a
  558. end$
  559. symbolic procedure abs_ld_deriv(p)$
  560. if get(p,'derivs) then reval cons('DF,caar get(p,'derivs))$
  561. symbolic procedure abs_ld_deriv_pow(p)$
  562. if get(p,'derivs) then cdar get(p,'derivs)
  563. else 0$
  564. symbolic procedure which_first(a,b,l)$
  565. if null l then nil else
  566. if a = car l then a else
  567. if b = car l then b else which_first(a,b,cdr l)$
  568. symbolic procedure sort_derivs(l,ftem,vl)$
  569. % yields a sorted list of all derivatives in p
  570. begin scalar l1,l2,a,fa$
  571. return
  572. if null l then nil
  573. else
  574. <<a:=car l$
  575. fa:=caar a$
  576. l:=cdr l$
  577. while l do
  578. <<if fa=caaar l then
  579. % if abs_dfrel(a,car l,ftem,vl) then l1:=cons(car l,l1)
  580. % else l2:=cons(car l,l2)
  581. if abs_dfrel(a,car l,vl) then l1:=cons(car l,l1)
  582. else l2:=cons(car l,l2)
  583. else
  584. if fa=which_first(fa,caaar l,ftem) then l2:=cons(car l,l2)
  585. else l1:=cons(car l,l1)$
  586. l:=cdr l>>$
  587. append(sort_derivs(l1,ftem,vl),cons(a,sort_derivs(l2,ftem,vl)))>>
  588. end$
  589. symbolic procedure dfmax(p,q,vl)$
  590. % yields the higher derivative
  591. % vl list of variables e.g. p=((x 2 y 3 z).2), q=((x y 4 z).1)
  592. % df(f,x,2,y,3,z)^2, df(f,x,y,4,z)
  593. if dfrel(p,q,vl) then q
  594. else p$
  595. symbolic procedure dfrel(p,q,vl)$
  596. % the relation "p is lower than q"
  597. % vl list of vars e.g. p=((x 2 y 3 z).2), q=((x y 4 z).1)
  598. if cdr p='infinity then nil
  599. else if cdr q='infinity then t
  600. else begin scalar a$
  601. return
  602. if lex_ then dfrel1(p,q,vl) else
  603. if zerop(a:=absdeg(car p)-absdeg(car q)) then dfrel1(p,q,vl)
  604. else if a<0 then t
  605. else nil
  606. end$
  607. symbolic procedure diffrelp(p,q,v)$
  608. % liefert t, falls p einfacherer Differentialausdruck, sonst nil
  609. % p, q Paare (liste.power), v Liste der Variablen
  610. % liste Liste aus Var. und Ordn. der Ableit. in Diff.ausdr.,
  611. % power Potenz des Differentialausdrucks
  612. if cdr p='infinity then nil
  613. else if cdr q='infinity then t
  614. else dfrel1(p,q,v)$
  615. symbolic procedure dfrel1(p,q,v)$
  616. if null v then % same derivatives,
  617. if cdr p>cdr q then nil % considering powers
  618. else t
  619. else begin
  620. scalar a,b$
  621. a:=dfdeg(car p, car v)$
  622. b:=dfdeg(car q,car v)$
  623. return if a<b then t
  624. else if b<a then nil
  625. else dfrel1(p,q,cdr v) % same derivative w.r.t car v
  626. end$
  627. symbolic procedure absdeg(p)$
  628. if null p then 0
  629. else eval cons('PLUS,for each v in p collect if fixp(v) then sub1(v)
  630. else 1)$
  631. symbolic procedure maxderivs(numberlist,deriv,varlist)$
  632. if null numberlist then
  633. for each v in varlist collect dfdeg(deriv,v)
  634. else begin scalar l$
  635. for each v in varlist do
  636. <<l:=cons(max(car numberlist,dfdeg(deriv,v)),l)$
  637. numberlist:=cdr numberlist>>$
  638. return reverse l
  639. end$
  640. symbolic procedure dfdeg(p,v)$
  641. % yields degree of deriv. wrt. v$
  642. % e.g p='(x 2 y z 3), v='x --> 2
  643. if null(p:=member(v,p)) then 0
  644. else if null(cdr p) or not fixp(cadr p)
  645. then 1 % v without degree
  646. else cadr p$ % v with degree
  647. symbolic procedure df_int(d1,d2)$
  648. begin scalar n,l$
  649. return
  650. if d1 then
  651. if d2 then
  652. <<n:=dfdeg(d1,car d1)-dfdeg(d2,car d1)$
  653. l:=df_int(if cdr d1 and numberp cadr d1 then cddr d1
  654. else cdr d1 ,d2)$
  655. if n<=0 then l
  656. else if n=1 then cons(car d1,l)
  657. else cons(car d1,cons(n,l))
  658. >>
  659. else d1$
  660. end$
  661. symbolic procedure linear_fct(p,f)$
  662. begin scalar l$
  663. l:=ld_deriv(p,f)$
  664. return ((car l=f) and (cdr l=1))
  665. end$
  666. % not used anymore:
  667. %
  668. %symbolic procedure dec_ld_deriv(p,f,vl)$
  669. %% gets leading derivative of f in p wrt. vars order vl
  670. %% result: derivative , e.g. '(x 2 y 3 z)
  671. %begin scalar l,d,ld$
  672. % l:=get(p,'derivs)$
  673. % vl:=intersection(vl,get(p,'vars))$
  674. % while caaar l neq f do l:=cdr l$
  675. % ld:=car l$l:=cdr l$
  676. % % --> if lex_ then dfrel1() else
  677. % d:=absdeg(cdar ld)$
  678. % while l and (caaar l=f) and (d=absdeg cdaar l) do
  679. % <<if dfrel1(ld,car l,vl) then ld:=car l$
  680. % l:=cdr l>>$
  681. % return cdar ld$
  682. %end$
  683. symbolic procedure ld_deriv(p,f)$
  684. % gets leading derivative of f in p
  685. % result: derivative + power , e.g. '((DF f x 2 y 3 z).3)
  686. begin scalar l$
  687. return if l:=get(p,'derivs) then
  688. <<while caaar l neq f do l:=cdr l$
  689. if l then cons(reval cons('DF,caar l),cdar l)>>
  690. else cons(nil,0)$
  691. end$
  692. symbolic procedure ldiffp(p,f)$
  693. % liefert Liste der Variablen + Ordnungen mit Potenz
  694. % p Ausdruck in LISP - Notation, f Funktion
  695. ld_deriv_search(p,f,fctargs f)$
  696. symbolic procedure ld_deriv_search(p,f,vl)$
  697. % gets leading derivative of funktion f in expr. p w.r.t
  698. % list of variables vl
  699. begin scalar a$
  700. if p=f then a:=cons(nil,1)
  701. else
  702. <<a:=cons(nil,0)$
  703. if pairp p then
  704. if member(car p,'(PLUS TIMES QUOTIENT EQUAL)) then
  705. <<p:=cdr p$
  706. while p do
  707. <<a:=dfmax(ld_deriv_search(car p,f,vl),a,vl)$
  708. if cdr a='infinity then p:=nil
  709. else p:=cdr p
  710. >>
  711. >>
  712. else if car p='MINUS then a:=ld_deriv_search(cadr p,f,vl)
  713. else if car p='EXPT then
  714. <<a:=ld_deriv_search(cadr p,f,vl)$
  715. if numberp cdr a then
  716. if numberp caddr p
  717. then a:=cons(car a,times(caddr p,cdr a))
  718. else if not zerop cdr a
  719. then a:=cons(nil,'infinity)
  720. else if not my_freeof(caddr p,f)
  721. then a:=cons(nil,'infinity)
  722. >>
  723. else if car p='DF then
  724. if cadr p=f then a:=cons(cddr p,1)
  725. else if my_freeof(cadr p,f)
  726. then a:=cons(nil,0) % a constant
  727. else a:=cons(nil,'infinity)
  728. else if my_freeof(p,f) then a:=cons(nil,0)
  729. else a:=cons(nil,'infinity)
  730. >>$
  731. return a
  732. end$
  733. symbolic procedure lderiv(p,f,vl)$
  734. % fuehrende Ableitung in LISP-Notation mit Potenz (als dotted pair)
  735. begin scalar l$
  736. l:=ld_deriv_search(p,f,vl)$
  737. return cons(if car l then cons('DF,cons(f,car l))
  738. else if zerop cdr l then nil
  739. else f
  740. ,cdr l)
  741. end$
  742. symbolic procedure splitinhom(q,ftem,vl)$
  743. % Splitting the equation q into the homogeneous and inhom. part
  744. % returns dotted pair qhom . qinhom
  745. begin scalar qhom,qinhom,denm;
  746. vl:=varslist(q,ftem,vl)$
  747. if pairp q and (car q = 'QUOTIENT) then
  748. if starp(smemberl(ftem,caddr q),length vl) then
  749. <<denm:=caddr q; q:=cadr q>> else return (q . 0)
  750. else denm:=1;
  751. if pairp q and (car q = 'PLUS) then q:=cdr q
  752. else q:=list q;
  753. while q do <<
  754. if starp(smemberl(ftem,car q),length vl) then qinhom:=cons(car q,qinhom)
  755. else qhom :=cons(car q,qhom);
  756. q:=cdr q
  757. >>;
  758. if null qinhom then qinhom:=0
  759. else
  760. if length qinhom > 1 then qinhom:=cons('PLUS,qinhom)
  761. else qinhom:=car qinhom;
  762. if null qhom then qhom:=0
  763. else
  764. if length qhom > 1 then qhom:=cons('PLUS,qhom)
  765. else qhom:=car qhom;
  766. if denm neq 1 then <<qhom :=list('QUOTIENT, qhom,denm);
  767. qinhom:=list('QUOTIENT,qinhom,denm)>>;
  768. return qhom . qinhom
  769. end$
  770. symbolic procedure search_den(l)$
  771. % get all denominators and arguments of LOG,... anywhere in a list l
  772. begin scalar l1$
  773. if pairp l then
  774. if car l='quotient then
  775. l1:=union(cddr l,union(search_den(cadr l),search_den(caddr l)))
  776. else if member(car l,'(log ln logb log10)) then
  777. if pairp cadr l and (caadr l='QUOTIENT) then
  778. l1:=union(list cadadr l,search_den(cadr l))
  779. else l1:=union(cdr l,search_den(cadr l))
  780. else for each s in l do l1:=union(search_den(s),l1)$
  781. return l1$
  782. end$
  783. symbolic procedure zero_den(l,ftem,vl)$
  784. begin scalar cases$
  785. l:=search_den(l)$
  786. while l do <<
  787. if not freeofzero(car l,ftem,vl) then cases:=cons(car l,cases);
  788. l:=cdr l
  789. >>$
  790. return cases
  791. end$
  792. symbolic procedure forg_int (forg,fges)$
  793. for each ex in forg collect
  794. if pairp ex and pairp cadr ex then forg_int_f(ex,smemberl(fges,ex))
  795. else ex$
  796. symbolic procedure forg_int_f(ex,fges)$
  797. % try to integrate expr. ex of the form df(f,...)=expr.
  798. begin scalar p,h,f$
  799. p:=caddr ex$
  800. f:=cadadr ex$
  801. if pairp p and (car p='PLUS)
  802. then p:=reval cons('PLUS,cons(list('MINUS,cadr ex),cdr p))
  803. else p:=reval list('DIFFERENCE,p,cadr ex)$
  804. p:=integratepde(p,cons(f,fges),nil,nil,nil)$
  805. if p and (car p) and not cdr p then
  806. <<h:=car lderiv(car p,f,fctargs f)$
  807. p:=reval list('PLUS,car p,h)$
  808. ftem_:=reverse ftem_$
  809. for each ff in reverse fnew_ do
  810. if not member(ff,ftem_) then ftem_:=fctinsert(ff,ftem_)$
  811. ftem_:=reverse ftem_$
  812. ex:=list('EQUAL,h,p)>>$
  813. return ex
  814. end$
  815. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  816. % general purpose procedures %
  817. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  818. symbolic procedure smemberl(fl,ex)$
  819. % smember for a list
  820. if fl and ex then
  821. if smember(car fl,ex) then cons(car fl,smemberl(cdr fl,ex))
  822. else smemberl(cdr fl,ex)$
  823. symbolic operator my_freeof$
  824. symbolic procedure my_freeof(u,v)$
  825. % a patch for FREEOF in REDUCE 3.5
  826. not(smember(v,u)) and freeofdepl(depl!*,u,v)$
  827. lisp flag('(my_freeof),'BOOLEAN)$
  828. symbolic procedure freeoflist(l,m)$
  829. % liefert t, falls kein Element aus m in l auftritt
  830. if null m then t
  831. else if freeof(l,car m) then freeoflist(l,cdr m)
  832. else nil$
  833. symbolic procedure freeofdepl(de,u,v)$
  834. if null de then t
  835. else if smember(v,cdar de) and smember(caar de,u) then nil
  836. else freeofdepl(cdr de,u,v)$
  837. symbolic procedure fctinsert(f,ftem)$
  838. % isert a function f in the function list ftem
  839. if null ftem then list f
  840. else if fctlength car ftem >= fctlength f then cons(f,ftem)
  841. else cons(car ftem,fctinsert(f,cdr ftem))$
  842. symbolic procedure newfct(id,l,nfct)$
  843. begin scalar f$
  844. f:=mkid(id,nfct)$
  845. depl!*:=delete(assoc(f,depl!*),depl!*)$
  846. %put(f,'simpfn,'simpiden)$
  847. %if pairp l then f:=cons(f,l)$
  848. if pairp l then depl!*:=cons(cons(f,l),depl!*)$
  849. if print_ then
  850. <<terpri()$
  851. if pairp l then
  852. <<write "new function: "$
  853. fctprint list f>>
  854. else
  855. write "new constant: ",f>>$
  856. return f$
  857. end$
  858. symbolic procedure varslist(p,ftem,vl)$
  859. begin scalar l$
  860. ftem:=argset smemberl(ftem,p)$
  861. for each v in vl do
  862. if not my_freeof(p,v) or member(v,ftem) then l:=cons(v,l)$
  863. return reverse l$
  864. end$
  865. symbolic procedure var_list(pdes,forg,vl)$
  866. begin scalar l,l1$
  867. for each p in pdes do l:=union(get(p,'vars),l)$
  868. for each v in vl do
  869. if member(v,l) or not my_freeof(forg,v) then l1:=cons(v,l1)$
  870. return reverse l1$
  871. end$
  872. symbolic procedure fctlist(ftem,pdes,forg)$
  873. begin scalar fges,l$
  874. for each p in pdes do l:=union(get(p,'fcts),l)$
  875. for each f in ftem do
  876. if not my_freeof(forg,f) or member(f,l) then fges:=fctinsert(f,fges)$
  877. for each f in forg do
  878. if not pairp f and not member(f,fges) then fges:=fctinsert(f,fges)$
  879. for each f in l do
  880. if not member(f,fges) then fges:=fctinsert(f,fges)$
  881. return reverse fges$
  882. end$
  883. symbolic operator fargs$
  884. symbolic procedure fargs f$
  885. cons('LIST,fctargs f)$
  886. symbolic procedure fctargs f$
  887. % arguments of a function
  888. if (f:=assoc(f,depl!*)) then cdr f$
  889. symbolic procedure fctlength f$
  890. % number of arguments
  891. length fctargs f$
  892. symbolic procedure fctsort(l)$
  893. % list sorting
  894. begin scalar l1,l2,l3,m,n$
  895. return
  896. if null l then nil
  897. else
  898. <<n:=fctlength car l$
  899. l2:=list car l$
  900. l:=cdr l$
  901. while l do
  902. <<m:=fctlength car l$
  903. if m<n then l1:=cons(car l,l1)
  904. else if m>n then l3:=cons(car l,l3)
  905. else l2:=cons(car l,l2)$
  906. l:=cdr l>>$
  907. append(fctsort reverse l3,append(reverse l2,fctsort reverse l1))>>
  908. end$
  909. symbolic procedure listprint(l)$
  910. % print a funktion
  911. if pairp l then
  912. <<write car l$
  913. for each v in cdr l do
  914. <<write ","$write v>> >>$
  915. symbolic procedure fctprint1(f)$
  916. % print a funktion
  917. if f then
  918. if pairp f then
  919. <<write car f$
  920. if pairp cdr f then
  921. <<write "("$
  922. listprint cdr f$
  923. write ")">>
  924. >>
  925. else write f$
  926. symbolic procedure fctprint(fl)$
  927. % Ausdrucken der Funktionen aus fl
  928. begin scalar n,l,f$
  929. n:=0$
  930. while fl do
  931. <<f:=car fl$
  932. fl:=cdr fl$
  933. if pairp f then
  934. if car f='EQUAL then
  935. <<n:=delength f$
  936. if (null print_) or (n>print_) then
  937. <<terpri()$write cadr f,"= expr. with ",n," terms"$
  938. if (l:=get(cadr f,'fcts)) then
  939. <<write " in "$
  940. myprin2l(l,", ")>>$
  941. terpri()>>
  942. else mathprint f$
  943. n:=0>>
  944. else
  945. <<if n eq 4 then
  946. <<terpri()$n:=0>>$
  947. fctprint1 f$
  948. if fl then write ", "$
  949. n:=add1 n>>
  950. else
  951. <<if n eq 4 then
  952. <<terpri()$n:=0>>$
  953. l:=assoc(f,depl!*)$
  954. fctprint1 if l then l
  955. else f$
  956. if fl then write ", "$
  957. n:=add1 n>>
  958. >>$
  959. %if n neq 0 then terpri()
  960. end$
  961. symbolic procedure deprint(l)$
  962. % Ausdrucken der Gl. aus der Liste l
  963. if l and print_ then for each x in l do eqprint list('EQUAL,0,x)$
  964. symbolic procedure eqprint(e)$
  965. % Ausdrucken der Gl. e
  966. if print_ then
  967. begin scalar n$
  968. n:=delength e$
  969. if n>print_ then
  970. <<write "expr. with "$write n$write " terms"$
  971. terpri()
  972. >>
  973. else
  974. mathprint e$
  975. end$
  976. symbolic procedure print_level$
  977. if print_ and level_ then <<
  978. terpri()$
  979. write "New level : "$
  980. for each m in reverse level_ do write m,"."$
  981. >>$
  982. symbolic procedure print_statistic(pdes,fcts)$
  983. if print_ then begin
  984. integer j,k,le,r,s$
  985. scalar n,m,p,el,fl,vl$
  986. %--- printing the stats of equations:
  987. if pdes then <<
  988. terpri()$write "number of equations : ",length pdes$
  989. terpri()$write "total no of terms : ",
  990. j:=for each p in pdes sum get(p,'terms)$
  991. k:=for each p in pdes sum get(p,'length)$
  992. if k neq j then <<terpri()$write "total no of factors : ",k>>$
  993. while pdes do <<
  994. j:=0;
  995. el:=nil;
  996. for each p in pdes do <<
  997. vl:=get(p,'vars);
  998. if vl then le:=length vl
  999. else le:=0;
  1000. if ((j=0) and null vl) or
  1001. (j=le) then el:=cons(p,el)
  1002. else if j<le then <<
  1003. j:=le;
  1004. el:=list(p)
  1005. >>
  1006. >>;
  1007. pdes:=setdiff(pdes,el);
  1008. if el then <<
  1009. n:=length el$
  1010. terpri()$write n," equation"$
  1011. if n>1 then write"s"$write" in ",j," variable"$
  1012. if j neq 1 then write"s"$
  1013. write": "$
  1014. k:=0;
  1015. while el do <<
  1016. if k=4 then <<k:=0;terpri()>>
  1017. else k:=add1 k$
  1018. write car el,"(",get(car el,'length)$
  1019. if (s:=get(car el,'starde)) then
  1020. for r:=1:(1+cdr s) do write"*"$
  1021. write")"$
  1022. el:=cdr el$
  1023. if el then write","$
  1024. >>
  1025. >>$
  1026. j:=add1 j;
  1027. >>
  1028. >>
  1029. else <<terpri()$write "no equations">>$
  1030. %--- printing the stats of functions:
  1031. for each f in fcts do if not pairp f then fl:=cons(f,fl)$
  1032. if fl then <<
  1033. fl:=fctsort reverse fl$
  1034. m:=fctlength car fl$
  1035. while m>=0 do <<
  1036. n:=0$
  1037. el:=nil;
  1038. while fl and (fctlength car fl=m) do <<
  1039. n:=add1 n$
  1040. el:=cons(car fl,el)$
  1041. fl:=cdr fl
  1042. >>$
  1043. if n>0 then
  1044. if m>0 then <<
  1045. terpri()$
  1046. write n," function"$
  1047. if n>1 then write"s"$
  1048. write" with ",m," argument",if m>1 then "s : "
  1049. else " : "
  1050. >> else <<
  1051. terpri()$
  1052. write n," constant"$
  1053. if n>1 then write"s"$
  1054. write" : "
  1055. >>$
  1056. k:=0;
  1057. while el do <<
  1058. if k=10 then <<k:=0;terpri()>>
  1059. else k:=add1 k$
  1060. write car el$
  1061. el:=cdr el$
  1062. if el then write","$
  1063. >>$
  1064. m:=if fl then fctlength car fl
  1065. else -1
  1066. >>
  1067. >> else <<terpri()$write "no functions or constants">>$
  1068. terpri()$
  1069. end$
  1070. symbolic procedure print_pde_ineq(pdes,ineqs)$
  1071. % print all pdes and ineqs
  1072. <<if pdes then
  1073. <<terpri()$terpri()$write "equations : "$
  1074. typeeqlist(pdes)>>
  1075. else
  1076. <<terpri()$terpri()$write "no equations">>$
  1077. if ineqs then
  1078. <<terpri()$write "non-vanishing expressions: "$
  1079. for each aa in ineqs do eqprint aa>>$
  1080. >>$
  1081. symbolic procedure print_fcts(fcts,vl)$
  1082. % print all fcts and vars
  1083. <<if fcts then
  1084. <<terpri()$write "functions : "$
  1085. fctprint(fcts)>>$
  1086. if vl then
  1087. <<terpri()$write "variables : "$
  1088. fctprint(vl)>>$
  1089. >>$
  1090. symbolic procedure print_pde_fct_ineq(pdes,ineqs,fcts,vl)$
  1091. % print all pdes, ineqs and fcts
  1092. if print_ then begin$
  1093. print_pde_ineq(pdes,ineqs)$
  1094. print_fcts(fcts,vl)$
  1095. print_statistic(pdes,fcts)
  1096. end$
  1097. symbolic procedure no_of_terms(d)$
  1098. if not pairp d then if d then 1
  1099. else 0
  1100. else if car d='PLUS then length d - 1
  1101. else 1$
  1102. symbolic procedure delength(d)$
  1103. % Laenge eines Polynoms in LISP - Notation
  1104. if not pairp d then
  1105. if d then 1
  1106. else 0
  1107. else
  1108. if (car d='PLUS) or (car d='TIMES) or (car d='QUOTIENT)
  1109. or (car d='MINUS) or (car d='EQUAL)
  1110. then for each a in cdr d sum delength(a)
  1111. else 1$
  1112. symbolic procedure pdeweight(d,ftem)$
  1113. % Laenge eines Polynoms in LISP - Notation
  1114. if not smemberl(ftem,d) then 0
  1115. else if not pairp d then 1
  1116. else if (car d='PLUS) or (car d='TIMES) or (car d='EQUAL)
  1117. or (car d='QUOTIENT) then
  1118. for each a in cdr d sum pdeweight(a,ftem)
  1119. else if (car d='EXPT) then
  1120. if numberp caddr d then
  1121. caddr d*pdeweight(cadr d,ftem)
  1122. else 1
  1123. else 1$
  1124. symbolic procedure desort(l)$
  1125. % list sorting
  1126. begin scalar l1,l2,l3,m,n$
  1127. return
  1128. if null l then nil
  1129. else
  1130. <<n:=delength car l$
  1131. l2:=list car l$
  1132. l:=cdr l$
  1133. while l do
  1134. <<m:=delength car l$
  1135. if m<n then l1:=cons(car l,l1)
  1136. else if m>n then l3:=cons(car l,l3)
  1137. else l2:=cons(car l,l2)$
  1138. l:=cdr l>>$
  1139. append(desort(l1),append(l2,desort(l3)))>>
  1140. end$
  1141. symbolic procedure argset(ftem)$
  1142. % List of arguments of all functions in ftem
  1143. if ftem then union(reverse fctargs car ftem,argset(cdr ftem))
  1144. else nil$
  1145. symbolic procedure backup_pdes(pdes,forg)$
  1146. % make a backup of all pdes
  1147. begin scalar cop$
  1148. cop:=list(nequ_,
  1149. for each p in pdes collect
  1150. list(p,
  1151. for each q in prop_list collect cons(q,get(p,q)),
  1152. for each q in allflags_ collect if flagp(p,q) then q),
  1153. for each f in forg collect
  1154. if pairp f then cons(cadr f,get(cadr f,'fcts))
  1155. else cons(f,get(f,'fcts)),
  1156. ftem_,
  1157. ineq_)$
  1158. return cop
  1159. end$
  1160. symbolic procedure restore_pdes(cop)$
  1161. % restore the pde list cop
  1162. % first element must be the old value of nequ_
  1163. % the elements must have the form (p . property_list_of_p)
  1164. begin scalar pdes$
  1165. % delete all new produced pdes
  1166. for i:=car cop:sub1 nequ_ do setprop(mkid(eqname_,i),nil)$
  1167. nequ_:=car cop$
  1168. for each c in cadr cop do
  1169. <<pdes:=cons(car c,pdes)$
  1170. for each s in cadr c do
  1171. put(car c,car s,cdr s)$
  1172. for each s in caddr c do
  1173. if s then flag1(car c,s)$
  1174. >>$
  1175. for each c in caddr cop do
  1176. put(car c,'fcts,cdr c)$
  1177. ftem_:=cadddr cop$
  1178. ineq_:=car cddddr cop$
  1179. return reverse pdes$
  1180. end$
  1181. symbolic procedure copy_from_backup(copie)$
  1182. % restore the pde list copie
  1183. % first element must be the old value of nequ_
  1184. % the elements must have the form (p . property_list_of_p)
  1185. begin scalar l,pdes,cop$
  1186. cop:=cadr copie$
  1187. l:=cop$
  1188. for i:=1:length cop do
  1189. <<pdes:=cons(mkid(eqname_,nequ_),pdes)$
  1190. setprop(car pdes,nil)$
  1191. nequ_:=add1 nequ_>>$
  1192. pdes:=reverse pdes$
  1193. for each p in pdes do
  1194. <<cop:=subst(p,caar l,cop)$
  1195. l:=cdr l>>$
  1196. for each c in cop do
  1197. <<for each s in cadr c do
  1198. put(car c,car s,cdr s)$
  1199. for each s in caddr c do
  1200. if s then flag1(car c,s)$
  1201. >>$
  1202. for each c in caddr copie do
  1203. put(car c,'fcts,cdr c)$
  1204. ftem_:=cadddr copie$
  1205. return pdes$
  1206. end$
  1207. symbolic procedure deletepde(pdes)$
  1208. begin scalar s,ps$
  1209. ps:=promptstring!*$
  1210. promptstring!*:=""$
  1211. terpri()$
  1212. write "pde to be deleted: "$
  1213. s:=termread()$
  1214. promptstring!*:=ps$
  1215. if member(s,pdes) then setprop(s,nil)$
  1216. return delete(s,pdes)$
  1217. end$
  1218. symbolic procedure addfunction(ft)$
  1219. begin scalar f,l,ps$
  1220. ps:=promptstring!*$
  1221. promptstring!*:=""$
  1222. terpri()$
  1223. write "What is the name of the new function? "$
  1224. terpri()$
  1225. write "(terminate with Enter, no ; or $) "$
  1226. f:=termread()$
  1227. depl!*:=delete(assoc(f,depl!*),depl!*)$
  1228. terpri()$
  1229. write "Give a list of variables ",f," depends on, for example x,y,z; "$
  1230. terpri()$
  1231. write "If ",f," shall be constant then just input ; "$
  1232. l:=termxread()$
  1233. if (pairp l) and (car l='!*comma!*) then l:=cdr l;
  1234. if pairp l then depl!*:=cons(cons(f,l),depl!*) else
  1235. if l then depl!*:=cons(list(f,l),depl!*)$
  1236. ft:=fctinsert(f,ft)$
  1237. promptstring!*:=ps$
  1238. return ft
  1239. end$
  1240. symbolic procedure change_pde_flag(pdes)$
  1241. begin scalar p,fla$
  1242. repeat <<
  1243. terpri()$
  1244. write "From which PDE do you want to change a flag, e.g. e23?"$
  1245. terpri()$
  1246. p:=termread()$
  1247. >> until not freeof(pdes,p)$
  1248. repeat <<
  1249. terpri()$
  1250. write "Type in one of the following flags which should be flipped:"$
  1251. terpri()$
  1252. write allflags_;
  1253. terpri()$
  1254. fla:=termread()$
  1255. >> until not freeof(allflags_,fla)$
  1256. if flagp(p,fla) then remflag1(p,fla)
  1257. else flag(list(p),fla)
  1258. end$
  1259. symbolic procedure write_in_file(pdes,ftem)$
  1260. begin scalar p,pl,s,h,ps,wn$
  1261. ps:=promptstring!*$
  1262. promptstring!*:=""$
  1263. terpri()$
  1264. write "Enter a list of equations, like e2,e5,e35; from: "$terpri()$
  1265. fctprint pdes$terpri()$
  1266. write "To write all equations just enter ; "$terpri()$
  1267. repeat <<
  1268. s:=termxread()$
  1269. h:=s;
  1270. if s=nil then pl:=pdes else
  1271. if s and (car s='!*comma!*) then <<
  1272. s:=cdr s;
  1273. pl:=nil;h:=nil$
  1274. if (null s) or pairp s then <<
  1275. for each p in s do
  1276. if member(p,pdes) then pl:=cons(p,pl);
  1277. h:=setdiff(pl,pdes);
  1278. >> else h:=s;
  1279. >>;
  1280. if h then <<write "These are no equations: ",h," Try again."$terpri()>>$
  1281. >> until null h$
  1282. write"Shall the name of the equation be written? (y/n) "$
  1283. repeat s:=termread()
  1284. until (s='y) or (s='Y) or (s='n) or (s='N)$
  1285. if (s='y) or (s='Y) then wn:=t$
  1286. write"Please give the name of the file (without ;) : "$
  1287. s:=termread()$
  1288. off nat;
  1289. out s;
  1290. for each h in ftem do
  1291. if assoc(h,depl!*) then <<
  1292. p:=pl;
  1293. while p and freeof(get(car p,'val),h) do p:=cdr p;
  1294. if p then <<
  1295. write"depend ",h$
  1296. for each v in cdr assoc(h,depl!*) do write ",",v$
  1297. write"$"$terpri()
  1298. >>
  1299. >>$
  1300. if wn then
  1301. for each h in pl do algebraic write h,":=",lisp get(h,'val)
  1302. else
  1303. for each h in pl do algebraic write lisp get(h,'val)$
  1304. write"end$"$terpri()$
  1305. shut s;
  1306. on nat;
  1307. promptstring!*:=ps$
  1308. end$
  1309. symbolic procedure replacepde(pdes,ftem,vl)$
  1310. begin scalar p,q,ex,ps,h$
  1311. ps:=promptstring!*$
  1312. promptstring!*:=""$
  1313. repeat <<
  1314. terpri()$
  1315. write "Is there a (further) new function in the changed/new PDE that"$
  1316. terpri()$
  1317. write "is to be calculated (y/n)? "$
  1318. p:=termread()$
  1319. if (p='y) or (p='Y) then ftem:=addfunction(ftem)
  1320. >> until (p='n) or (p='N)$
  1321. terpri()$
  1322. write "If you want to replace a pde then type its name, e.g. e23."$
  1323. terpri()$
  1324. write "If you want to add a pde then type `new_pde'. "$
  1325. terpri()$
  1326. write "In both cases terminate with Enter (no ; or $) : "$
  1327. p:=termread()$
  1328. if (p='NEW_PDE) or member(p,pdes) then
  1329. <<terpri()$write "Input of a value for "$
  1330. if p='new_pde then write "the new pde."
  1331. else write p,"."$
  1332. terpri()$
  1333. write "You can use names of other pds, e.g. 3*e12 - df(e13,x)."$
  1334. terpri()$
  1335. write "Terminate the expression with ; or $ : "$
  1336. terpri()$
  1337. ex:=termxread()$
  1338. for each a in pdes do ex:=subst(get(a,'val),a,ex)$
  1339. terpri()$
  1340. write "Do you want the equation to be"$terpri()$
  1341. write "- left completely unchanged"$
  1342. terpri()$
  1343. write " (e.g. to keep the structure of a product to "$
  1344. terpri()$
  1345. write " investigate subcases) (1)"$
  1346. terpri()$
  1347. write "- simplified (e.g. e**log(x) -> x) without"$
  1348. terpri()$
  1349. write " dropping non-zero factors and denominators"$
  1350. terpri()$
  1351. write " (e.g. to introduce integrating factors) (2)"$
  1352. terpri()$
  1353. write "- simplified completely (3) "$
  1354. h:=termread()$
  1355. if h=2 then ex:=reval ex$
  1356. if h<3 then h:=nil
  1357. else h:=t$
  1358. if p neq 'NEW_PDE then <<setprop(p,nil)$pdes:=delete(p,pdes)>>$
  1359. q:=mkeq(ex,ftem,vl,allflags_,h,list(0))$
  1360. terpri()$write q$
  1361. if p='NEW_PDE then write " is added"
  1362. else write " replaces ",p$
  1363. pdes:=eqinsert(q,pdes)>>
  1364. else <<terpri()$
  1365. write "A pde ",p," does not exist! (Back to previous menu)">>$
  1366. promptstring!*:=ps$
  1367. return list(pdes,ftem)
  1368. end$
  1369. symbolic procedure selectpdes(pdes,n)$
  1370. % interactive selection of n pdes
  1371. % n may be an integer or nil. If nil then the
  1372. % number of pdes is free.
  1373. if pdes then
  1374. begin scalar l,s,ps,m$
  1375. ps:=promptstring!*$
  1376. promptstring!*:=""$
  1377. terpri()$
  1378. if null n then <<
  1379. write "How many equations do you want to select? "$terpri()$
  1380. write "(number <ENTER>) : "$terpri()$
  1381. n:=termread()$
  1382. >>$
  1383. write "Please select ",n," equation"$
  1384. if n>1 then write "s"$write " from: "$
  1385. fctprint pdes$terpri()$
  1386. m:=0$
  1387. s:=t$
  1388. while (m<n) and s do
  1389. <<m:=add1 m$
  1390. if n>1 then write m,". "$
  1391. write "pde: "$
  1392. s:=termread()$
  1393. while not member(s,pdes) do
  1394. <<write "Error!!! Please select a pde from: "$
  1395. fctprint pdes$
  1396. terpri()$if n>1 then write m,". "$
  1397. write "pde: "$
  1398. s:=termread()>>$
  1399. if s then
  1400. <<pdes:=delete(s,pdes)$
  1401. l:=cons(s,l)>> >>$
  1402. promptstring!*:=ps$
  1403. return reverse l$
  1404. end$
  1405. symbolic operator nodepnd$
  1406. symbolic procedure nodepnd(fl)$
  1407. for each f in cdr fl do
  1408. depl!*:=delete(assoc(reval f,depl!*),depl!*)$
  1409. symbolic operator err_catch_sub$
  1410. symbolic procedure err_catch_sub(h2,h6,h3)$
  1411. % do sub(h2=h6,h3) with error catching
  1412. begin scalar h4,h5;
  1413. h4 := list('EQUAL,h2,h6);
  1414. h5:=errorset({'subeval,mkquote{reval h4,
  1415. reval h3 }},nil,nil)
  1416. where !*protfg=t;
  1417. erfg!*:=nil;
  1418. return if errorp h5 then nil
  1419. else car h5
  1420. end$
  1421. symbolic operator low_mem$
  1422. % if garbage collection recovers only 500000 cells then backtrace
  1423. % to be used only on workstations, not PCs i.e. under LINUX, Windows
  1424. symbolic procedure newreclaim()$
  1425. <<oldreclaim();
  1426. if (known!-free!-space() < 500000 ) then backtrace()
  1427. >>$
  1428. symbolic procedure low_mem()$
  1429. if not( getd 'oldreclaim) then <<
  1430. copyd('oldreclaim,'!%reclaim);
  1431. copyd('!%reclaim,'newreclaim);
  1432. >>$
  1433. symbolic operator polyansatz$
  1434. symbolic procedure polyansatz(ev,iv,fn,ordr)$
  1435. % ev, iv are algebraic mode lists
  1436. % generates a polynomial in the variables ev of order ordr
  1437. % with functions of the variables iv
  1438. begin scalar a,fi,el1,el2,f,fl,p,pr;
  1439. a:=reval list('EXPT,cons('PLUS,cons(1,cdr ev)),ordr)$
  1440. a:=reverse cdr a$
  1441. fi:=0$
  1442. iv:=cdr iv$
  1443. for each el1 in a collect <<
  1444. if (not pairp el1) or
  1445. (car el1 neq 'TIMES) then el1:=list el1
  1446. else el1:=cdr el1;
  1447. f:=newfct(fn,iv,fi);
  1448. fi:=add1 fi;
  1449. fl:=cons(f,fl)$
  1450. pr:=list f$
  1451. for each el2 in el1 do
  1452. if not fixp el2 then pr:=cons(el2,pr);
  1453. if length pr>1 then pr:=cons('TIMES,pr)
  1454. else pr:=car pr;
  1455. p:=cons(pr,p)
  1456. >>$
  1457. p:=reval cons('PLUS,p)$
  1458. return list('LIST,p,cons('LIST,fl))
  1459. end$
  1460. symbolic operator polyans$
  1461. symbolic procedure polyans(ordr,dgr,x,y,d_y,fn)$
  1462. % generates a polynom
  1463. % for i:=0:dgr sum fn"i"(x,y,d_y(1),..,d_y(ordr-1))*d_y(ordr)**i
  1464. % with fn as the function names and d_y as names or derivatives of y
  1465. % w.r.t. x
  1466. begin scalar ll,fl,a,i,f$
  1467. i:=sub1 ordr$
  1468. while i>0 do
  1469. <<ll:=cons(list(d_y,i),ll)$
  1470. i:=sub1 i>>$
  1471. ll:=cons(y,ll)$
  1472. ll:=reverse cons(x,ll)$
  1473. fl:=nil$
  1474. i:=0$
  1475. while i<=dgr do
  1476. <<f:=newfct(fn,ll,i)$
  1477. fl:=(f . fl)$
  1478. a:=list('PLUS,list('TIMES,f,list('EXPT,list(d_y,ordr),i)),a)$
  1479. i:=add1 i>>$
  1480. return list('list,reval a,cons('list,fl))
  1481. end$ % of polyans
  1482. symbolic operator sepans$
  1483. symbolic procedure sepans(kind,v1,v2,fn)$
  1484. % Generates a separation ansatz
  1485. % v1,v2 = lists of variables, fn = new function name + index added
  1486. % The first variable of v1 occurs only in one sort of the two sorts of
  1487. % functions and the remaining variables of v1 in the other sort of
  1488. % functios.
  1489. % The variables of v2 occur in all functions.
  1490. % Returned is a sum of products of each one function of both sorts.
  1491. % form: fn1(v11;v21,v22,v23,..)*fn2(v12,..,v1n;v21,v22,v23,..)+...
  1492. % the higher "kind", the more general and difficult the ansatz is
  1493. % kind = 0 is the full case
  1494. begin scalar n,vl1,vl2,h1,h2,h3,h4,fl$
  1495. if cdr v1 = nil then <<vl1:=cdr v2$vl2:=cdr v2>>
  1496. else <<vl1:=cons(cadr v1,cdr v2)$
  1497. vl2:=append(cddr v1,cdr v2)>>$
  1498. return
  1499. if kind = 0 then <<vl1:=append(cdr v1,cdr v2)$
  1500. h1:=newfct(fn,vl1,'_)$
  1501. list('LIST,h1,list('LIST,h1))>>
  1502. else
  1503. if kind = 1 then <<h1:=newfct(fn,vl1,1)$
  1504. list('LIST,h1,list('LIST,h1))>>
  1505. else
  1506. if kind = 2 then <<h1:=newfct(fn,vl2,1)$
  1507. list('LIST,h1,list('LIST,h1))>>
  1508. else
  1509. if kind = 3 then <<h1:=newfct(fn,vl1,1)$
  1510. h2:=newfct(fn,vl2,2)$
  1511. list('LIST,reval list('PLUS,h1,h2),
  1512. list('LIST,h1,h2))>>
  1513. else
  1514. if kind = 4 then <<h1:=newfct(fn,vl1,1)$
  1515. h2:=newfct(fn,vl2,2)$
  1516. list('LIST,reval list('TIMES,h1,h2),
  1517. list('LIST,h1,h2))>>
  1518. else
  1519. if kind = 5 then <<h1:=newfct(fn,vl1,1)$
  1520. h2:=newfct(fn,vl2,2)$
  1521. h3:=newfct(fn,vl1,3)$
  1522. list('LIST,reval list('PLUS,list('TIMES,h1,h2),h3),
  1523. list('LIST,h1,h2,h3))>>
  1524. else
  1525. if kind = 6 then <<h1:=newfct(fn,vl1,1)$
  1526. h2:=newfct(fn,vl2,2)$
  1527. h3:=newfct(fn,vl2,3)$
  1528. list('LIST,reval list('PLUS,list('TIMES,h1,h2),h3),
  1529. list('LIST,h1,h2,h3))>>
  1530. else
  1531. if kind = 7 then <<h1:=newfct(fn,vl1,1)$
  1532. h2:=newfct(fn,vl2,2)$
  1533. h3:=newfct(fn,vl1,3)$
  1534. h4:=newfct(fn,vl2,4)$
  1535. list('LIST,reval list('PLUS,
  1536. list('TIMES,h1,h2),h3,h4),
  1537. list('LIST,h1,h2,h3,h4))>>
  1538. else
  1539. % ansatz of the form FN = FN1(v11,v2) + FN2(v12,v2) + ... + FNi(v1i,v2)
  1540. if kind = 8 then <<n:=1$ vl1:=cdr v1$ vl2:=cdr v2$
  1541. fl:=()$
  1542. while vl1 neq () do <<
  1543. h1:=newfct(fn,cons(car vl1,vl2),n)$
  1544. vl1:=cdr vl1$
  1545. fl:=cons(h1, fl)$
  1546. n:=n+1
  1547. >>$
  1548. list('LIST, cons('PLUS,fl), cons('LIST,fl))>>
  1549. else
  1550. <<h1:=newfct(fn,vl1,1)$
  1551. h2:=newfct(fn,vl2,2)$
  1552. h3:=newfct(fn,vl1,3)$
  1553. h4:=newfct(fn,vl2,4)$
  1554. list('LIST,reval list('PLUS,list('TIMES,h1,h2),
  1555. list('TIMES,h3,h4)),
  1556. list('LIST,h1,h2,h3,h4))>>
  1557. end$ % of sepans
  1558. %
  1559. % Orderings support!
  1560. %
  1561. % change_derivs_ordering(pdes,vl,fl) changes the ordering of the
  1562. % list of derivatives depending on the current ordering (this
  1563. % is detected "automatically" by sort_derivs using the lex_ flag to
  1564. % toggle between total-degree and lexicogrpahic.
  1565. %
  1566. symbolic procedure change_derivs_ordering(pdes,fl,vl)$
  1567. begin scalar p, dl;
  1568. for each p in pdes do <<
  1569. if tr_orderings then <<
  1570. terpri()$
  1571. write "Old: ", get(p,'derivs)$
  1572. >>$
  1573. dl := sort_derivs(get(p,'derivs),fl,vl)$
  1574. if tr_orderings then <<
  1575. terpri()$
  1576. write "New: ", dl$
  1577. >>$
  1578. put(p,'derivs,dl)$
  1579. >>$
  1580. return pdes
  1581. end$
  1582. %
  1583. % check_globals() is used to check that the values with which CRACK is
  1584. % being called are coherent and/or valid.
  1585. %
  1586. % !FIXME! would be nice if we had a list which we could use to store
  1587. % the global variables and the associated valid values.
  1588. %
  1589. symbolic procedure check_globals()$
  1590. begin scalar flag$
  1591. flag := nil$
  1592. if !*batch_mode neq nil and !*batch_mode neq t then
  1593. <<
  1594. terpri()$
  1595. write "!*batch_mode needs to be a boolean: ",
  1596. !*batch_mode," is invalid"$
  1597. flag := t$
  1598. >>$
  1599. if printmenu_ neq nil and printmenu_ neq t then
  1600. <<
  1601. terpri()$
  1602. write "printmenu_ needs to be a boolean: ",
  1603. printmenu_," is invalid"$
  1604. flag := t$
  1605. >>$
  1606. if expert_mode neq nil and expert_mode neq t then
  1607. <<
  1608. terpri()$
  1609. write "expert_mode needs to be a boolean: ",
  1610. expert_mode," is invalid"$
  1611. flag := t$
  1612. >>$
  1613. if repeat_mode neq nil and repeat_mode neq t then
  1614. <<
  1615. terpri()$
  1616. write "repeat_mode needs to be a boolean: ",
  1617. repeat_mode," is invalid"$
  1618. flag := t$
  1619. >>$
  1620. if not fixp genint_ and genint_ neq nil then
  1621. <<
  1622. terpri()$
  1623. write "genint_ needs to be an integer or nil: ",
  1624. genint_," is invalid"$
  1625. flag := t$
  1626. >>$
  1627. if not fixp facint_ and facint_ neq nil then
  1628. <<
  1629. terpri()$
  1630. write "facint_ needs to be an integer or nil: ",
  1631. facint_," is invalid"$
  1632. flag := t$
  1633. >>$
  1634. if potint_ neq nil and potint_ neq t then
  1635. <<
  1636. terpri()$
  1637. write "potint_ needs to be a boolean: ",
  1638. potint_," is invalid"$
  1639. flag := t$
  1640. >>$
  1641. if safeint_ neq nil and safeint_ neq t then
  1642. <<
  1643. terpri()$
  1644. write "safeint_ needs to be a boolean: ",
  1645. safeint_," is invalid"$
  1646. flag := t$
  1647. >>$
  1648. if freeint_ neq nil and freeint_ neq t then
  1649. <<
  1650. terpri()$
  1651. write "potint_ needs to be a boolean: ",
  1652. potint_," is invalid"$
  1653. flag := t$
  1654. >>$
  1655. if not fixp odesolve_ then
  1656. <<
  1657. terpri()$
  1658. write "odesolve_ needs to be an integer: ",
  1659. odesolve_," is invalid"$
  1660. flag := t$
  1661. >>$
  1662. if not fixp max_factor then
  1663. <<
  1664. terpri()$
  1665. write "max_factor needs to be an integer: ",
  1666. max_factor," is invalid"$
  1667. flag := t$
  1668. >>$
  1669. if not fixp gensep_ then
  1670. <<
  1671. terpri()$
  1672. write "gensep_ needs to be an integer: ",
  1673. gensep_," is invalid"$
  1674. flag := t$
  1675. >>$
  1676. if not fixp new_gensep and new_gensep neq nil then
  1677. <<
  1678. terpri()$
  1679. write "new_gensep needs to be an integer or nil: ",
  1680. new_gensep," is invalid"$
  1681. flag := t$
  1682. >>$
  1683. if not fixp subst_0 then
  1684. <<
  1685. terpri()$
  1686. write "subst_0 needs to be an integer: ",
  1687. subst_0," is invalid"$
  1688. flag := t$
  1689. >>$
  1690. if not fixp subst_1 then
  1691. <<
  1692. terpri()$
  1693. write "subst_1 needs to be an integer: ",
  1694. subst_1," is invalid"$
  1695. flag := t$
  1696. >>$
  1697. if not fixp subst_2 then
  1698. <<
  1699. terpri()$
  1700. write "subst_2 needs to be an integer: ",
  1701. subst_2," is invalid"$
  1702. flag := t$
  1703. >>$
  1704. if not fixp subst_3 then
  1705. <<
  1706. terpri()$
  1707. write "subst_3 needs to be an integer: ",
  1708. subst_3," is invalid"$
  1709. flag := t$
  1710. >>$
  1711. if not fixp subst_4 then
  1712. <<
  1713. terpri()$
  1714. write "subst_4 needs to be an integer: ",
  1715. subst_4," is invalid"$
  1716. flag := t$
  1717. >>$
  1718. if not fixp cost_limit5 then
  1719. <<
  1720. terpri()$
  1721. write "cost_limit5 needs to be an integer: ",
  1722. cost_limit5," is invalid"$
  1723. flag := t$
  1724. >>$
  1725. if not fixp max_red_len then
  1726. <<
  1727. terpri()$
  1728. write "max_red_len needs to be an integer: ",
  1729. max_red_len," is invalid"$
  1730. flag := t$
  1731. >>$
  1732. if not fixp pdelimit_0 and pdelimit_0 neq nil then
  1733. <<
  1734. terpri()$
  1735. write "pdelimit_0 needs to be an integer or nil: ",
  1736. pdelimit_0," is invalid"$
  1737. flag := t$
  1738. >>$
  1739. if not fixp pdelimit_1 and pdelimit_1 neq nil then
  1740. <<
  1741. terpri()$
  1742. write "pdelimit_1 needs to be an integer or nil: ",
  1743. pdelimit_1," is invalid"$
  1744. flag := t$
  1745. >>$
  1746. if not fixp pdelimit_2 and pdelimit_2 neq nil then
  1747. <<
  1748. terpri()$
  1749. write "pdelimit_2 needs to be an integer or nil: ",
  1750. pdelimit_2," is invalid"$
  1751. flag := t$
  1752. >>$
  1753. if not fixp pdelimit_3 and pdelimit_3 neq nil then
  1754. <<
  1755. terpri()$
  1756. write "pdelimit_3 needs to be an integer or nil: ",
  1757. pdelimit_3," is invalid"$
  1758. flag := t$
  1759. >>$
  1760. if not fixp pdelimit_4 and pdelimit_4 neq nil then
  1761. <<
  1762. terpri()$
  1763. write "pdelimit_4 needs to be an integer or nil: ",
  1764. pdelimit_4," is invalid"$
  1765. flag := t$
  1766. >>$
  1767. if not numberp length_inc then
  1768. <<
  1769. terpri()$
  1770. write "length_inc needs to be an number: ",
  1771. length_inc," is invalid"$
  1772. flag := t$
  1773. >>$
  1774. if tr_main neq t and tr_main neq nil then
  1775. <<
  1776. terpri()$
  1777. write "tr_main needs to be a boolean: ",
  1778. tr_main," is invalid"$
  1779. flag := t$
  1780. >>$
  1781. if tr_gensep neq t and tr_gensep neq nil then
  1782. <<
  1783. terpri()$
  1784. write "tr_gensep needs to be a boolean: ",
  1785. tr_gensep," is invalid"$
  1786. flag := t$
  1787. >>$
  1788. if tr_genint neq t and tr_genint neq nil then
  1789. <<
  1790. terpri()$
  1791. write "tr_genint needs to be a boolean: ",
  1792. tr_genint," is invalid"$
  1793. flag := t$
  1794. >>$
  1795. if tr_decouple neq t and tr_decouple neq nil then
  1796. <<
  1797. terpri()$
  1798. write "tr_decouple needs to be a boolean: ",
  1799. tr_decouple," is invalid"$
  1800. flag := t$
  1801. >>$
  1802. if tr_redlength neq t and tr_redlength neq nil then
  1803. <<
  1804. terpri()$
  1805. write "tr_redlength needs to be a boolean: ",
  1806. tr_redlength," is invalid"$
  1807. flag := t$
  1808. >>$
  1809. if tr_orderings neq t and tr_orderings neq nil then
  1810. <<
  1811. terpri()$
  1812. write "tr_orderings needs to be a boolean: ",
  1813. tr_orderings," is invalid"$
  1814. flag := t$
  1815. >>$
  1816. if homogen_ neq t and homogen_ neq nil then
  1817. <<
  1818. terpri()$
  1819. write "homogen_ needs to be a boolean: ",
  1820. homogen_," is invalid"$
  1821. flag := t$
  1822. >>$
  1823. if solvealg_ neq t and solvealg_ neq nil then
  1824. <<
  1825. terpri()$
  1826. write "solvealg_ needs to be a boolean: ",
  1827. solvealg_," is invalid"$
  1828. flag := t$
  1829. >>$
  1830. if print_more neq t and print_more neq nil then
  1831. <<
  1832. terpri()$
  1833. write "print_more needs to be a boolean: ",
  1834. print_more," is invalid"$
  1835. flag := t$
  1836. >>$
  1837. if print_all neq t and print_all neq nil then
  1838. <<
  1839. terpri()$
  1840. write "print_all needs to be a boolean: ",
  1841. print_all," is invalid"$
  1842. flag := t$
  1843. >>$
  1844. if logoprint_ neq t and logoprint_ neq nil then
  1845. <<
  1846. terpri()$
  1847. write "logoprint_ needs to be a boolean: ",
  1848. logoprint_," is invalid"$
  1849. flag := t$
  1850. >>$
  1851. if poly_only neq t and poly_only neq nil then
  1852. <<
  1853. terpri()$
  1854. write "poly_only needs to be a boolean: ",
  1855. poly_only," is invalid"$
  1856. flag := t$
  1857. >>$
  1858. if time_ neq t and time_ neq nil then
  1859. <<
  1860. terpri()$
  1861. write "time_ needs to be a boolean: ",
  1862. time_," is invalid"$
  1863. flag := t$
  1864. >>$
  1865. if (not null print_) and (not fixp print_) then
  1866. <<
  1867. terpri()$
  1868. write "print_ needs to be an integer: ",
  1869. print_," is invalid"$
  1870. flag := t$
  1871. >>$
  1872. if not fixp dec_hist then
  1873. <<
  1874. terpri()$
  1875. write "dec_hist needs to be an integer: ",
  1876. dec_hist," is invalid"$
  1877. flag := t$
  1878. >>$
  1879. if not fixp maxalgsys_ then
  1880. <<
  1881. terpri()$
  1882. write "maxalgsys_ needs to be an integer: ",
  1883. maxalgsys_," is invalid"$
  1884. flag := t$
  1885. >>$
  1886. if adjust_fnc neq t and adjust_fnc neq nil then
  1887. <<
  1888. terpri()$
  1889. write "adjust_fnc needs to be a boolean: ",
  1890. adjust_fnc," is invalid"$
  1891. flag := t$
  1892. >>$
  1893. if not vectorp orderings_ and orderings_ neq nil then
  1894. <<
  1895. terpri()$
  1896. write "orderings_ needs to be a vector: ",
  1897. orderings_," is invalid"$
  1898. flag := t$
  1899. >>$
  1900. if simple_orderings neq t and simple_orderings neq nil then
  1901. <<
  1902. terpri()$
  1903. write "simple_orderings needs to be a boolean: ",
  1904. simple_orderings," is invalid"$
  1905. flag := t$
  1906. >>$
  1907. if lex_ neq t and lex_ neq nil then
  1908. <<
  1909. terpri()$
  1910. write "lex_ needs to be a boolean: ",
  1911. lex_," is invalid"$
  1912. flag := t$
  1913. >>$
  1914. if collect_sol neq t and collect_sol neq nil then
  1915. <<
  1916. terpri()$
  1917. write "lex_ needs to be a boolean: ",
  1918. lex_," is invalid"$
  1919. flag := t$
  1920. >>$
  1921. if flag then
  1922. return nil
  1923. else
  1924. return t$
  1925. end$
  1926. endmodule$
  1927. end$