conlaw0.red 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. %==== Procedures as in LIEPDE:
  2. symbolic procedure comparedif1(u1l,u2l)$
  3. % checks whether u2l has more or at least equally many 1's, 2's, ...
  4. % contained as u1l.
  5. % returns a list of 1's, 2's, ... which are in excess in u2l
  6. % compared with u1l. The returned value is 0 if both are identical
  7. begin
  8. scalar ul;
  9. if u2l=nil then if u1l neq nil then return nil
  10. else return 0
  11. else if u1l=nil then return u2l
  12. else % both are non-nil
  13. if car u1l < car u2l then return nil else
  14. if car u1l = car u2l then return comparedif1(cdr u1l,cdr u2l) else <<
  15. ul:=comparedif1(u1l,cdr u2l);
  16. return if not ul then nil else
  17. if zerop ul then list car u2l else
  18. cons(car u2l,ul)
  19. >>
  20. end$ % of comparedif1
  21. %-------------
  22. symbolic procedure comparedif2(u1,u1list,du2)$
  23. % checks whether du2 is a derivative of u1 differentiated
  24. % wrt. u1list
  25. begin
  26. scalar u2l;
  27. u2l:=combidif(du2)$ % u2l=(u2, 1, 1, ..)
  28. if car u2l neq u1 then return nil else
  29. return comparedif1(u1list, cdr u2l)
  30. end$ % of comparedif2
  31. %-------------
  32. symbolic procedure listdifdif1(du1,deplist)$
  33. % lists all elements of deplist which are *not* derivatives
  34. % of du1
  35. begin
  36. scalar u1,u1list,res,h$
  37. h:=combidif(du1);
  38. u1:=car h;
  39. u1list:=cdr h;
  40. for each h in deplist do
  41. if not comparedif2(u1,u1list,h) then res:=cons(h,res);
  42. return res
  43. end$ % of listdifdif1
  44. %-------------
  45. symbolic operator listdifdif2$
  46. symbolic procedure listdifdif2(lhslist,deplist)$
  47. % lists all elements of deplist which are *not* derivatives
  48. % of any element of lhslist
  49. begin
  50. scalar h;
  51. deplist:=cdr reval deplist;
  52. lhslist:=cdr reval lhslist;
  53. for each h in lhslist do
  54. deplist:=listdifdif1(h,deplist);
  55. return cons('LIST,deplist)
  56. end$ % of listdifdif2
  57. %-------------
  58. symbolic operator totdeg$
  59. symbolic procedure totdeg(p,f)$
  60. % Ordnung (total) der hoechsten Ableitung von f im Ausdruck p
  61. eval(cons('PLUS,ldiff1(car ldifftot(reval p,reval f),fctargs reval f)))$
  62. %-------------
  63. symbolic procedure diffdeg(p,v)$
  64. % liefert Ordnung der Ableitung von p nach v$
  65. % p Liste Varible+Ordnung der Ableitung, v Variable (Atom)
  66. if null p then 0 % alle Variable bearbeitet ?
  67. else if car p=v then % v naechste Variable ?
  68. if cdr p then
  69. if numberp(cadr p) then cadr p % folgt eine Zahl ?
  70. else 1
  71. else 1
  72. else diffdeg(cdr p,v)$ % weitersuchen
  73. %-------------
  74. symbolic procedure ldiff1(l,v)$
  75. % liefert Liste der Ordnungen der Ableitungen nach den Variablen aus v
  76. % l Liste (Variable + Ordnung)$ v Liste der Variablen
  77. if null v then nil % alle Variable abgearbeitet ?
  78. else cons(diffdeg(l,car v),ldiff1(l,cdr v))$
  79. % Ordnung der Ableitung nach
  80. % erster Variable anhaengen
  81. %-------------
  82. symbolic procedure ldifftot(p,f)$
  83. % leading derivative total degree ordering
  84. % liefert Liste der Variablen + Ordnungen mit Potenz
  85. % p Ausdruck in LISP - Notation, f Funktion
  86. ldifftot1(p,f,fctargs f)$
  87. %-------------
  88. symbolic procedure ldifftot1(p,f,vl)$
  89. % liefert Liste der Variablen + Ordnungen mit Potenz
  90. % p Ausdruck in LISP - Notation, f Funktion, lv Variablenliste
  91. begin scalar a$
  92. a:=cons(nil,0)$
  93. if not atom p then
  94. if member(car p,list('EXPT,'PLUS,'MINUS,'TIMES,
  95. 'QUOTIENT,'DF,'EQUAL)) then
  96. % erlaubte Funktionen
  97. <<if (car p='PLUS) or (car p='TIMES) or (car p='QUOTIENT)
  98. or (car p='EQUAL) then
  99. <<p:=cdr p$
  100. while p do
  101. <<a:=diffreltot(ldifftot1(car p,f,vl),a,vl)$
  102. p:=cdr p>> >>
  103. else if car p='MINUS then
  104. a:=ldifftot1(cadr p,f,vl)
  105. else if car p='EXPT then % Exponent
  106. if numberp caddr p then
  107. <<a:=ldifftot1(cadr p,f,vl)$
  108. a:=cons(car a,times(caddr p,cdr a))>>
  109. else a:=cons(nil,0)
  110. % Poetenz aus Basis wird mit
  111. % Potenz multipliziert
  112. else if car p='DF then % Ableitung
  113. if cadr p=f then a:=cons(cddr p,1)
  114. % f wird differenziert?
  115. else a:=cons(nil,0)>> % sonst Konstante bzgl. f
  116. else if p=f then a:=cons(nil,1)
  117. % Funktion selbst
  118. else a:=cons(nil,0) % alle uebrigen Fkt. werden
  119. else if p=f then a:=cons(nil,1)$ % wie Konstante behandelt
  120. return a
  121. end$
  122. %-------------
  123. symbolic procedure diffreltot(p,q,v)$
  124. % liefert komplizierteren Differentialausdruck$
  125. if diffreltotp(p,q,v) then q
  126. else p$
  127. %-------------
  128. symbolic procedure diffreltotp(p,q,v)$
  129. % liefert t, falls p einfacherer Differentialausdruck, sonst nil
  130. % p, q Paare (liste.power), v Liste der Variablen
  131. % liste Liste aus Var. und Ordn. der Ableit. in Diff.ausdr.,
  132. % power Potenz des Differentialausdrucks
  133. begin scalar n,m$
  134. m:=eval(cons('PLUS,ldiff1(car p,v)))$
  135. n:=eval(cons('PLUS,ldiff1(car q,v)))$
  136. return
  137. if m<n then t
  138. else if n<m then nil
  139. else diffrelp(p,q,v)$
  140. end$
  141. %-------------
  142. algebraic procedure subdif1(xlist,ylist,ordr)$
  143. % A list of lists of derivatives of one order for all functions
  144. begin
  145. scalar allsub,revx,i,el,oldsub,newsub;
  146. revx:=reverse xlist;
  147. allsub:={};
  148. oldsub:= for each y in ylist collect y=y;
  149. for i:=1:ordr do % i is the order of next substitutions
  150. <<oldsub:=for each el in oldsub join nextdy(revx,xlist,el);
  151. allsub:=cons(oldsub,allsub)
  152. >>;
  153. return allsub
  154. end$
  155. %-------------
  156. algebraic procedure nextdy(revx,xlist,dy)$
  157. % generates all first order derivatives of lhs dy
  158. % revx = reverse xlist; xlist is the list of variables;
  159. % dy the old derivative
  160. begin
  161. scalar x,n,ldy,rdy,ldyx,sublist;
  162. x:=first revx; revx:=rest revx;
  163. sublist:={};
  164. ldy:=lhs dy;
  165. rdy:=rhs dy;
  166. while lisp(not member(prepsq simp!* algebraic x,
  167. prepsq simp!* algebraic ldy))
  168. and (revx neq {}) do
  169. <<x:=first revx; revx:=rest revx>>;
  170. n:=length xlist;
  171. if revx neq {} then % dy is not the function itself
  172. while first xlist neq x do xlist:=rest xlist;
  173. xlist:=reverse xlist;
  174. % New higher derivatives
  175. while xlist neq {} do
  176. <<x:=first xlist;
  177. ldyx:=df(ldy,x);
  178. sublist:=cons((lisp reval algebraic ldyx)=
  179. mkid(mkid(rdy,!`),n), sublist);
  180. n:=n-1;
  181. xlist:=rest xlist
  182. >>;
  183. return sublist
  184. end$
  185. %-------------
  186. symbolic procedure combidif(s)$
  187. % extracts the list of derivatives from s: % u`1`1`2 --> (u, 1, 1, 2)
  188. begin scalar temp,ans,no,n1;
  189. s:=reval s; % to guarantee s is in true prefix form
  190. temp:=reverse explode s;
  191. while not null temp do
  192. <<n1:=<<no:=nil;
  193. while (not null temp) and (not eqcar(temp,'!`)) do
  194. <<no:=car temp . no;temp:=cdr temp>>;
  195. compress no
  196. >>;
  197. if (not fixp n1) then n1:=intern n1;
  198. ans:=n1 . ans;
  199. if eqcar(temp,'!`) then <<temp:=cdr temp; temp:=cdr temp>>;
  200. >>;
  201. return ans
  202. end$
  203. %-------------
  204. symbolic operator dif$
  205. symbolic procedure dif(s,n)$
  206. % e.g.: dif(fnc!`1!`3!`3!`4, 3) --> fnc!`1!`3!`3!`3!`4
  207. begin scalar temp,ans,no,n1,n2,done;
  208. s:=reval s; % to guarantee s is in true prefix form
  209. temp:=reverse explode s;
  210. n2:=reval n;
  211. n2:=explode n2;
  212. while (not null temp) and (not done) do
  213. <<n1:=<<no:=nil;
  214. while (not null temp) and (not eqcar(temp,'!`)) do
  215. <<no:=car temp . no;temp:=cdr temp>>;
  216. compress no
  217. >>;
  218. if (not fixp n1) or ((fixp n1) and (n1 leq n)) then
  219. <<ans:=nconc(n2,ans); ans:='!` . ans; ans:='!! . ans; done:=t>>;
  220. ans:=nconc(no,ans);
  221. if eqcar(temp,'!`) then <<ans:='!` . ans; ans:='!! . ans;
  222. temp:=cdr temp; temp:=cdr temp>>;
  223. >>;
  224. return intern compress nconc(reverse temp,ans);
  225. end$
  226. %-------------
  227. algebraic procedure maklist(ex)$
  228. % making a list out of an expression if not already
  229. if lisp(atom algebraic ex) then {ex} else
  230. if lisp(car algebraic ex neq 'LIST) then ex:={ex}
  231. else ex$
  232. %-------------
  233. algebraic procedure depnd(y,xlist)$
  234. for each xx in xlist do
  235. for each x in xx do depend y,x$
  236. %==== Other procedures:
  237. symbolic operator totdif$
  238. symbolic procedure totdif(s,x,n,dylist)$
  239. % total derivative of s(x,dylist) w.r.t. x which is the n'th variable
  240. begin
  241. scalar tdf,el1,el2;
  242. tdf:=simpdf {s,x};
  243. <<dylist:=cdr dylist;
  244. while dylist do
  245. <<el1:=cdar dylist;dylist:=cdr dylist;
  246. while el1 do
  247. <<el2:=car el1;el1:=cdr el1;
  248. tdf:=addsq(tdf ,multsq( simp!* dif(el2,n), simpdf {s,el2}))
  249. >>
  250. >>
  251. >>;
  252. return prepsq tdf
  253. end$
  254. %-------------
  255. algebraic procedure simppl(pllist,ulist,tt,xx)$
  256. begin
  257. scalar pl,hh,td,xd,lulist,ltt,lxx,ltd,dv,newtd,e1,deno,ok,
  258. newpllist,contrace;
  259. %contrace:=t;
  260. lisp <<
  261. lulist:=cdr reval algebraic ulist;
  262. lxx:=reval algebraic xx;
  263. ltt:=reval algebraic tt;
  264. >>;
  265. newpllist:={};
  266. for each pl in pllist do <<
  267. td:=first pl;
  268. xd:=second pl;
  269. repeat <<
  270. lisp <<
  271. ltd:=reval algebraic td;
  272. if contrace then <<write"ltd1=",ltd;terpri()>>$
  273. dv:=nil;
  274. newtd:=nil;
  275. deno:=nil;
  276. if (pairp ltd) and (car ltd='QUOTIENT) and
  277. my_freeof(caddr ltd,ltt) and
  278. my_freeof(caddr ltd,lxx)
  279. then <<deno:=caddr ltd;ltd:=cadr ltd>>;
  280. ok:=t;
  281. if (pairp ltd) and (car ltd = 'PLUS) then ltd:= cdr ltd else
  282. if (pairp ltd) and (car ltd neq 'TIMES) then ok:=nil
  283. else ltd:=list ltd;
  284. if contrace then <<write"ltd2=",ltd;terpri()>>$
  285. if ok then <<
  286. for each e1 in ltd do <<
  287. hh:=intpde(e1, lulist, list(lxx,ltt), lxx, t);
  288. dv :=cons(car hh,dv);
  289. newtd:=cons(cadr hh,newtd);
  290. >>;
  291. dv :=reval cons('PLUS,dv);
  292. newtd:=reval cons('PLUS,newtd);
  293. if deno then <<newtd:=list('QUOTIENT,newtd,deno);
  294. dv :=list('QUOTIENT,dv ,deno) >>;
  295. if contrace then <<write"newtd=",newtd;terpri();
  296. write"dv=",dv ;terpri() >>$
  297. td:=newtd;
  298. if contrace then <<write"td=",td;terpri()>>$
  299. if (dv neq 0) and (dv neq nil) then <<
  300. xd:=reval(list('PLUS,xd,list('DF,dv,tt)));
  301. if contrace then <<write"xd=",xd;terpri()>>$
  302. %algebraic mode:
  303. %hh:=lisp gensym()$
  304. %sbb:=absorbconst({td*hh,xd*hh},{hh})$
  305. %if (sbb neq nil) and (sbb neq 0) then
  306. %<<td:=sub(sbb,td*hh)/hh; xd:=sub(sbb,xd*hh)/hh>>;
  307. % cllist would have to be scaled as well
  308. >>
  309. >>
  310. >>
  311. >>
  312. until lisp(dv)=0;
  313. newpllist:=cons({td,xd}, newpllist);
  314. >>;
  315. return reverse newpllist
  316. end$ % simppl
  317. %-------------
  318. symbolic operator fdepterms$
  319. symbolic procedure fdepterms(td,f)$
  320. % fdepterms regards td as a fraction where f occurs only in the
  321. % numerator. It determines all terms of the numerator in
  322. % which f occurs divided through the denominator.
  323. begin
  324. scalar nu,de,e1,sm;
  325. td:=reval td;
  326. if pairp td then
  327. if car td='QUOTIENT then <<nu:=cadr td;de:=caddr td>>;
  328. if null nu then nu:=td;
  329. if not pairp nu then if freeof(nu,f) then sm:=0
  330. else sm:=nu
  331. else <<
  332. if car nu = 'PLUS then nu:=cdr nu
  333. else nu:=list nu;
  334. for each e1 in nu do
  335. if not freeof(e1,f) then sm:=cons(e1,sm);
  336. if null sm then sm:=0 else
  337. if length sm = 1 then sm:=car sm
  338. else sm:=cons('PLUS,sm)
  339. >>;
  340. if de then sm:=list('QUOTIENT,sm,de);
  341. return sm
  342. end$ % of fdepterms
  343. %-------------
  344. end$