crmain.red 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. %**********************************************************************
  2. module crackstar$
  3. %**********************************************************************
  4. % Main program
  5. % Author: Andreas Brand 1995, updates and extensions by Thomas Wolf
  6. %
  7. % $Id: crmain.red,v 1.34 1998/06/25 18:17:32 tw Exp tw $
  8. %
  9. symbolic operator crack$
  10. symbolic procedure crack(el,il,fl,vl)$
  11. begin scalar l,l1,l2,n,m,ezgcdold,mcdold,gcdold,expold,ratold,
  12. ratargold$
  13. if not check_globals() then
  14. <<
  15. rederr "Some global variables have incorrect values, please check!"$
  16. >>$
  17. if print_ and logoprint_ then <<
  18. terpri()$
  19. write
  20. "This is CRACK - a solver for overdetermined partial ",
  21. "differential equations"$
  22. terpri()$
  23. write "$Revision: 1.34 $ ($Date: 1998/06/25 18:17:32 $)"$terpri()$
  24. write "**********************************************************",
  25. "****************"$
  26. terpri()$
  27. >>$
  28. rulelist_:=if pairp userrules_ then
  29. if pairp crackrules_
  30. then list('LIST,userrules_,crackrules_)
  31. else list('LIST,userrules_)
  32. else
  33. if pairp crackrules_ then
  34. list('LIST,crackrules_)
  35. else nil$
  36. ezgcdold:=!*ezgcd$
  37. gcdold:=!*gcd$
  38. expold:=!*exp$
  39. mcdold:=!*mcd$
  40. ratold:=!*rational$
  41. ratargold:=!*ratarg$
  42. !*ezgcd:=t$
  43. !*gcd:=nil$
  44. !*exp:=t$
  45. !*mcd:=t$
  46. !*rational:=t$
  47. !*ratarg:=t$
  48. fnew_:=nil$
  49. ftem_:=nil$
  50. stop_:=nil$
  51. dec_hist_list:=nil$
  52. level_:=nil$
  53. stepcounter_:=0$
  54. batchcount_:=-1$
  55. n:=time()$
  56. m:=gctime()$
  57. if pairp el and (car el='LIST) then el:=cdr el
  58. else el:=list el$
  59. if pairp fl and (car fl='LIST) then fl:=cdr fl
  60. else fl:=list fl$
  61. if pairp vl and (car vl='LIST) then vl:=cdr vl
  62. else vl:=list vl$
  63. if pairp il and (car il='LIST) then il:=cdr il
  64. else il:=list il$
  65. l1:=el$
  66. for each p in il do l2:=union(ineqsplit(p,fl),l2)$
  67. il:=l2$
  68. vl:=union(reverse argset fl,vl)$
  69. fl:=fctlist(nil,nil,union(fl,nil))$
  70. orderings_:=make_orderings(fl, vl)$ % Orderings support!
  71. if not !*batch_mode then printmenu_:=t$
  72. history_:=nil;
  73. %
  74. % Orderings Note: orderings_prop_list_all() inserts all the valid
  75. % orderings into each of the initial equations, i.e. all equations
  76. % are in all orderings
  77. %
  78. l:=crackmain(mkeqlist(el,fl,vl,allflags_,t,orderings_prop_list_all()),
  79. il,fl,vl)$
  80. if l=list(nil) then l:=nil$
  81. l:=union(l,nil)$
  82. if !*time or time_ then
  83. <<terpri()$write "CRACK needed : ",time()-n," ms GC time : ",
  84. gctime()-m," ms">>$
  85. for i:=1:nequ_ do setprop(mkid(eqname_,i),nil)$
  86. l:=for each a in l collect
  87. <<l1:=nil$
  88. l2:=caddr a$
  89. for each b in cadr a do
  90. if (pairp b) and (car b = 'EQUAL) then l1:=cons(b,l1)
  91. else l2:=cons(b,l2)$
  92. list(car a,l1,l2,cadddr a)>>$
  93. if adjust_fnc and null stop_ then
  94. l:=for each a in l collect if l1:=dropredund(a,fl,vl) then cdr l1
  95. else a$
  96. !*ezgcd:=ezgcdold$
  97. !*gcd:=gcdold$
  98. !*exp:=expold$
  99. !*mcd:=mcdold$
  100. !*rational:=ratold$
  101. !*ratarg:=ratargold$
  102. if print_ and logoprint_ then <<
  103. terpri()$
  104. write "This is the end of the CRACK run"$
  105. terpri()$
  106. write "**********************************************************",
  107. "****************"$
  108. terpri()$
  109. >>$
  110. return if l then
  111. cons('LIST,for each a in l collect
  112. list('LIST,cons('LIST,car a),
  113. cons('LIST,cadr a),
  114. cons('LIST,caddr a),
  115. cons('LIST,cadddr a)))
  116. else list('LIST)
  117. end$
  118. symbolic procedure crackmain(pdes,ineq,forg,vl)$
  119. % Main program
  120. begin scalar result,l,pl,dec_hist_list_copy,%cases_copy,
  121. s,ps,batch_one_step,expert_mode_copy,
  122. loopcount,level_length,optionsl$
  123. level_length:=length level_;
  124. if tr_main and print_ then
  125. <<terpri()$write "start of the main procedure">>$
  126. depl_copy_:=depl!*$
  127. dec_hist_list_copy:=dec_hist_list$
  128. expert_mode_copy:=expert_mode$
  129. contradiction_:=nil$
  130. ineq_:=ineq$ % global list of nonvanishing de's
  131. ftem_:=fctlist(ftem_,pdes,forg)$ % global list of free functions
  132. if printmenu_ then printmainmenu()$
  133. printmenu_:=nil$
  134. repeat
  135. <<pl:=proc_list_$ % global list of procedures
  136. stop_:=nil$
  137. ftem_:=fctlist(ftem_,pdes,forg)$
  138. vl:=var_list(pdes,forg,vl)$
  139. if !*batch_mode or batch_one_step or (batchcount_>=stepcounter_) then
  140. <<if !*batch_mode then
  141. if print_more then
  142. print_pde_fct_ineq(pdes,ineq_,
  143. append(forg,setdiff(ftem_,forg)),vl)
  144. else print_statistic(pdes,append(forg,setdiff(ftem_,forg)))$
  145. stepcounter_:=add1 stepcounter_$
  146. if tr_main and print_ then
  147. <<terpri()$terpri()$write "Step ",stepcounter_,":"$terpri()>>$
  148. batch_one_step:=nil$
  149. expert_mode:=nil$
  150. while pl do <<
  151. if tr_main and print_ and print_more then
  152. if pairp(l:=get(car pl,'description)) then <<
  153. for each a in l do if a then write a$
  154. write " : "
  155. >> else
  156. write "trying ",car pl," : "$
  157. l:=apply(car pl,list list(pdes,forg,vl,pdes))$
  158. if l and not contradiction_ then <<
  159. if length l = 1 % before the test was: if cases_
  160. then result:= car l % car l is a list of crackmain results
  161. % resulting from investigating subcases
  162. else <<pdes:=car l$ forg:=cadr l>>$ % no case-splitting
  163. pl:=nil$
  164. >> else
  165. if contradiction_ then pl:=nil
  166. else <<
  167. pl:=cdr pl$
  168. if tr_main and print_ and print_more then
  169. <<write " no success"$terpri()>>$
  170. if not pl then stop_:=t
  171. >>
  172. >>
  173. >>
  174. else
  175. <<rds nil$wrs nil$
  176. ps:=promptstring!*$
  177. promptstring!*:="selected item: "$
  178. terpri()$s:=termread()$
  179. expert_mode:=expert_mode_copy$
  180. if s='m then printmainmenu()
  181. else if s='h then printhelp()
  182. else if s='a then batch_one_step:=t
  183. else if s='e then <<expert_mode:=not expert_mode$
  184. expert_mode_copy:=expert_mode>>
  185. else if s='l then <<repeat_mode:=not repeat_mode>>
  186. else if s='g then
  187. <<promptstring!*:="number of steps: "$
  188. s:=termread()$
  189. promptstring!*:="selected item: "$
  190. if fixp(s) then batchcount_:=sub1 stepcounter_+s
  191. else <<write "wrong input!!!"$terpri()>>
  192. >>
  193. else if s='q then stop_:=t
  194. else if s='x then !*batch_mode:=t
  195. else if s='p then
  196. print_pde_ineq(if expert_mode then selectpdes(pdes,1)
  197. else pdes,
  198. ineq_)
  199. else if s='o then
  200. <<
  201. % Orderings support!
  202. % Added return value to optionsmenu to allow changing of the
  203. % variables list and pdes list
  204. if tr_orderings then
  205. <<
  206. terpri()$ write "vl : ", vl$
  207. terpri()$ write "ftem_ : ", ftem_$
  208. >>$
  209. optionsl := optionsmenu(vl,pdes)$
  210. vl := car optionsl$
  211. pdes := cdr optionsl$
  212. if tr_orderings then
  213. <<
  214. terpri()$ write "pdes : ", pdes$
  215. terpri()$ write "vl : ", vl$
  216. terpri()$ write "ftem_ : ", ftem_$
  217. >>$
  218. >>
  219. else if s='c then change_pde_flag(pdes)
  220. else if s='w then write_in_file(pdes,ftem_)
  221. else if s='proc then printproclist()
  222. else if s='f then
  223. <<print_fcts(append(forg,setdiff(ftem_,forg)),vl)$
  224. terpri()>>
  225. else if s='s then <<
  226. print_level()$
  227. print_statistic(pdes,append(forg,setdiff(ftem_,forg)))
  228. >>
  229. else if s='d then
  230. pdes:=deletepde(pdes)
  231. else if s='r then
  232. <<pdes:=replacepde(pdes,ftem_,vl);
  233. ftem_:=cadr pdes;
  234. pdes:=car pdes>>
  235. else if numberp s and (s>0) and (s<=length proc_list_) then
  236. <<loopcount:=0;
  237. repeat
  238. <<l:=apply(nth(pl,s),list list(pdes,forg,vl,pdes))$
  239. if l and not contradiction_ then
  240. <<stepcounter_:=add1 stepcounter_$
  241. loopcount:=add1 loopcount$
  242. if length l = 1 % before the test was: if cases_
  243. then result:=car l % car l is a list of crackmain results
  244. % resulting from investigating subcases
  245. else <<pdes:=car l$ forg:=cadr l>>$ % no case-splitting
  246. terpri()>>
  247. else if (not contradiction_) and (loopcount=0) then
  248. <<write "no success"$terpri()>>
  249. >>
  250. until not repeat_mode or not l or contradiction_>>
  251. else
  252. <<write "illegal input: '",s,"'"$terpri()>>$
  253. promptstring!*:=ps$
  254. if ifl!* then rds cadr ifl!*$
  255. if ofl!* then wrs cdr ofl!*$
  256. >>
  257. >>
  258. until contradiction_ or result or stop_ or not pdes$
  259. if not (contradiction_ or result) then <<
  260. if print_ then <<terpri()$
  261. terpri()$ write">>>>>>>>> Solution"$
  262. if level_ then <<
  263. write" of level "$
  264. for each m in reverse level_ do write m,"."$
  265. >>$
  266. write" : "$
  267. >>$
  268. ftem_:=fctlist(ftem_,pdes,forg)$
  269. forg:=forg_int(forg,ftem_)$
  270. print_pde_fct_ineq(pdes,ineq_,append(forg,setdiff(ftem_,forg)),vl)$
  271. algebraic
  272. crack_out(lisp(cons('LIST,for each a in pdes collect get(a,'val))),
  273. lisp(cons('LIST,setdiff(forg,ftem_))),
  274. lisp(cons('LIST,ftem_)),
  275. lisp(cons('LIST,ineq_)))$
  276. result:=if collect_sol then
  277. list list(for each a in pdes collect get(a,'val),
  278. forg,setdiff(ftem_,forg),ineq_)
  279. else list(nil)$
  280. >>$
  281. dec_hist_list:=dec_hist_list_copy$
  282. if tr_main and print_ then
  283. <<terpri()$write "end of the main procedure"$terpri()>>$
  284. l:=(length level_)+1-level_length;
  285. for s:=1:l do if level_ then level_:=cdr level_$
  286. return result$
  287. end$
  288. algebraic procedure crack_out(eqns,asigns,freef,ineq)$
  289. begin
  290. end$
  291. symbolic procedure priproli(proclist)$
  292. begin integer i$
  293. scalar l$
  294. for each a in proclist do
  295. <<i:=add1 i$
  296. terpri()$
  297. if i<10 then write " "$
  298. write i$
  299. write " : "$
  300. if pairp(l:=get(a,'description)) then
  301. (for each s in l do if s then write s)
  302. else write a>>$
  303. terpri()$
  304. end$
  305. symbolic procedure priprolinr(proclist,fullproclist)$
  306. begin integer i,j$
  307. scalar cfpl$
  308. j:=0;
  309. for each a in proclist do <<
  310. j:=j+1;
  311. i:=1;
  312. cfpl:=fullproclist;
  313. while cfpl and (a neq car cfpl) do <<i:=add1 i$cfpl:=cdr cfpl>>$
  314. if cfpl then <<if (j>1) then write ","$
  315. if (i<10) then write " "$
  316. if i=((i/30)*30) then terpri()$
  317. write i>>$
  318. >>$
  319. terpri()$
  320. end$
  321. symbolic procedure changeproclist()$
  322. begin scalar l,p,err;
  323. terpri()$
  324. write "Please type in a list of the numbers 1 .. ",
  325. length full_proc_list_,", like 1,2,5,4,..,15; which"$
  326. terpri()$
  327. write"will be the new priority list of procedures done by CRACK."$
  328. terpri()$
  329. write"Numbers stand for the following actions:"$terpri()$
  330. priproli(full_proc_list_)$
  331. terpri()$write"The current list is:"$
  332. priprolinr(proc_list_,full_proc_list_)$
  333. l:=termxread()$
  334. if fixp l and
  335. l <= length full_proc_list_ then l:=list('!*comma!*,l);
  336. if (not pairp l) or
  337. (car l neq '!*comma!*)
  338. then
  339. <<terpri()$write"Error: not a legal list of elements.";
  340. err:=t>>
  341. else <<
  342. l:=cdr l;
  343. while l do <<
  344. if (not fixp car l) or
  345. (car l > length full_proc_list_)
  346. then
  347. <<terpri()$write "Error: ",car l," is not an element number.";
  348. l:=nil$
  349. err:=t>>
  350. else <<
  351. p:=union(list nth(full_proc_list_,car l),p);
  352. l:=cdr l
  353. >>
  354. >>;
  355. >>;
  356. if not err then
  357. <<proc_list_:=reverse p;
  358. terpri()$write"The new order of procedures:"$
  359. priproli(proc_list_)>>
  360. else
  361. <<terpri()$write "The procedure list is still unchanged."$terpri()>>
  362. end$
  363. symbolic procedure printproclist()$
  364. begin
  365. terpri()$
  366. write "Please select one of the following items"$
  367. priproli(proc_list_)
  368. end$
  369. symbolic procedure printmainmenu()$
  370. <<printproclist()$
  371. write "f : Print functions and variables"$
  372. terpri()$write "p : Print pdes"$
  373. terpri()$write "s : Print statistics"$
  374. terpri()$write "x : Exit interactive mode"$
  375. terpri()$write "q : Quit"$
  376. terpri()$write "h : Help"$terpri()>>$
  377. symbolic procedure printhelp()$
  378. <<
  379. terpri()$write "proc : Print list of procedures"$
  380. terpri()$write "f : Print functions and variables"$
  381. terpri()$write "p : Print pdes"$
  382. terpri()$write "s : Print statistics"$
  383. terpri()$write "a : Do one step automatically"$
  384. terpri()$write "g : Go on for a number of steps automatically"$
  385. terpri()$write "l : Toggle repeating mode to : "$
  386. if repeat_mode then write "SINGLE"
  387. else write "LOOP"$
  388. terpri()$write "e : Toggle equation selection to : "$
  389. if expert_mode then write "AUTOMATIC"
  390. else write "USER"$
  391. terpri()$write "d : Delete one pde"$
  392. terpri()$write "r : Replace or add one pde"$
  393. terpri()$write "c : Change a flag of one pde"$
  394. terpri()$write "w : Write equations into a file"$
  395. terpri()$write "x : Exit interactive mode"$
  396. terpri()$write "o : Enter a menu for the setting of options & flags"$
  397. terpri()$write "q : Quit crack"$
  398. terpri()$write "m : Menu"$
  399. terpri()$write "h : Help"$terpri()>>$
  400. %
  401. % Orderings support!
  402. %
  403. % For orderings we need to modify pdes and vl which means that we
  404. % require them as options. We return a list (vl, pdes) with the
  405. % possibly modified values.
  406. %
  407. symbolic procedure optionsmenu(vl,pdes)$
  408. begin scalar s,ps,newvl,newftem$
  409. ps:=promptstring!*$
  410. while s neq 'x do
  411. <<
  412. terpri()$
  413. write "cp : Change the priorities of procedures"$
  414. terpri()$
  415. % Orderings support!
  416. write "o : Toggle ordering (",
  417. if lex_ then "Lexicographic" else "Total-degree",
  418. " ordering in use)"$
  419. terpri()$
  420. write "ov : Change ordering on variables"$
  421. terpri()$
  422. write "of : Change ordering on functions"$
  423. terpri()$
  424. write "op : Print current ordering"$
  425. terpri()$
  426. % END Orderings support!
  427. write "p : Maximal length of an expression to be printed (",print_,")"$
  428. terpri()$
  429. write "pm : ",
  430. if print_more then "Do not p" else "P",
  431. "rint more informations about the pdes"$
  432. terpri()$
  433. write "pa : ",
  434. if print_all then "Do not p" else "P",
  435. "rint all informations about the pdes"$
  436. terpri()$
  437. write "e : Basic name of new generated equations (",eqname_,")"$
  438. terpri()$
  439. write "f : Basic name of new functions and constants (",fname_,")"$
  440. terpri()$
  441. write "tm : ",
  442. if tr_main then "Do not t" else "T",
  443. "race main procedure"$
  444. terpri()$
  445. write "ts : ",
  446. if tr_gensep then "Do not t" else "T",
  447. "race generalized separation"$
  448. terpri()$
  449. write "ti : ",
  450. if tr_genint then "Do not t" else "T",
  451. "race generalized integration"$
  452. terpri()$
  453. write "td : ",
  454. if tr_decouple then "Do not t" else "T",
  455. "race decoupling process"$
  456. terpri()$
  457. write "tr : ",
  458. if tr_redlength then "Do not t" else "T",
  459. "race length reduction process"$
  460. terpri()$
  461. % Orderings support!
  462. write "to : ",
  463. if tr_orderings then "Do not t" else "T",
  464. "race orderings process"$
  465. terpri()$
  466. write "na : Change output to "$
  467. if !*nat then write "OFF nat"
  468. else write "ON nat"$
  469. terpri()$
  470. write "fc : Print no of free cells"$
  471. terpri()$
  472. write "br : Break"$
  473. terpri()$
  474. write "r : Input of an assignment"$
  475. terpri()$
  476. write "x : Exit this options menu"$
  477. terpri()$terpri()$
  478. s:=termread()$
  479. if s='cp then changeproclist()
  480. else if s='p then
  481. <<promptstring!*:="Print length : "$
  482. s:=termread()$
  483. if not s or fixp(s) then print_:=s
  484. else
  485. <<terpri()$write "Print length must be NIL or an integer!!!"$terpri()>>
  486. >>
  487. % Orderings support!
  488. else if s='o then <<
  489. lex_:=not lex_$
  490. %
  491. % Go through the list of equations and change all the
  492. % list of derivatives using sort_derivs() [new version
  493. % by Thomas]
  494. %
  495. pdes := change_derivs_ordering(pdes,ftem_,vl)$
  496. >>
  497. else if s='op then <<
  498. terpri()$
  499. write "Current orderings are :"$
  500. terpri()$
  501. write "Functions : ", ftem_$
  502. terpri()$
  503. write "Variables : ", vl$
  504. >>
  505. else if s='ov then <<
  506. terpri()$
  507. write "Current variable ordering is :", vl$
  508. terpri()$
  509. promptstring!*:="New variable ordering : "$
  510. newvl := termxread()$
  511. % !FIXME! Now we need to convert it to the correct form for vl
  512. vl := cdr newvl$
  513. % !FIXME! Do we need to change the derivs too?
  514. pdes := change_derivs_ordering(pdes,ftem_,vl)$
  515. if tr_orderings then <<
  516. terpri()$
  517. write "New variable list: ", vl$
  518. >>$
  519. >>
  520. else if s='of then <<
  521. terpri()$
  522. write "Current function ordering is :", ftem_$
  523. terpri()$
  524. promptstring!*:="New function ordering : "$
  525. newftem := termxread()$
  526. % !FIXME! Now we need to convert it to the correct form for ftem_
  527. ftem_ := cdr newftem$
  528. % !FIXME! Do we need to change the derivs too?
  529. pdes := change_derivs_ordering(pdes,ftem_,vl)$
  530. if tr_orderings then <<
  531. terpri()$
  532. write "New functions list: ", ftem_$
  533. >>
  534. >>
  535. else if s='to then tr_orderings:=not tr_orderings
  536. %
  537. else if s='pm then print_more:=not print_more
  538. else if s='pa then print_all:=not print_all
  539. else if s='tm then tr_main:=not tr_main
  540. else if s='ts then tr_gensep:=not tr_gensep
  541. else if s='ti then tr_genint:=not tr_genint
  542. else if s='td then tr_decouple:=not tr_decouple
  543. else if s='tr then tr_redlength:=not tr_redlength
  544. else if s='e then
  545. <<promptstring!*:="Equation name : "$
  546. s:=termread()$
  547. if s and idp s
  548. then eqname_:=s
  549. else
  550. <<terpri()$write "Equation name must be an identifier!!!"$terpri()>>
  551. >>
  552. else if s='f then
  553. <<promptstring!*:="Function name : "$
  554. s:=termread()$
  555. if s and idp s
  556. then fname_:=s
  557. else
  558. <<terpri()$write "Function name must be an identifier!!!"$terpri()>>
  559. >>
  560. else if s='na then !*nat:=not !*nat
  561. else if s='fc then <<
  562. reclaim()$ % do garbage collection
  563. terpri()$write known!-free!-space()," free cells"$terpri()
  564. >>
  565. else if s='br then <<
  566. terpri()$write"This is Standard Lisp. Return to Reduce by Ctrl D."$
  567. terpri()$
  568. standardlisp()
  569. >>
  570. else if s='r then
  571. <<write "Type in any R-Lisp assignment of the form";terpri()$
  572. write "LIST('SETQ,'variable_name,value) "$ terpri()$
  573. promptstring!*:="The expression: "$
  574. s:=termxread()$
  575. if pairp s and (car s='SETQ) and idp cadr s
  576. then set(cadr s,eval quote reval caddr s)>>$
  577. promptstring!*:=ps$
  578. >>$
  579. % Orderings Support!
  580. return vl . pdes
  581. end$
  582. symbolic procedure to_do(arglist)$
  583. if to_do_list then
  584. begin scalar p,l$
  585. p:=car to_do_list;
  586. to_do_list:=cdr to_do_list;
  587. if tr_main and print_ and print_more then
  588. if pairp(l:=get(car p,'description)) then
  589. <<for each a in l do if a then write a$
  590. write " : ">>
  591. else write "trying ",car p," : "$
  592. l:=apply(car p,list(list(car arglist,cadr arglist,
  593. caddr arglist,cadddr cdr p)))$
  594. if not l then l:=arglist$
  595. return l$
  596. end$
  597. symbolic procedure subst_derivative(arglist)$
  598. % Substitution of a derivative of a function by an new function
  599. % in all pdes and in forg
  600. begin scalar f,l,q,g,h,pdes,forg$
  601. pdes:=car arglist$
  602. forg:=cadr arglist$
  603. l:=check_subst_df(pdes,forg)$
  604. for each d in l do
  605. <<f:=newfct(fname_,fctargs cadr d,nfct_)$
  606. nfct_:=add1 nfct_$
  607. ftem_:=reverse fctinsert(f,reverse delete(cadr d,ftem_))$
  608. if print_ then
  609. <<terpri()$write "replacing "$
  610. fctprint1 d$
  611. write " by "$fctprint list f>>$
  612. for each s in pdes do dfsubst_update(f,d,s)$
  613. % integrating f in order to substitute for cadr d
  614. % in ineq_
  615. h:=cddr d;
  616. g:=f;
  617. while h do <<
  618. for r:=1:(if (length h =1) or
  619. ((length h > 1) and (not fixp cadr h))
  620. then 1
  621. else (cadr h)
  622. ) do
  623. g:=list('PLUS,gensym(),list('INT,g,car h));
  624. h:=cdr h;
  625. if h and (fixp car h) then h:=cdr h
  626. >>;
  627. % now the substitution in ineq_
  628. ineq_:=for each s in ineq_ collect reval subst(g,cadr d,s);
  629. if member(cadr d,forg) then
  630. <<q:=mkeq(list('PLUS,d,list('MINUS,f)),
  631. list(f,cadr d),fctargs f,allflags_,nil,list(0))$
  632. remflag1(q,'to_eval)$
  633. put(q,'not_to_eval,f)$
  634. pdes:=eqinsert(q,pdes)>>$
  635. forg:=dfsubst_forg(f,g,cadr d,forg)$
  636. >>$
  637. return if l then list(pdes,forg)
  638. else nil
  639. end$
  640. symbolic procedure undo_subst_derivative(arglist)$
  641. % undo Substitution of a derivative of a function by an new function
  642. % in all pdes and in forg
  643. begin scalar success$
  644. for each p in car arglist do
  645. if get(p,'not_to_eval) then
  646. <<remprop(p,'not_to_eval)$
  647. flag(list p,'to_eval)$
  648. success:=t>>$
  649. return if success then arglist
  650. else nil
  651. end$
  652. symbolic procedure subst_level_0(arglist)$
  653. % Substitution of a function by an expression of at most length subst_0
  654. % depending on less variables than the function,
  655. % not allowing case distinctions,
  656. % ftem-dep. coefficient allowed
  657. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  658. subst_0,pdelimit_0,t,nil,t,nil,nil,nil)$
  659. symbolic procedure subst_level_05(arglist)$
  660. % Substitution of a function by an expression of at most length subst_0
  661. % depending on less variables than the function,
  662. % not allowing case distinctions,
  663. % ftem-dep. coefficient allowed
  664. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  665. subst_0,pdelimit_0,nil,t,t,nil,nil,nil)$
  666. symbolic procedure subst_level_1(arglist)$
  667. % Substitution of a function by an expression of at most length subst_1
  668. % depending on less variables than the function,
  669. % allowing case distinctions,
  670. % ftem-dep. coefficient allowed
  671. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  672. subst_1,pdelimit_1,t,nil,nil,nil,nil,nil)$
  673. symbolic procedure subst_level_2(arglist)$
  674. % Substitution of a function by an expression of at most length subst_2
  675. % depending on less variables than the function,
  676. % allowing case distinctions,
  677. % ftem-dep. coefficient allowed
  678. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  679. subst_2,pdelimit_2,t,nil,nil,nil,nil,nil)$
  680. symbolic procedure subst_level_3(arglist)$
  681. % Substitution of a function by an expression of at most length subst_1
  682. % depending on all variables,
  683. % allowing case distinctions,
  684. % ftem-dep. coefficient allowed
  685. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  686. subst_3,pdelimit_3,nil,nil,nil,nil,nil,nil)$
  687. symbolic procedure subst_level_33(arglist)$
  688. % Substitution of a function by an expression of at most length subst_2
  689. % depending on all variables,
  690. % not giving case distinctions,
  691. % no ftem-dep. coefficient
  692. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  693. subst_4,pdelimit_4,nil,nil,t,t,nil,nil)$
  694. symbolic procedure subst_level_35(arglist)$
  695. % Substitution of a function by an expression of at most length subst_2
  696. % depending on all variables,
  697. % not giving case distinctions,
  698. % ftem-dep. coefficient allowed
  699. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  700. subst_4,pdelimit_4,nil,nil,t,nil,nil,nil)$
  701. symbolic procedure subst_level_4(arglist)$
  702. % Substitution of a function by an expression of at most length subst_2
  703. % depending on all variables,
  704. % allowing case distinctions,
  705. % ftem-dep. coefficient allowed
  706. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  707. subst_4,pdelimit_4,nil,nil,nil,nil,nil,nil)$
  708. symbolic procedure subst_level_45(arglist)$
  709. % Substitution of a function by an expression
  710. % such that the growth of all equations is minimal
  711. % with some penalty for non-linearity increasing substitutions
  712. % no substitutions introducing case distinctions
  713. % no growth of total length of all equations
  714. % good for algebraic problems
  715. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  716. subst_4,pdelimit_4,nil,nil,t,nil,t,0)$
  717. symbolic procedure subst_level_5(arglist)$
  718. % Substitution of a function by an expression
  719. % such that the growth of all equations is minimal
  720. % with some penalty for non-linearity increasing substitutions
  721. % and substitutions introducing case distinctions
  722. % good for algebraic problems
  723. make_subst(car arglist,cadr arglist,caddr arglist,cadddr arglist,
  724. subst_4,pdelimit_4,nil,nil,nil,nil,t,cost_limit5)$
  725. symbolic procedure factorization(arglist)$
  726. % Factorization of a pde and investigation of the resulting subcases
  727. begin scalar ineq,l$
  728. ineq:=ineq_$
  729. if expert_mode then l:=selectpdes(car arglist,1)
  730. else l:=cadddr arglist$
  731. return split_and_crack(get_fact_pde(l),
  732. car arglist,ineq,cadr arglist,caddr arglist)$
  733. end$
  734. symbolic procedure separation(arglist)$
  735. % Direct separation of a pde
  736. begin scalar p,l,l1,pdes,forg$
  737. pdes:=car arglist$
  738. forg:=cadr arglist$
  739. if expert_mode then l1:=selectpdes(pdes,1)
  740. else l1:=cadddr arglist$
  741. if (p:=get_separ_pde(l1)) then
  742. <<l:=separate(p)$
  743. if l and
  744. ((length l>1) or
  745. ((length l = 1) and (car l neq p))) then
  746. <<pdes:=delete(p,pdes)$
  747. while l do
  748. <<pdes:=eqinsert(car l,pdes)$
  749. l:=cdr l>>$
  750. l:=list(pdes,forg)>> >>$
  751. return l$
  752. end$
  753. symbolic procedure alg_solve_system(arglist)$
  754. begin scalar pdes,l1,l2,l3,l4,fl,vl,zd$
  755. pdes:=car arglist$
  756. l1:=selectpdes(pdes,nil)$
  757. for each l2 in l1 do vl:=union(get(l2,'vars),vl);
  758. for each l2 in l1 do fl:=union(get(l2,'fcts),fl);
  759. l1:=for each l2 in l1 collect get(l2,'val)$
  760. write"Please give a list of constants, functions or derivatives"$
  761. terpri()$
  762. write"of functions to be solved algebraically, like f,g,df(g,x,2);"$
  763. terpri()$
  764. l2:=termxread()$
  765. write"l2=",l2$terpri()$
  766. if l2 then <<
  767. l2:=if (pairp l2) and (car l2='!*comma!*) then cdr l2
  768. else list l2;
  769. l3:=cdr solveeval list(cons('LIST,l1),cons('LIST,l2));
  770. % cdr to drop 'LIST
  771. %write"l3=",l3$terpri()$
  772. %algebraic write"l3=",cons('LIST,l3)$
  773. %write"fl=",fl$terpri()$
  774. %write"vl=",vl$terpri()$
  775. if null l3 then <<
  776. write"There is no solution."$
  777. terpri()
  778. >> else
  779. if length l3 > 1 then <<
  780. write"can currently not handle 2 solutions"$
  781. terpri()
  782. >> else <<
  783. l3:=for each l4 in l3 collect << % for each solution l4
  784. l4:=for each l5 in cdr l4 collect <<
  785. zd:=union(zero_den(reval l5,fl,vl),zd)$
  786. {'PLUS,cadr l5,{'MINUS,caddr l5}}
  787. >> % l4 is now a list of expressions to vanish
  788. >>;
  789. if length l3 = 1 then << %######### 1 solution - a restriction for now
  790. l4:=car l3; % the solution
  791. for each l5 in l4 do <<
  792. l5:=mkeq(if zd then cons('TIMES,append(zd,list l5))
  793. else l5,
  794. fl,vl,allflags_,nil,list(0))$
  795. pdes:=eqinsert(l5,pdes)$
  796. >>;
  797. return {pdes,cadr arglist}
  798. >>
  799. >>
  800. >>
  801. end$
  802. symbolic procedure alg_solve_deriv(arglist)$
  803. % Solving an equation that is algebraic for a function
  804. % or a derivative of a function,
  805. % So far no flag is installed to remember a corresponding
  806. % investigation because the check is quick and done very
  807. % rarely with lowest priority.
  808. begin scalar l,l1,pdes,forg$
  809. pdes:=car arglist$
  810. forg:=cadr arglist$
  811. if expert_mode then l1:=selectpdes(pdes,1)
  812. else l1:=cadddr arglist$
  813. if (l:=algsolvederiv(l1)) then
  814. <<pdes:=delete(car l,pdes)$
  815. pdes:=eqinsert(cdr l,pdes)$
  816. to_do_list:=cons(list('factorization,pdes,forg,caddr arglist,list cdr l),
  817. to_do_list);
  818. l:=list(pdes,forg);
  819. >>$
  820. return l
  821. end$
  822. symbolic procedure alg_for_deriv(p)$
  823. % find the first function with only one sort of derivative
  824. % which in addition occurs non-linear
  825. begin scalar dl,d,f$
  826. dl:=get(p,'derivs);
  827. while dl and null d do << % for each function
  828. d:=car dl$ % d is the leading power of the leading deriv. of f
  829. f:=caar d; % the next function f
  830. if fctlength f < get(p,'nvars) then <<d:=nil;dl:=nil>>
  831. else <<
  832. dl:=cdr dl;
  833. if cdr d = 1 then d:=nil; % must not be linear in lead. deriv.
  834. while dl and (f = caaar dl) do <<
  835. if d and (car d neq caar dl) then d:=nil;
  836. dl:=cdr dl
  837. >>
  838. >>
  839. >>;
  840. return d
  841. end$
  842. symbolic procedure algsolvederiv(l)$
  843. begin scalar d,p$
  844. while l and null (d:=alg_for_deriv(car l)) do l:=cdr l;
  845. if d then <<
  846. p:=cdr d$
  847. d:=solveeval list(get(car l,'val),
  848. if 1=length car d then caar d
  849. else cons('DF,car d));
  850. if d and (car d='LIST) and (length d = p+1) then
  851. p:=for each el in cdr d collect if car el='EQUAL then
  852. reval list('PLUS,cadr el,list('MINUS,caddr el)) else d:=nil
  853. else d:=nil;
  854. if d then <<
  855. d:=cons('TIMES,p);
  856. p:=car l;
  857. d:=mkeq(d,get(p,'fcts),get(p,'vars),allflags_,nil,get(p,'orderings))$
  858. if print_ then write p," factorized to ",d
  859. >>
  860. >>;
  861. return if d then p . d
  862. else nil
  863. end$
  864. symbolic procedure quick_integration(arglist)$
  865. % Integration of a short first order de with at most two terms
  866. begin scalar l,l1,pdes,forg$
  867. pdes:=car arglist$
  868. forg:=cadr arglist$
  869. if expert_mode then <<l1:=selectpdes(pdes,1);flag(l1,'to_int)>>
  870. else l1:=cadddr arglist$
  871. if (l:=quick_integrate_one_pde(l1)) then
  872. <<pdes:=delete(car l,pdes)$
  873. for each s in l do pdes:=eqinsert(s,pdes)$
  874. for each s in l do
  875. to_do_list:=cons(list('subst_level_4,pdes,forg,caddr arglist,list s),
  876. to_do_list)$
  877. l:=list(pdes,forg)>>$
  878. return l$
  879. end$
  880. symbolic procedure full_integration(arglist)$
  881. % Integration of a pde
  882. % only if then a function can be substituted
  883. begin scalar l,l1,pdes,forg$
  884. pdes:=car arglist$
  885. forg:=cadr arglist$
  886. if expert_mode then <<l1:=selectpdes(pdes,1);flag(l1,'to_int)>>
  887. else l1:=cadddr arglist$
  888. if (l:=integrate_one_pde(l1,genint_,t)) then
  889. <<pdes:=delete(car l,pdes)$
  890. for each s in l do pdes:=eqinsert(s,pdes)$
  891. for each s in cdr l do
  892. to_do_list:=cons(list('subst_level_4,pdes,forg,caddr arglist,list s),
  893. to_do_list)$
  894. l:=list(pdes,forg)>>$
  895. return l$
  896. end$
  897. symbolic procedure integration(arglist)$
  898. % Integration of a pde
  899. begin scalar l,l1,pdes,forg$
  900. pdes:=car arglist$
  901. forg:=cadr arglist$
  902. if expert_mode then <<l1:=selectpdes(pdes,1);flag(l1,'to_int)>>
  903. else l1:=cadddr arglist$
  904. if (l:=integrate_one_pde(l1,genint_,nil)) then
  905. <<pdes:=delete(car l,pdes)$
  906. for each s in l do pdes:=eqinsert(s,pdes)$
  907. for each s in cdr l do
  908. to_do_list:=cons(list('subst_level_4,pdes,forg,caddr arglist,list s),
  909. to_do_list)$
  910. l:=list(pdes,forg)>>$
  911. return l$
  912. end$
  913. symbolic procedure multintfac(arglist)$
  914. % Seaching of an integrating factor for a set of pde's
  915. begin scalar pdes,forg,l,stem,ftem,vl,vl1$
  916. pdes:=car arglist$
  917. if null pdes or (length pdes=1) then return nil$
  918. forg:=cadr arglist$
  919. for each p in pdes do
  920. if not (get(p,'starde) or get(p,'nonrational)) then
  921. <<stem:=cons(get(p,'val),stem)$
  922. ftem:=union(get(p,'fcts),ftem)$
  923. vl:=union(get(p,'vars),vl)
  924. >>$
  925. vl1:=vl$
  926. fnew_:=nil$
  927. while vl1 do
  928. if (l:=findintfac(stem,ftem,vl,car vl1,nil,nil,nil,nil)) then
  929. <<ftem:=smemberl(ftem,car l)$
  930. vl:=union(smemberl(vl,car l),argset ftem)$
  931. l:=addintco(car l, ftem, nil, vl, car vl1)$
  932. ftem_:=reverse ftem_$
  933. for each f in reverse fnew_ do
  934. ftem_:=fctinsert(f,ftem_)$
  935. ftem_:=reverse ftem_$
  936. ftem:=union(fnew_,ftem)$
  937. fnew_:=nil$
  938. pdes:=eqinsert(mkeq(l,smemberl(ftem_,ftem),vl,allflags_,t,list(0)),
  939. pdes)$
  940. vl1:=nil$
  941. l:=list(pdes,forg)>>
  942. else vl1:=cdr vl1$
  943. return l$
  944. end$
  945. symbolic procedure length_reduction_2(arglist)$
  946. % Do one length reduction step
  947. begin scalar l$
  948. l:=dec_one_step(car arglist,ftem_,caddr arglist,t)$
  949. % t --> length must reduce
  950. if l then l:=list(l,cadr arglist)$
  951. return l$
  952. end$
  953. symbolic procedure decoupling(arglist)$
  954. % Do one decoupling step
  955. begin scalar l$
  956. l:=dec_one_step(car arglist,ftem_,caddr arglist,nil)$
  957. % nil --> length need not reduce
  958. if l then l:=list(l,cadr arglist)$
  959. return l$
  960. end$
  961. symbolic procedure clean_up(pdes)$
  962. begin scalar newpdes;
  963. while pdes do <<
  964. if flagp(car pdes,'to_drop) then
  965. setprop(car pdes,nil) else
  966. newpdes:=cons(car pdes,newpdes);
  967. pdes:=cdr pdes
  968. >>;
  969. return reverse newpdes
  970. end$
  971. symbolic procedure gen_separation(arglist)$
  972. % Indirect separation of a pde
  973. begin scalar p,l,l1,pdes$
  974. % pdes:=clean_up(car arglist)$
  975. % if pdes then l:=list(pdes,cadr arglist)$
  976. % because the bookeeping of to_drop is not complete instead:
  977. pdes:=car arglist$
  978. % to return the new list of pdes in case gensep is not successful
  979. if expert_mode then <<
  980. l1:=selectpdes(pdes,1);
  981. if get(car l1,'starde) then flag(l1,'to_gensep)
  982. >> else l1:=cadddr arglist$
  983. if (p:=get_gen_separ_pde(l1)) then
  984. <<l:=gensep(p)$
  985. pdes:=delete(p,pdes)$
  986. for each a in l do pdes:=eqinsert(a,pdes)$
  987. l:=list(pdes,cadr arglist)>>$
  988. return l$
  989. end$
  990. symbolic procedure add_differentiated_pdes(arglist)$
  991. % all pdes in which the leading derivative of a function of all
  992. % vars occurs nonlinear will be differentited w.r.t all vars and
  993. % the resulting pdes are added to the list of pdes
  994. begin scalar pdes,l,l1,q$
  995. pdes:=car arglist$
  996. if expert_mode then l1:=selectpdes(pdes,1)
  997. else l1:=cadddr arglist$
  998. for each p in l1 do
  999. if flagp(p,'to_diff) then
  1000. % --------------- it should be differentiated only once
  1001. <<for each f in get(p,'allvarfcts) do
  1002. if (cdr ld_deriv(p,f)>1) then
  1003. <<if print_ then
  1004. <<terpri()$
  1005. write "differentiating ",p," w.r.t. "$
  1006. listprint fctargs f$
  1007. write " we get the new equations : ">>$
  1008. for each v in fctargs f do
  1009. <<q:=mkeq(list('DF,get(p,'val),v),get(p,'fcts),get(p,'vars),
  1010. delete('to_int,delete('to_diff,allflags_)),t,list(0))$
  1011. prevent_simp(v,p,q)$
  1012. if print_ then write q," "$
  1013. pdes:=eqinsert(q,pdes)>>$
  1014. remflag1(p,'to_diff)$
  1015. l:=cons(pdes,cdr arglist)>>
  1016. >>$
  1017. return l$
  1018. end$
  1019. symbolic procedure add_diff_star_pdes(arglist)$
  1020. % a star-pde is differentiated and then added
  1021. begin scalar pdes,l,l1,q$
  1022. pdes:=car arglist$
  1023. if expert_mode then l1:=selectpdes(pdes,1)
  1024. else l1:=cadddr arglist$
  1025. for each p in l1 do
  1026. if (null l) and flagp(p,'to_diff) and get(p,'starde) then <<
  1027. if print_ then
  1028. <<terpri()$
  1029. write "differentiating ",p," w.r.t. "$
  1030. listprint get(p,'vars)$
  1031. write " we get the new equations : "
  1032. >>$
  1033. for each v in get(p,'vars) do
  1034. <<q:=mkeq(list('DF,get(p,'val),v),get(p,'fcts),get(p,'vars),
  1035. delete('to_int,allflags_),t,get(p,'orderings))$
  1036. if null get(q,'starde) then flag(list q,'to_int)$
  1037. prevent_simp(v,p,q)$
  1038. %check whether q really includes 'fcts and 'vars: should be ok
  1039. if print_ then write q," "$
  1040. pdes:=eqinsert(q,pdes)$
  1041. >>$
  1042. remflag1(p,'to_diff)$
  1043. l:=cons(pdes,cdr arglist)$
  1044. >>$
  1045. return l$
  1046. end$
  1047. symbolic procedure split_and_crack(p,pdes,ineq,forg,vl)$
  1048. % for each factor of p CRACKMAIN is called
  1049. if p then
  1050. begin scalar l,l1,q,contrad,result,n,cop,s$
  1051. n:=0$
  1052. l:=cdr get(p,'val)$ % list of factors of p
  1053. contrad:=t$
  1054. if print_ then
  1055. <<terpri()$
  1056. write "factorizing ",p$
  1057. write " we get the alternative equations : "$
  1058. deprint(l)>>$
  1059. for each d in l do
  1060. if not member(d,ineq) and not contradictioncheck(s,pdes)
  1061. then
  1062. <<n:=n+1$
  1063. level_:=cons(n,level_)$
  1064. if print_ then
  1065. <<print_level()$
  1066. terpri()$
  1067. write "CRACK is now called with the assumtion : "$
  1068. deprint(list d)>>$
  1069. q:=mkeq(d,get(p,'fcts),get(p,'vars),allflags_,nil,get(p,'orderings))$
  1070. cop:=backup_pdes(pdes,forg)$
  1071. l1:=crackmain(eqinsert(q,delete(p,pdes)),ineq,forg,vl)$
  1072. pdes:=restore_pdes(cop)$
  1073. if not member(d,ineq) then
  1074. <<ineq:=cons(d,ineq)$
  1075. s:=d>>
  1076. else s:=nil$
  1077. if not contradiction_ then contrad:=nil$
  1078. if l1 and not contradiction_ then
  1079. result:=union(l1,result);
  1080. contradiction_:=nil$ % <--- neu
  1081. >>$
  1082. contradiction_:=contrad$
  1083. if contradiction_ then result:=nil$
  1084. return if null result then nil
  1085. else list result
  1086. % by returning list result and not just result, what is returned
  1087. % is a list with only a single element. This is indicating that the
  1088. % content of what is returned from this procedure is a list of
  1089. % crackmain returns and not (pdes,forg) which is returned from
  1090. % other modules and which is a list of more than one element.
  1091. end$
  1092. symbolic procedure stop_batch(arglist)$
  1093. begin
  1094. % !*batch_mode:=nil$
  1095. batchcount_:=stepcounter_ - 2$
  1096. return {car arglist,cadr arglist} % only to have arglist involved
  1097. end$
  1098. endmodule$
  1099. end$