dcfsfqe.red 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. % ----------------------------------------------------------------------
  2. % $Id: dcfsfqe.red,v 1.7 2004/05/03 08:59:17 dolzmann Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 2004 Andreas Dolzmann and Thomas Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: dcfsfqe.red,v $
  7. % Revision 1.7 2004/05/03 08:59:17 dolzmann
  8. % Added verbose output.
  9. %
  10. % Revision 1.6 2004/04/27 16:54:54 dolzmann
  11. % Fixed a bug in the latest bug fix.
  12. %
  13. % Revision 1.5 2004/04/27 10:24:25 dolzmann
  14. % Fixed a bug in dcfsf_qebasis2: Infinite recursion should no longer occurr.
  15. %
  16. % Revision 1.4 2004/04/26 16:34:02 dolzmann
  17. % dcfsf_qevar can now handle truth values.
  18. % Removed superflous calls of cl_simpl.
  19. %
  20. % Revision 1.3 2004/04/26 16:24:44 dolzmann
  21. % Implemented quantifier elimination.
  22. %
  23. % Revision 1.2 2004/03/22 15:52:29 sturm
  24. % Implemented derivative of differential polynomial including theory.
  25. % Not tested so far.
  26. %
  27. % Revision 1.1 2004/03/22 12:31:49 sturm
  28. % Initial check-in.
  29. % Mostly copied from acfsf.
  30. % Includes Diploma Thesis by Kacem plus wrapper for this.
  31. %
  32. % ----------------------------------------------------------------------
  33. lisp <<
  34. fluid '(dcfsfqe_rcsid!* dcfsfqe_copyright!*);
  35. dcfsfqe_rcsid!* := "$Id: dcfsfqe.red,v 1.7 2004/05/03 08:59:17 dolzmann Exp $";
  36. dcfsfqe_copyright!* := "Copyright (c) 2004 A. Dolzmann, T. Sturm"
  37. >>;
  38. module dcfsfqe;
  39. % Diferentially closed field standard form quantifier elimination.
  40. procedure dcfsf_orddegf(f,v);
  41. % Diferentially closed field standard form order and degree. [f] is
  42. % a standard form; [v] is a variable. Returns a pair of numbers.
  43. % The [car] is the order and the [cdr] is the degree wrt. [v].
  44. dcfsf_orddegf1(f,v,(-1) . (-1));
  45. procedure dcfsf_orddegf1(f,v,od);
  46. % Diferentially closed field standard form order and degree
  47. % subroutine. [f] is a standard form; [v] is a variable; [od] is a
  48. % pair of numbers. Returns a pair of numbers. The [car] is the
  49. % order and the [cdr] is the degree wrt. [v].
  50. begin scalar mv,r; integer lord;
  51. if domainp f then
  52. return od;
  53. mv := mvar f;
  54. lord := if mv eq v then
  55. 0
  56. else if pairp mv and cadr mv eq v then
  57. caddr mv
  58. else
  59. -2;
  60. if lord > car od then
  61. od := lord . ldeg f
  62. else if lord = car od then
  63. od := lord . max(cdr od,ldeg f);
  64. r := f;
  65. while not domainp r and mvar r eq mv do
  66. r := red r;
  67. return dcfsf_orddegf1(lc f,v,dcfsf_orddegf1(r,v,od))
  68. end;
  69. procedure dcfsf_ordf(f,v);
  70. % Diferentially closed field standard form order. [f] is a standard
  71. % form with kernel order [{...,(d v 2),(d v 1),v}]; [v] is a
  72. % variable. Returns a number, the order of [f] wrt. [v].
  73. if domainp f then
  74. -1
  75. else if mvar f eq v then
  76. 0
  77. else if pairp mvar f and cadr mvar f eq v then
  78. caddr mvar f
  79. else
  80. -1;
  81. procedure dcfsf_degf(f,v);
  82. % Diferentially closed field standard form order. [f] is a standard
  83. % form with kernel order [{...,(d v 2),(d v 1),v}]; [v] is a
  84. % variable. Returns a number, the order of [f] wrt. [v].
  85. if domainp f then
  86. 0
  87. else if mvar f eq v or pairp mvar f and cadr mvar f eq v then
  88. ldeg f
  89. else
  90. 0;
  91. procedure dcfsf_df(f,x);
  92. % Diferentially closed field standard form derivative. [f] is a
  93. % standard form; [x] is a possibly composite kernel. Returns a
  94. % standard form. Computes the partial derivative of [f] wrt. [x].
  95. begin scalar oldorder,w;
  96. oldorder := setkorder {x};
  97. w := dcfsf_df1(reorder f,x);
  98. setkorder oldorder;
  99. return reorder w
  100. end;
  101. procedure dcfsf_df1(f,x);
  102. % Diferentially closed field standard form derivative subroutine.
  103. % [f] is a standard form; [x] is a possibly composite kernel that
  104. % is largest wrt. the current kernel order. Returns a standard
  105. % form. Computes the partial derivative of [f] wrt. [x].
  106. if domainp f or mvar f neq x then
  107. nil
  108. else if eqn(ldeg f,1) then
  109. lc f
  110. else
  111. x .** (ldeg f - 1) .* multf(ldeg f,lc f) .+ dcfsf_df1(red f,x);
  112. procedure dcfsf_derivationf(f,theo);
  113. % Diferentially closed field standard form derivation. [f] is a
  114. % standard form; [theo] is a theory. Returns a standard form.
  115. % Computes the derivative of [f].
  116. begin scalar res;
  117. for each v in kernels f do
  118. res := addf(res,multf(dcfsf_df(f,v),dcfsf_derivationk(v,theo)));
  119. return res
  120. end;
  121. procedure dcfsf_derivationk(k,theo);
  122. % Diferentially closed field kernel derivation. [k] is a kernel;
  123. % [theo] is a theory. Returns a standard form. Computes the
  124. % derivative of [k], which is possibly specified in [theo].
  125. begin scalar oldorder,kpf,kp,a,cnt;
  126. kp := dcfsf_derivationk1 k;
  127. kpf := kp .** 1 .* 1 .+ nil;
  128. oldorder := setkorder {kp};
  129. cnt := t;
  130. while cnt and theo do <<
  131. a := car theo;
  132. theo := cdr theo;
  133. if dcfsf_op a eq 'equal then <<
  134. a := dcfsf_arg2l a;
  135. if mvar a eq kp and lc a = 1 then <<
  136. cnt := nil;
  137. kpf := negf red a
  138. >>
  139. >>
  140. >>;
  141. setkorder oldorder;
  142. return reorder kpf
  143. end;
  144. procedure dcfsf_derivationk1(k);
  145. % Diferentially closed field kernel derivation subroutine. [k] is a
  146. % kernel. Returns a kernel. Computes the derivative of [k].
  147. if atom k then
  148. !*a2k {'d,k,1}
  149. else
  150. !*a2k {'d,cadr k,caddr k + 1};
  151. procedure dcfsf_qe!-kacem(f,theo);
  152. begin scalar w;
  153. f := rl_prepfof f;
  154. f := cl_pnf f;
  155. w := dqe_start1 f;
  156. if w eq t then
  157. w := 'true
  158. else if null w then
  159. w := 'false;
  160. w := rl_simp w;
  161. return w
  162. end;
  163. switch kacem;
  164. procedure dcfsf_qe(f,theo);
  165. if !*kacem then
  166. dcfsf_qe!-kacem(f,theo)
  167. else
  168. dcfsf_qe0(f,theo);
  169. procedure dcfsf_qe0(f,theo);
  170. begin scalar w,bl;
  171. f := cl_simpl(cl_pnf cl_nnf f,theo,-1);
  172. w := cl_splt f;
  173. bl := car w;
  174. f := cadr w;
  175. for each blk in bl do
  176. f := cl_simpl(dcfsf_qeblk(f,blk,theo),nil,-1);
  177. return f
  178. end;
  179. procedure dcfsf_qeblk(f,blk,theo);
  180. if car blk eq 'all then
  181. rl_nnfnot dcfsf_qeblk1(rl_nnfnot f,blk,theo)
  182. else
  183. dcfsf_qeblk1(f,blk,theo);
  184. procedure dcfsf_qeblk1(f,blk,theo);
  185. <<
  186. if !*rlverbose then
  187. ioto_tprin2t {"Eliminating ",blk};
  188. for each v in cdr blk do
  189. f := dcfsf_qevar(f,v,theo);
  190. f
  191. >>;
  192. procedure dcfsf_qevar(f,v,theo);
  193. begin scalar rl;
  194. if !*rlverbose then
  195. ioto_tprin2t {"Eliminating ",v};
  196. f := cl_dnf f;
  197. rl := if rl_op f eq 'or then
  198. for each ff in rl_argn f collect
  199. dcfsf_qevar1(ff,v,theo)
  200. else
  201. {dcfsf_qevar1(f,v,theo)};
  202. return rl_smkn('or,rl)
  203. end;
  204. procedure dcfsf_qevar1(f,v,theo);
  205. begin scalar r,w;
  206. if rl_tvalp f then
  207. return f;
  208. w := dcfsf_nf(f,v);
  209. r := dcfsf_qevar2(car w,cadr w,v,theo);
  210. r := rl_mkn('and,{rl_smkn('and,caddr w),r});
  211. return r
  212. end;
  213. procedure dcfsf_nf(f,v);
  214. if rl_op f eq 'and then
  215. dcfsf_nf1(rl_argn f,v)
  216. else
  217. dcfsf_nf1({f},v);
  218. procedure dcfsf_nf1(f,v);
  219. begin scalar e,n,s;
  220. n := numr simp 1;
  221. for each at in f do
  222. if not(v memq dcfsf_varlat at) then
  223. s := at . s
  224. else if dcfsf_op at eq 'equal then
  225. e := dcfsf_arg2l(at) . e
  226. else
  227. n := multf(dcfsf_arg2l at,n);
  228. return {e,n,s}
  229. end;
  230. procedure dcfsf_qevar2(fl,g,v,theo);
  231. % Special case on page 5.
  232. begin scalar oo,kl,r;
  233. kl := dcfsf_mkkl(v,dcfsf_maxorder(g . fl,v));
  234. oo := setkorder kl;
  235. fl := for each f in fl collect reorder f;
  236. g := reorder g;
  237. r := dcfsf_qesc5(fl,g,v,theo);
  238. setkorder oo;
  239. return cl_apply2ats(r,'dcfsf_reorderat)
  240. end;
  241. procedure dcfsf_reorderat(a);
  242. if rl_tvalp a then
  243. a
  244. else
  245. dcfsf_0mk2(dcfsf_op a,reorder dcfsf_arg2l a);
  246. procedure dcfsf_maxorder(fl,v);
  247. begin scalar w; integer m;
  248. for each f in fl do <<
  249. w := dcfsf_orddegf(f,v);
  250. if car w > m then
  251. m := car w
  252. >>;
  253. return m
  254. end;
  255. procedure dcfsf_mkkl(v,m);
  256. reversip(v . for i := 1 : m collect !*a2k {'d,v,i});
  257. procedure dcfsf_qesc5(fl,g,v,theo);
  258. % Special case on page 5.
  259. <<
  260. fl := sort(fl,'dcfsf_qeordp);
  261. if !*rlverbose then
  262. ioto_prin2 {"[",length fl,dcfsf_orddegf(lastcar fl,v),"] "};
  263. if null fl then
  264. dcfsf_qesc1(g,v,theo)
  265. else if null cdr fl then
  266. if g = 1 then
  267. dcfsf_qesc2(car fl,v,theo)
  268. else
  269. dcfsf_qebasis(car fl,g,v,theo)
  270. else
  271. dcfsf_qesc5r(fl,g,v,theo)
  272. >>;
  273. procedure dcfsf_qesc50(fl,g,v,theo);
  274. begin scalar nfl,r,f,pl;
  275. if null g then
  276. return 'false;
  277. if domainp g then
  278. g := 1;
  279. while fl do <<
  280. f := car fl;
  281. fl := cdr fl;
  282. if domainp f then <<
  283. if f then <<
  284. r := 'false;
  285. fl := nil
  286. >>
  287. >> else if not(v memq dcfsf_varlat1 kernels f) then
  288. pl := dcfsf_0mk2('equal,f) . pl
  289. else
  290. nfl := f . nfl;
  291. >>;
  292. if r eq 'false then
  293. return 'false;
  294. r := dcfsf_qesc5(nfl,g,v,theo);
  295. r := rl_mkn('and,{rl_smkn('and,pl),r});
  296. return r
  297. end;
  298. procedure dcfsf_qeordp(f1,f2);
  299. begin scalar p1,p2,v;
  300. v := dcfsf_mvar f1;
  301. p1 := dcfsf_orddegf(f1,v);
  302. p2 := dcfsf_orddegf(f2,v);
  303. return car p1 > car p2 or car p1 = car p2 and cdr p1 > cdr p2
  304. end;
  305. procedure dcfsf_mvar(f);
  306. begin scalar w;
  307. w := mvar f;
  308. return if pairp w and car w eq 'd then
  309. cadr w
  310. else
  311. w
  312. end;
  313. procedure dcfsf_qebasis(f1,g,v,theo);
  314. if null g then
  315. 'false
  316. else if domainp g then
  317. dcfsf_qesc2(f1,v,theo)
  318. else if dcfsf_ordf(g,v) leq dcfsf_ordf(f1,v) then
  319. dcfsf_qebasis1(f1,g,v,theo)
  320. else
  321. dcfsf_qebasis2(f1,g,v,theo);
  322. procedure dcfsf_qebasis1(f1,g,v,theo);
  323. begin scalar phi1p,phi2p;
  324. phi1p := dcfsf_qesc50({red f1,lc f1},g,v,theo);
  325. phi1p := cl_simpl(phi1p,nil,-1);
  326. if phi1p eq 'true then
  327. return 'true;
  328. phi2p := dcfsf_qesc(f1,lc f1,g,v,theo);
  329. return cl_simpl(rl_mkn('or,{phi1p,phi2p}),nil,-1);
  330. end;
  331. procedure dcfsf_qebasis2(f1,g,v,theo);
  332. begin scalar psi,sp,s1,sf1,if1,qr,r,dp,phi1p,phi3p,r;
  333. if1 := lc f1;
  334. sp := dcfsf_ordf(g,v);
  335. s1 := dcfsf_ordf(f1,v);
  336. sf1 := dcfsf_separant f1;
  337. dp := dcfsf_degf(g,v);
  338. qr := qremf(multf(exptf(sf1,dp),g),dcfsf_dn(f1,sp-s1,v,theo));
  339. r := cdr qr;
  340. phi1p := dcfsf_qesc50({red f1,lc f1},g,v,theo);
  341. if dcfsf_degf(f1,v) > 1 then <<
  342. psi := dcfsf_qebasis(f1,multf(multf(sf1,if1),r),v,theo);
  343. phi3p := dcfsf_qesc50({f1,sf1},g,v,theo);
  344. r := rl_mkn('or,{phi1p,psi,phi3p});
  345. >> else <<
  346. psi := dcfsf_qebasis(f1,multf(if1,r),v,theo);
  347. r := rl_mkn('or,{phi1p,psi})
  348. >>;
  349. return r
  350. end;
  351. procedure dcfsf_mvar(f);
  352. if domainp f then
  353. nil
  354. else if pairp mvar f and car f eq 'd then
  355. cadr mvar f
  356. else
  357. mvar f;
  358. procedure dcfsf_separant(f);
  359. dcfsf_df(f,mvar f);
  360. procedure dcfsf_qesc5r(fl,g,v,theo);
  361. begin scalar phi1p,phi2p,fm,ffl;
  362. ffl := reverse fl;
  363. fm := car ffl;
  364. phi1p := dcfsf_qesc50(red fm . lc fm . cdr ffl,g,v,theo);
  365. phi2p := dcfsf_qesc5r2(fl,g,v,theo);
  366. return rl_mkn('or,{phi1p,phi2p})
  367. end;
  368. procedure dcfsf_qesc5r2(fl,g,v,theo);
  369. begin scalar ffl,fm,fm1;
  370. ffl := reverse fl;
  371. fm := car ffl;
  372. ffl := cdr ffl;
  373. fm1 := car ffl;
  374. ffl := cdr ffl;
  375. if dcfsf_ordf(fm,v) = dcfsf_ordf(fm1,v) then
  376. return dcfsf_qesc5r2u1(fm,fm1,ffl,g,v,theo);
  377. return dcfsf_qesc5r2u2(fm,fm1,ffl,g,v,theo)
  378. end;
  379. procedure dcfsf_qesc5r2u1(fm,fm1,ffl,g,v,theo);
  380. begin scalar dm1,ifm,qr,r,psip;
  381. dm1 := dcfsf_degf(fm1,v);
  382. ifm := lc fm;
  383. qr := qremf(multf(exptf(ifm,dm1),fm1),fm);
  384. r := cdr qr;
  385. psip := dcfsf_qesc50(fm . r . ffl,multf(ifm,g),v,theo);
  386. return psip
  387. end;
  388. procedure dcfsf_qesc5r2u2(fm,fm1,ffl,g,v,theo);
  389. begin scalar sfm,dm1,qr,r,sm,sm1,psip,ifm;
  390. sfm := dcfsf_separant fm;
  391. dm1 := dcfsf_degf(fm1,v);
  392. sm := dcfsf_ordf(fm,v);
  393. sm1 := dcfsf_ordf(fm1,v);
  394. ifm := lc fm;
  395. qr := qremf(multf(exptf(sfm,dm1),fm1),
  396. dcfsf_dn(fm,sm1-sm,v,theo));
  397. r := cdr qr;
  398. psip := dcfsf_qesc50(fm . r . ffl,multf(ifm,g),v,theo);
  399. return psip
  400. end;
  401. procedure dcfsf_dn(f,n,v,theo);
  402. begin scalar r,s,m;
  403. m := if kord!* and pairp car kord!* and car car kord!* eq 'd then
  404. caddr car kord!* else 0;
  405. s := car dcfsf_orddegf(f,v);
  406. m := max(m,s+n);
  407. setkorder dcfsf_mkkl(v,m);
  408. r := reorder f;
  409. for i := 1 : n do
  410. r := dcfsf_derivationf(r,theo);
  411. return reorder r;
  412. end;
  413. procedure dcfsf_qesc1(g,v,theo);
  414. rl_smkn('or,for each gt in dcfsf_cl(g,v) collect dcfsf_0mk2('neq,gt));
  415. procedure dcfsf_cl(f,v);
  416. if domainp f or not(v memq dcfsf_varlat1 kernels f) then
  417. {f}
  418. else
  419. nconc(dcfsf_cl(lc f,v),dcfsf_cl(red f,v));
  420. procedure dcfsf_cl1(f,v);
  421. dcfsf_cl2(f,v,T);
  422. procedure dcfsf_cl2(f,v,flg);
  423. begin scalar w;
  424. if domainp f or not(v memq dcfsf_varlat1 kernels f) then
  425. return if flg then
  426. nil . f
  427. else
  428. {f} . nil
  429. else <<
  430. w := dcfsf_cl2(red f,v,T);
  431. return nconc(car dcfsf_cl2(lc f,v,nil),car w) . cdr w
  432. >>
  433. end;
  434. procedure dcfsf_qesc(f1,if1,g,v,theo);
  435. begin
  436. if null g or null if1 then
  437. return 'false;
  438. if domainp if1 then
  439. if1 := 1;
  440. if g = 1 and not(v memq dcfsf_varlat1 kernels if1) then
  441. return rl_mkn('and,{dcfsf_0mk2('neq,if1),dcfsf_qesc2(f1,v,theo)});
  442. if dcfsf_ordf(g,v) < dcfsf_ordf(f1,v) then
  443. return dcfsf_qesc3(f1,g,if1,v,theo);
  444. return dcfsf_qesc4(f1,g,if1,v,theo);
  445. end;
  446. procedure dcfsf_qesc2(f,v,theo);
  447. begin scalar w,ftl,f1;
  448. w := dcfsf_cl1(f,v);
  449. f1 := cdr w;
  450. ftl := car w;
  451. return rl_smkn('or,dcfsf_0mk2('equal,f1) .
  452. for each gt in ftl collect dcfsf_0mk2('neq,gt))
  453. end;
  454. procedure dcfsf_qesc3(f,g,iff,v,theo);
  455. begin scalar iff,w1,w2;
  456. w1 := for each gt in dcfsf_cl(g,v) collect
  457. dcfsf_0mk2('neq,gt);
  458. w2 := for each ct in dcfsf_cl(iff,v) collect
  459. dcfsf_0mk2('neq,ct);
  460. return rl_mkn('and,{rl_smkn('or,w1),rl_smkn('or,w2)})
  461. end;
  462. procedure dcfsf_qesc4(f,g,iff,v,theo);
  463. begin scalar qr,dd,dp,w1,w2,r,s;
  464. dd := dcfsf_degf(f,v);
  465. dp := dcfsf_degf(g,v);
  466. s := dcfsf_ordf(f,v);
  467. qr := qremf(multf(exptf(iff,dd*dp),exptf(g,dd)),f);
  468. r := cdr qr;
  469. w1 := for each ct in dcfsf_cl(iff,v) collect
  470. dcfsf_0mk2('neq,ct);
  471. w2 := for each rt in dcfsf_cl(r,v) collect
  472. dcfsf_0mk2('neq,rt);
  473. return rl_mkn('and,{rl_smkn('or,w1),rl_smkn('or,w2)})
  474. end;
  475. endmodule; % [dcfsfqe]
  476. end; % of file