crident.red 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. %********************************************************************
  2. module identities$
  3. %********************************************************************
  4. % Routines for dealing with differential identities
  5. % Author: Thomas Wolf
  6. % May 1999
  7. symbolic procedure drop_idty(id)$
  8. % recycles a name of an identity
  9. <<setprop(id,nil)$
  10. recycle_ids:=id . recycle_ids$
  11. idnties_:=delete(id,idnties_)>>$
  12. symbolic procedure new_id_name$
  13. % provides a name for a new identity
  14. begin scalar id$
  15. if null recycle_ids then <<
  16. id:=mkid(idname_,nid_)$
  17. nid_:=add1 nid_$
  18. >> else <<
  19. id:=car recycle_ids$
  20. recycle_ids:=cdr recycle_ids
  21. >>$
  22. setprop(id,nil)$
  23. return id
  24. end$
  25. symbolic procedure replace_idty$
  26. begin scalar p,ps,ex$
  27. ps:=promptstring!*$
  28. promptstring!*:=""$
  29. terpri()$
  30. write "If you want to replace an identity then ",
  31. "type its name, e.g. id_2 <ENTER>."$
  32. terpri()$
  33. write "If you want to add an identity then type `new_idty' <ENTER>. "$
  34. p:=termread()$
  35. if (p='NEW_IDTY) or member(p,idnties_) then
  36. <<terpri()$write "Input of a value for "$
  37. if p='NEW_IDTY then write "the new identity."
  38. else write p,"."$
  39. terpri()$
  40. write "You can use names of other identities, e.g. 3*id_2 - df(id_1,x); "$
  41. terpri()$
  42. write "Terminate the expression with ; or $ : "$
  43. terpri()$
  44. ex:=termxread()$
  45. for each a in idnties_ do ex:=subst(get(a,'val),a,ex)$
  46. if p neq 'NEW_IDTY then drop_idty(p)$
  47. new_idty(reval ex,nil,nil)$
  48. terpri()$write car idnties_$
  49. if p='NEW_IDTY then write " is added"
  50. else write " replaces ",p$
  51. >>
  52. else <<terpri()$
  53. write "An identity ",p," does not exist! (Back to previous menu)">>$
  54. promptstring!*:=ps$
  55. end$
  56. symbolic procedure trivial_idty(pdes,idval)$
  57. if zerop idval or
  58. (pdes and
  59. null smemberl(pdes,search_li(idval,'DF))) % identity is purely alg.
  60. then t else nil$
  61. symbolic procedure new_idty(idty,pdes,simp)$
  62. % idty is the value of a new differential identity between equations
  63. begin scalar id,idcp$
  64. if simp then idty:=simplifypde(idty,pdes,t,nil)$
  65. if not trivial_idty(pdes,idty) then <<
  66. idcp:=idnties_$
  67. while idcp and (get(car idcp,'val) neq idty) do idcp:=cdr idcp;
  68. if null idcp then <<
  69. id:=new_id_name();
  70. put(id,'val,idty)$
  71. flag1(id,'to_subst)$
  72. flag1(id,'to_int)$
  73. idnties_:=cons(id,idnties_)
  74. >>
  75. >>
  76. end$
  77. symbolic procedure show_id$
  78. begin scalar l,n$
  79. terpri()$
  80. l:=length idnties_$
  81. write if l=0 then "No" else l,
  82. if l=1 then " identity." else " identities"$
  83. if l=0 then terpri()
  84. else <<
  85. n:=1;
  86. for each l in reverse idnties_ do <<
  87. terpri()$
  88. algebraic write n,") ",l," : 0 = ",lisp(get(l,'val));
  89. n:=add1 n;
  90. if print_all then <<
  91. terpri()$write " to_int : ",flagp(l,'to_int)$
  92. terpri()$write " to_subst : ",flap(l,'to_subst)$
  93. >>
  94. >>
  95. >>
  96. end$
  97. symbolic procedure del_red_id(pdes)$
  98. begin scalar oldli,pl,s,idty,news,succ,p,l$ % ,r,newr$
  99. if idnties_ then <<
  100. oldli:=idnties_$
  101. while oldli do
  102. if not flagp(car oldli,'to_subst) then oldli:=cdr oldli
  103. else <<
  104. idty:=get(car oldli,'val)$
  105. pl:=smemberl(pdes,idty)$
  106. for each p in pl do l:=union(get(p,'vars),l)$
  107. if l then l:=length l else l:=0$
  108. pl:=setdiff(pl,search_li(idty,'DF));
  109. % now all pdes in pl are redundand, drop the longest
  110. if null pl then remflag1(car oldli,'to_subst)
  111. else <<
  112. drop_idty(car oldli);
  113. % find the longest equation s of those with the most variables
  114. s:=nil;
  115. while pl do <<
  116. if (null get(car pl,'starde) ) and
  117. (get(car pl,'nvars)=l ) and
  118. (null(% flagp(s,'to_int) or
  119. % flagp(s,'to_fullint) or
  120. % flagp(s,'to_sep) or
  121. % flagp(s,'to_gensep) or
  122. % flagp(s,'to_decoup) or
  123. flagp(s,'to_eval)) ) and
  124. ((null s ) or
  125. (get(car pl,'nvars)>get(s,'nvars) ) or
  126. ((get(car pl,'nvars)=get(s,'nvars)) and
  127. (get(car pl,'terms)>get(s,'terms)) ) ) then s:=car pl;
  128. pl:=cdr pl
  129. >>;
  130. if null s then remflag1(car oldli,'to_subst)
  131. else <<
  132. if print_ then <<
  133. write "Equation ",s," is dropped as it is a consequence of others: "$
  134. algebraic write "0 = ",lisp(idty)$
  135. >>$
  136. % assuming s occurs linearly:
  137. pl:=coeffn(idty,s,1)$
  138. news:=reval {'QUOTIENT,{'DIFFERENCE,{'TIMES,pl,s},idty},pl};
  139. %for each r in idnties_ do
  140. %if not freeof(get(r,'val),s) then <<
  141. % newr:=reval subst(news,s,get(r,'val));
  142. % newr:=simplifypde(newr,pdes,t,nil)$
  143. % put(r,'val,newr)$
  144. % flag1(r,'to_subst)$
  145. % flag1(r,'to_int)$
  146. %>>$
  147. succ:=t$
  148. pdes:=drop_pde(s,pdes,news)$
  149. oldli:=cdr oldli
  150. >>
  151. >>
  152. >>
  153. >>;
  154. if succ then return pdes
  155. end$
  156. symbolic procedure del_redundant_de(argset)$
  157. begin scalar pdes;
  158. if pdes:=del_red_id(car argset) then return {pdes,cadr argset}$
  159. end$
  160. symbolic procedure write_id_to_file(pdes)$
  161. begin scalar s,p,h,pl,ps$
  162. if idnties_ then <<
  163. ps:=promptstring!*$
  164. promptstring!*:=""$
  165. write"Please give the name of the file in double quotes"$terpri()$
  166. write"without `;' : "$
  167. s:=termread()$
  168. out s;
  169. off nat$
  170. write"load crack$"$terpri()$
  171. write"lisp(nequ_:=",nequ_,")$"$terpri()$
  172. write"off batch_mode$"$terpri()$
  173. write"list_of_variables:="$
  174. algebraic write lisp cons('LIST,vl_)$
  175. write"list_of_functions:="$
  176. algebraic write lisp cons('LIST,pdes)$
  177. for each h in pdes do
  178. if pl:=assoc(h,depl!*) then
  179. for each p in cdr pl do
  180. algebraic write "depend ",lisp h,",",lisp p$
  181. write"list_of_equations:="$
  182. algebraic write
  183. lisp( cons('LIST,for each h in idnties_ collect get(h,'val)));
  184. terpri()$ write"solution_:=crack(list_of_equations,{},"$
  185. terpri()$ write" list_of_functions,"$
  186. terpri()$ write" list_of_variables)$"$
  187. terpri()$
  188. terpri()$
  189. write"end$"$terpri()$
  190. shut s;
  191. on nat;
  192. promptstring!*:=ps$
  193. >>
  194. end$
  195. symbolic procedure remove_idl$
  196. <<for each h in idnties_ do setprop(h,nil);
  197. idnties_:=nil>>$
  198. symbolic procedure start_history(pdes)$
  199. begin scalar l,ps$
  200. ps:=promptstring!*$
  201. promptstring!*:=""$
  202. write"For recording the history of equations all currently"$ terpri()$
  203. write"recorded histories would be deleted as well as all"$ terpri()$
  204. write"present decoupling information, i.e. `dec_with'"$ terpri()$
  205. write"would be set to nil. Please confirm (y/n). "$
  206. l:=termread()$
  207. if (l='y) or (l='Y) then <<
  208. record_hist:=t;
  209. for each l in pdes do put(l,'histry_,l)$
  210. for each l in pdes do put(l,'dec_with,nil)$
  211. >>;
  212. promptstring!*:=ps$
  213. end$
  214. symbolic procedure stop_history(pdes)$
  215. <<record_hist:=nil;
  216. for each l in pdes do put(l,'histry_,l)>>$
  217. % write"Do you want to delete all dec_with information? (y/n) "$
  218. % l:=termread()$
  219. % if (l='y) or (l='Y) then
  220. % for each l in pdes do put(l,'dec_with,nil)$
  221. symbolic procedure idty_integration(argset)$
  222. begin scalar l,pdes,idcp;
  223. pdes:=car argset;
  224. idcp:=idnties_;
  225. while idcp do
  226. if not flagp(car idcp,'to_int) then idcp:=cdr idcp else
  227. if l:=integrate_idty(car idcp,pdes,%cadr argset,
  228. ftem_,vl_) then <<
  229. pdes:=l;idcp:=nil>> else <<
  230. remflag1(car idcp,'to_int);
  231. idcp:=cdr idcp;
  232. >>;
  233. if l then return {pdes,cadr argset}
  234. end$
  235. symbolic procedure integrate_idty(org_idty,allpdes,%forg,
  236. fl,vl)$
  237. % idty is a differential identity between equations
  238. % allpdes, fl, vl are lisp lists of equation names, functions and variables
  239. % ways to optimize: use conlaw instead of the initial intcurrent2
  240. % use more general methods to take advantage of
  241. % non-conservation laws
  242. if idnties_ then
  243. begin scalar cl,ncl,vlcp,xlist,eql,a,f,newpdes,ftem_bak,
  244. nx,dl,l,k,ps,idty,pdes,extrapdes,newidtylist$ %nclu
  245. if null org_idty then
  246. if null cdr idnties_ then org_idty:=car idnties_
  247. else <<
  248. show_id()$
  249. ps:=promptstring!*$
  250. promptstring!*:=""$
  251. write"Which of the identities shall be integrated? (no) "$
  252. k:=length(idnties_);
  253. repeat
  254. l:=termread()
  255. until (fixp l) and (0<l) and (l<=k);
  256. org_idty:=nth(idnties_,k+1-l)$
  257. promptstring!*:=ps
  258. >>$
  259. idty:=reval num reval get(org_idty,'val)$
  260. if trivial_idty(allpdes,idty) then return nil$
  261. pdes:=smemberl(allpdes,idty)$
  262. a:=all_deriv_search(idty,pdes)$
  263. xlist:=smemberl(vl,a)$
  264. cl:=intcurrent3(idty,cons('LIST,pdes),cons('LIST,xlist))$
  265. % intcurrent3 is only successful if only 2 derivatives found
  266. if (not zerop caddr cl) and inter_divint then
  267. cl:=intcurrent2(idty,cons('LIST,pdes),cons('LIST,xlist))$
  268. if zerop caddr cl then <<
  269. cl:=cdadr cl;
  270. vlcp:=xlist;
  271. xlist:=nil;
  272. while vlcp do <<
  273. if not zerop car cl then <<
  274. ncl:=cons(car cl,ncl);
  275. xlist:=cons(car vlcp,xlist)
  276. >>;
  277. cl:=cdr cl;
  278. vlcp:=cdr vlcp
  279. >>;
  280. % ncl:=reverse ncl;
  281. % xlist:=reverse xlist;
  282. cl:=ncl;
  283. % % Now try to get a divergence in less differentiation variables.
  284. % % Each component of the divergence is tried to be written as
  285. % % a divergence in the other (right) variables
  286. % while ncl do <<
  287. % a:=intcurrent2(car ncl,cons('LIST,pdes),cons('LIST,cdr xlist))$
  288. % if not zerop caddr a then <<
  289. % cl:=cons(car ncl,cl); ncl:=cdr ncl;
  290. % vlcp:=cons(car xlist,vlcp); xlist:=cdr xlist
  291. % >> else <<
  292. % % It was possible to integrate car ncl to div(cdadr a,cdr xlist).
  293. % % distribute {'DF,car a,car xlist} to the divergence of cdr ncl
  294. % ncl:=cdr ncl;
  295. % a:=cdadr a;
  296. % nclu:=nil;
  297. % while ncl do <<
  298. % nclu:=cons(reval {'PLUS,car ncl,{'DF,car a,car xlist}}, nclu);
  299. % ncl:=cdr ncl;
  300. % a:=cdr a
  301. % >>;
  302. % ncl:=reverse nclu;
  303. % xlist:=cdr xlist
  304. % >>
  305. % >>$
  306. % ncl:=cl;
  307. % xlist:=vlcp;
  308. nx:=length xlist;
  309. while pdes do <<
  310. ncl:=subst(get(car pdes,'val),car pdes,ncl);
  311. pdes:=cdr pdes
  312. >>$
  313. ftem_bak:=ftem_;
  314. eql:=int_curl(reval cons('LIST,ncl), cons('LIST,fl),
  315. cons('LIST,xlist),cons('LIST,varslist(ncl,ftem_,vl)) )$
  316. % eql has the form {'LIST,reval cons('LIST,resu),cons('LIST,neweq)}
  317. if (null eql) or (null cdadr eql) or (zerop cadadr eql) then return nil;
  318. eql:=cdr eql;
  319. if print_ then <<
  320. ncl:=for i:=1:nx collect {'DF,nth(cl,i),nth(xlist,i)};
  321. ncl:=if cdr ncl then cons('PLUS,ncl)
  322. else car ncl;
  323. terpri()$
  324. write"The identity "$
  325. % mathprint idty$
  326. mathprint reval ncl;
  327. write"can be integrated to "$terpri()$
  328. deprint(cdar eql)$
  329. >>$
  330. if nx < 3 then a:='y else
  331. if (null inter_divint) or !*batch_mode then <<
  332. a:='n;
  333. if print_ then <<
  334. write"The integrated divergence is not used because it ",
  335. "has more than 2 terms and"$ terpri()$
  336. if !*batch_mode then write"`inter_divint' is nil."
  337. else write"batch_mode is on."$
  338. >>$
  339. terpri()
  340. >> else <<
  341. ps:=promptstring!*$
  342. promptstring!*:=""$
  343. write"Shall this integration be used? (y/n) "$
  344. repeat a:=termread() until (a='y) or (a='n);
  345. promptstring!*:=ps
  346. >>;
  347. if a='n then <<
  348. a:=setdiff(ftem_,ftem_bak);
  349. for each f in a do drop_fct(f)$
  350. ftem_:=ftem_bak
  351. >> else <<
  352. % the extra conditions from the generalized integration:
  353. extrapdes:=cdadr eql$
  354. eql:=cdar eql; % eql are now the integrated curl conditions
  355. drop_idty(org_idty)$
  356. while eql do <<
  357. if not zerop car eql then <<
  358. a:=mkeq(car eql,ftem_,vl,allflags_,nil,list(0),nil,allpdes);
  359. newpdes:=cons(a,newpdes);
  360. >>;
  361. eql:=cdr eql;
  362. >>;
  363. newpdes:=reverse newpdes;
  364. % formulate the new identities
  365. for i:=1:nx do <<
  366. idty:=nth(cl,i);
  367. if nx=1 then a:=car newpdes
  368. else <<
  369. % at first sum over df(q^{ji},j), j<i
  370. l:=i-1;
  371. dl:=nx-2;
  372. a:=for j:=1:(i-1) collect <<
  373. k:=l;
  374. l:=l+dl;
  375. dl:=sub1 dl;
  376. {'DF,nth(newpdes,k),nth(xlist,j)}
  377. >>;
  378. a:=if null a then 0 else
  379. if cdr a then cons('PLUS,a)
  380. else car a;
  381. idty:={'PLUS,idty,a};
  382. % then sum over -df(q^{ij},j), j>i
  383. if i=1 then l:=1
  384. else l:=k+nx-i+1;
  385. a:=for j:=(i+1):nx collect <<
  386. k:=l;
  387. l:=l+1;
  388. {'DF,nth(newpdes,k),nth(xlist,j)}
  389. >>;
  390. a:=if null a then 0 else
  391. if cdr a then cons('PLUS,a)
  392. else car a;
  393. >>$
  394. newidtylist:=cons({'DIFFERENCE,idty,a},newidtylist);
  395. >>;
  396. eql:=nil;
  397. for each a in extrapdes do <<
  398. a:=mkeq(a,ftem_,vl,allflags_,t,list(0),nil,allpdes);
  399. allpdes:=eqinsert(a,allpdes);
  400. to_do_list:=cons(list('subst_level_35,%allpdes,forg,vl_,
  401. list a),
  402. to_do_list);
  403. eql:=cons(a,eql)
  404. >>;
  405. if print_ then <<
  406. write"Integration gives: "$
  407. listprint(newpdes)$terpri()$
  408. if eql then <<
  409. write"with extra conditions: "$
  410. listprint(eql)
  411. >>$
  412. >>;
  413. for each a in newpdes do allpdes:=eqinsert(a,allpdes)$
  414. % now that allpdes is updated:
  415. for each a in newidtylist do new_idty(a,allpdes,t)$
  416. return allpdes
  417. >>
  418. >>
  419. end$
  420. symbolic procedure sortpermuli(a)$
  421. % a is a list of numbers to be sorted and the exchanges of neighbours
  422. % are to be counted
  423. begin scalar flp,conti,newa;
  424. repeat <<
  425. newa:=nil;
  426. conti:=nil;
  427. while cdr a do
  428. if car a < cadr a then <<newa:=cons(car a,newa); a:=cdr a>>
  429. else <<
  430. conti:=t;
  431. flp:=not flp;
  432. newa:=cons(cadr a,newa);
  433. a:=cons(car a,cddr a);
  434. >>$
  435. newa:=cons(car a,newa);
  436. a:=reverse newa
  437. >> until null conti;
  438. return flp . a
  439. end$
  440. symbolic procedure curlconst(xlist,vl)$
  441. % generates a list q^ij=r^ijk,_k with r^ijk totally antisymmetric
  442. % in the order q^(n-1)n,...
  443. % xlist is the list of xi,xj,xk
  444. % vl is the list of all variables new functions should depend on
  445. begin scalar n,qli,i,j,k,qij,a,flp,f,resu,qlicp$
  446. n:=length xlist$
  447. for i:=1:(n-1) do
  448. for j:=(i+1):n do << % generation of r^ijk,k
  449. qij:=nil;
  450. for k:=1:n do
  451. if (k neq i) and (k neq j) then <<
  452. a:=sortpermuli({i,j,k});
  453. flp:=car a;
  454. a:=cdr a;
  455. qlicp:=qli;
  456. while qlicp and (caar qlicp neq a) do qlicp:=cdr qlicp;
  457. if qlicp then f:=cdar qlicp
  458. else <<
  459. f:=newfct(fname_,vl,nfct_);
  460. nfct_:=add1 nfct_;
  461. ftem_:=fctinsert(f,ftem_);
  462. qli:=cons(a . f,qli)
  463. >>;
  464. f:={'DF,f,nth(xlist,k)};
  465. if flp then f:={'MINUS,f};
  466. qij:=cons(f,qij)
  467. >>$
  468. if null qij then <<qij:=newfct(fname_,setdiff(vl,xlist),nfct_);
  469. nfct_:=add1 nfct_;
  470. ftem_:=fctinsert(qij,ftem_)>>
  471. else
  472. if cdr qij then qij:=reval cons('PLUS,qij)
  473. else qij:=car qij;
  474. resu:=cons(qij,resu)
  475. >>$
  476. return resu
  477. end$
  478. symbolic procedure updt_curl(h2,rmdr,fl,done_xlist,x,cdrxlist,n,k)$
  479. % a subroutine of int_curl
  480. begin scalar i,h4,h5,h6,h7,rmdr,y,pint,succ$
  481. if (not zerop reval reval {'DF,rmdr,x}) then <<
  482. if print_ then <<terpri()$write"No success."$terpri()>>$
  483. succ:=nil
  484. >> else <<
  485. succ:=t;
  486. if done_xlist then << % there is one computed curl component to be updated
  487. % integration wrt done_xlist
  488. h7:=intcurrent2(rmdr,fl,cons('LIST,done_xlist));
  489. rmdr:=caddr h7;
  490. h7:=cdadr h7;
  491. % update the already computed h2-components with the new h7-comp.
  492. h4:=nil;
  493. h5:=-1;
  494. for i:=1:(k-1) do <<
  495. h5:=add1 h5;
  496. for h6:=1:(n-k) do <<h4:=cons(car h2,h4);h2:=cdr h2>>;
  497. h4:=cons({'DIFFERENCE,car h2,car h7},h4);
  498. h2:=cdr h2;
  499. h7:=cdr h7;
  500. for h6:=1:h5 do <<h4:=cons(car h2,h4);h2:=cdr h2>>
  501. >>;
  502. h2:=reverse h4;
  503. >>$
  504. % now generalized integration of the remainder
  505. if zerop rmdr then pint:=cons(0,nil)
  506. else <<
  507. y:=if cdrxlist then car cdrxlist
  508. else car done_xlist;
  509. fnew_:=nil$
  510. pint:=partint(rmdr,fl,vl_,y,genint_);
  511. % genint is max number of new terms
  512. if null pint then succ:=nil
  513. else for each h4 in fnew_ do ftem_:=fctinsert(h4,ftem_)
  514. >>
  515. >>;
  516. return if null succ then nil
  517. else cons(h2,pint)
  518. % pint=cons(generalized integral of rmdr,list of new eqn)
  519. end$
  520. symbolic procedure int_curl(pli,fl,xlist,vl)$
  521. % given a vector p^i satisfying p^i,_i=0, find q^{ij}=-q^{ji}
  522. % such that p^i=q^{ij},j
  523. % car result: (q^{12}, q^{13},.., q^{1n}, q^{23},.., q^{2n},.., q^{(n-1)n})
  524. % each q^{ij} comes with r^{ijk},k
  525. % cdr result: list of new conditions in fewer variables
  526. % works only if identically satisfied, not modulo some equations
  527. % vl is the list of all relevant variables
  528. % during computation is h2 =
  529. % (q^{kn},.., q^{k(k+1)},q^{(k-1)n},.., q^{(k-1)k},..,
  530. % q^{2n},.., q^{23}, q^{1n},.., q^{13},q^{12}} )
  531. begin scalar h1,h2,h3,resu,newpli,xcp,done_xlist,n,k,ok,neweq,ftem_bak$
  532. % conversion from algebraic mode lists to lisp lists:
  533. pli:=cdr pli$ xlist:=cdr xlist$ vl:=cdr vl; xcp:=xlist$
  534. n:=length(xlist);
  535. k:=0;
  536. ok:=t;
  537. ftem_bak:=ftem_;
  538. if n=1 then return {'LIST,reval cons('LIST,pli),{'LIST}}$
  539. while cdr pli and ok do <<
  540. k:=add1 k;
  541. % the integration has to be done first wrt cdr xlist. The resulting
  542. % curl will be used to change the remining pli to be integrated
  543. h3:=intcurrent2(reval car pli,fl,cons('LIST,cdr xlist));
  544. pli:=cdr pli;
  545. h1:=cdadr h3;
  546. h3:=reval reval caddr h3;
  547. % h3 now = the remainder of the integration wrt cdr xlist
  548. if not zerop h3 then <<
  549. % here the integration wrt the done_xlist. These curl updates will
  550. % not be used to update pli, because df(h3,car xlist)=0 is assumed
  551. h3:=updt_curl(h2,h3,fl,done_xlist,car xlist,cdr xlist,n,k)$
  552. if null h3 then ok:=nil
  553. else << % generalized integration of the remainder
  554. neweq:=append(cddr h3,neweq);
  555. h2:=car h3;
  556. h1:=cons({'PLUS,car h1,cadr h3},cdr h1);
  557. % because of cdr xlist neq nil here q^{k(k+1)} is updated
  558. >>
  559. >>$
  560. if ok then << % In the first round h2 is naturally nil --> use ok for test
  561. % append (q^{kn},.., q^{k(k+1)}) and h2
  562. h2:=append(reverse h1,h2);
  563. % update the remaining pli to be integrated
  564. newpli:=nil;
  565. while h1 do <<
  566. newpli:=cons({'PLUS,{'DF,car h1,car xlist},car pli},newpli);
  567. h1:=cdr h1;
  568. pli:=cdr pli
  569. >>;
  570. pli:=reverse newpli
  571. >>;
  572. done_xlist:=cons(car xlist,done_xlist);
  573. xlist:=cdr xlist
  574. >>$
  575. if ok then <<
  576. pli:=reval car pli;
  577. % to get the remainder of the last component of pli integrated
  578. if pli neq 0 then <<
  579. k:=k+1;
  580. h3:=updt_curl(h2,pli,fl,done_xlist,car xlist,nil,n,k)$
  581. if null h3 then ok:=nil
  582. else <<
  583. neweq:=append(cddr h3,neweq);
  584. h2:=car h3;
  585. h2:=cons({'DIFFERENCE,car h2,cadr h3},cdr h2)
  586. % because of null xlist here car h2=q^{n-1,n} is updated
  587. >>$
  588. >>
  589. >>;
  590. if null ok then << % drop all new functions
  591. h1:=setdiff(ftem_,ftem_bak);
  592. for each h2 in h1 do drop_fct(h2)$
  593. ftem_:=ftem_bak
  594. >> else <<
  595. h1:=curlconst(xcp,vl)$
  596. while h1 do <<
  597. resu:=cons({'PLUS,car h2,car h1},resu);
  598. h1:=cdr h1;
  599. h2:=cdr h2;
  600. >>$
  601. return {'LIST,reval cons('LIST,resu),cons('LIST,neweq)}
  602. >>
  603. end$
  604. endmodule$
  605. end$