acfsfgs.red 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. % ----------------------------------------------------------------------
  2. % $Id: acfsfgs.red,v 1.6 1999/04/13 13:05:33 sturm Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 1995-1999 Andreas Dolzmann and Thomas Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: acfsfgs.red,v $
  7. % Revision 1.6 1999/04/13 13:05:33 sturm
  8. % Minor corrections in comments.
  9. %
  10. % Revision 1.5 1999/04/12 09:25:58 sturm
  11. % Updated comments for exported procedures.
  12. %
  13. % Revision 1.4 1999/03/23 08:14:18 dolzmann
  14. % Changed copyright information.
  15. % Added fluids for the rcsid of the file and for the copyright information.
  16. %
  17. % Revision 1.3 1997/10/02 13:49:49 dolzmann
  18. % In procedure acfsf_qe1: Remove atomic formulas containing bound variables
  19. % from the theory.
  20. %
  21. % Revision 1.2 1997/08/24 16:17:41 sturm
  22. % Call cl_sitheo instead of acfsf_gssimpltheo.
  23. % Added service rl_surep with black box rl_multsurep.
  24. % Added service rl_siaddatl.
  25. %
  26. % Revision 1.1 1997/08/22 17:30:39 sturm
  27. % Created an acfsf context based on ofsf.
  28. %
  29. % ----------------------------------------------------------------------
  30. lisp <<
  31. fluid '(acfsf_gs_rcsid!* acfsf_gs_copyright!*);
  32. acfsf_gs_rcsid!* :=
  33. "$Id: acfsfgs.red,v 1.6 1999/04/13 13:05:33 sturm Exp $";
  34. acfsf_gs_copyright!* := "Copyright (c) 1995-1999 A. Dolzmann and T. Sturm"
  35. >>;
  36. module acfsfgs;
  37. % Algebraically closed field standard form Groebner simplifier.
  38. % Submodule of [acfsf].
  39. %DS
  40. % <CIMPL> ::= (<GP>, <PROD1>, <PROD2>, <OTHER>)
  41. % <GP> ::= ((<GB> . <PROD>) . <OTHER>)
  42. % <GB> ::= (<SF>,...)
  43. % <PROD> ::= <SF>
  44. % <PROD1> ::= <SF>
  45. % <PROD2> ::= <SF>
  46. % <OTHER> ::= (<ATOMIC_FORMULA>,...)
  47. procedure acfsf_gsc(f,atl);
  48. % Algebraically closed field Groebner simplification via
  49. % conjunctive normal form. [f] is a formula; [atl] is a theory.
  50. % Returns [inconsistent] or a formula equivalent to [f]. The
  51. % returned formula is somehow simpler than [f]. This procedure
  52. % temporarily turns off the switches [groebopt] and [rlsiexpla].
  53. % Temporarily changes the [torder] to [{{},revgradlex}] unless
  54. % [rlgsutord] is on. Accesses the switches [rlverbose], [rlgsvb],
  55. % [rlgsbnf], [rlgsrad], [rlgssub], [rlgsred], [rlgsprod],
  56. % [rlgserf], [rlgsutord], and the fluid [rlradmemv!*].
  57. begin scalar w,svrlgsvb;
  58. svrlgsvb := !*rlgsvb;
  59. if !*rlverbose and !*rlgsvb then on1 'rlgsvb else off1 'rlgsvb;
  60. w := acfsf_gsc1(f,atl);
  61. onoff('rlgsvb,svrlgsvb);
  62. return w
  63. end;
  64. procedure acfsf_gsc1(f,atl);
  65. % Algebraically closed field Groebner simplification via
  66. % conjunctive normal form subroutine. [f] is a formula; [atl] is a
  67. % theory. Returns [inconsistent] or a formula equivalent to [f].
  68. % The returned formula is somehow simpler than [f]. This procedure
  69. % temporarily turns off the switches [groebopt] and [rlsiexpla].
  70. % Temporarily changes the [torder] to [{{},revgradlex}] unless
  71. % [rlgsutord] is on. Accesses the switches [rlgsvb], [rlgsbnf],
  72. % [rlgsrad], [rlgssub], [rlgsred], [rlgsprod], [rlgserf],
  73. % [rlgsutord], and the fluid [rlradmemv!*].
  74. begin scalar phi,!*rlsiexpla; % Hack, but otherwise phi is not a bnf!
  75. if !*rlgsbnf then <<
  76. if !*rlgsvb then ioto_prin2 "[CNF";
  77. phi := cl_simpl(cl_cnf cl_nnf f,atl,-1);
  78. if !*rlgsvb then ioto_prin2 "] "
  79. >> else
  80. phi := cl_simpl(f,atl,-1);
  81. if phi eq 'inctheo then return 'inctheo;
  82. if rl_tvalp phi then
  83. return phi;
  84. phi := acfsf_gssimplify0(phi,atl);
  85. if phi eq 'inctheo then return 'inctheo;
  86. return cl_simpl(phi,atl,-1)
  87. end;
  88. procedure acfsf_gsd(f,atl);
  89. % Algebraically closed field Groebner simplification via
  90. % disjunctive normal form. [f] is a formula; [atl] is a theory.
  91. % Returns [inconsistent] or a formula equivalent to [f]. The
  92. % returned formula is somehow simpler than [f]. This procedure
  93. % temporarily turns off the switches [groebopt] and [rlsiexpla].
  94. % Temporarily changes the [torder] to [{{},revgradlex}] unless
  95. % [rlgsutord] is on. Accesses the switches [rlverbose], [rlgsvb],
  96. % [rlgsbnf], [rlgsrad], [rlgssub], [rlgsred], [rlgsprod],
  97. % [rlgserf], [rlgsutord], and the fluid [rlradmemv!*].
  98. begin scalar w,svrlgsvb;
  99. svrlgsvb := !*rlgsvb;
  100. if !*rlverbose and !*rlgsvb then on1 'rlgsvb else off1 'rlgsvb;
  101. w := acfsf_gsd1(f,atl);
  102. onoff('rlgsvb,svrlgsvb);
  103. return w
  104. end;
  105. procedure acfsf_gsd1(f,atl);
  106. % Algebraically closed field Groebner simplification via
  107. % disjunctive normal form subroutine. [f] is a formula; [atl] is a
  108. % theory. Returns [inconsistent] or a formula equivalent to [f].
  109. % The returned formula is somehow simpler than [f]. This procedure
  110. % temporarily turns off the switches [groebopt] and [rlsiexpla].
  111. % Temporarily changes the [torder] to [{{},revgradlex}] unless
  112. % [rlgsutord] is on. Accesses the switches [rlgsvb], [rlgsbnf],
  113. % [rlgsrad], [rlgssub], [rlgsred], [rlgsprod], [rlgserf],
  114. % [rlgsutord], and the fluid [rlradmemv!*].
  115. begin scalar phi,!*rlsiexpla; % Hack, but otherwise phi is not a bnf!
  116. if !*rlgsbnf then <<
  117. if !*rlgsvb then ioto_prin2 "[DNF";
  118. phi := cl_simpl(cl_nnfnot cl_dnf f,atl,-1);
  119. if !*rlgsvb then ioto_prin2 "] ";
  120. >> else
  121. phi := cl_simpl(cl_nnfnot f,atl,-1);
  122. if phi eq 'inctheo then return 'inctheo;
  123. if rl_tvalp phi then
  124. return cl_nnfnot phi;
  125. phi := acfsf_gssimplify0(phi,atl);
  126. if phi eq 'inctheo then return 'inctheo;
  127. return cl_simpl(cl_nnfnot phi,atl,-1)
  128. end;
  129. procedure acfsf_gsn(f,atl);
  130. % Algebraically closed field Groebner simplification via normal
  131. % form. [f] is a formula; [atl] is a theory. Returns [inconsistent]
  132. % or a formula equivalent to [f]. The returned formula is somehow
  133. % simpler than [f]. The normal form used depends on the toplevel
  134. % operator of [f]. This procedure temporarily turns off the
  135. % switches [groebopt] and [rlsiexpla]. Temporarily changes the
  136. % [torder] to [{{},revgradlex}] unless [rlgsutord] is on. Accesses
  137. % the switches [rlverbose], [rlgsvb], [rlgsbnf], [rlgsrad],
  138. % [rlgssub], [rlgsred], [rlgsprod], [rlgserf], [rlgsutord], and the
  139. % fluid [rlradmemv!*].
  140. if rl_tvalp f then
  141. f
  142. else if cl_atflp(rl_argn f) then
  143. if rl_op(f) eq 'and then acfsf_gsd(f,atl) else acfsf_gsc(f,atl)
  144. else
  145. if rl_op(f) eq 'and then acfsf_gsc(f,atl) else acfsf_gsd(f,atl);
  146. procedure acfsf_gssimplify0(f,atl);
  147. % Algebraically closed field Groebner simplify. [f] is a
  148. % conjunction of disjunctions of atomic formulas, a disjunction of
  149. % atomic formulas, or an atomic formula; [atl] is a theory. Returns
  150. % [inctheo] or a formula. This procedure temporarily turns off the
  151. % switch [groebopt]. Temporarily changes the [torder] to
  152. % [{{},revgradlex}] unless [rlgsutord] is on. Accesses the switches
  153. % [rlgsvb], [rlgsrad], [rlgssub], [rlgsred], [rlgsprod], [rlgserf],
  154. % [rlgsutord], and the fluid [rlradmemv!*].
  155. begin scalar res,oldtorder,!*groebopt,svkord;
  156. svkord := kord!*;
  157. oldtorder := cdr torder('((list) revgradlex));
  158. if !*rlgsutord then
  159. torder(oldtorder);
  160. res := acfsf_gssimplify(f,atl);
  161. torder oldtorder;
  162. kord!* := svkord;
  163. return res;
  164. end;
  165. procedure acfsf_gssimplify(f,atl);
  166. % Algebraically closed field Groebner simplify. [f] is a
  167. % conjunction of disjunctions of atomic formulas, a disjunction of
  168. % atomic formulas, or an atomic formula; [atl] is a theory. Returns
  169. % [inctheo] or a formula. Accesses the switches [rlgsvb],
  170. % [rlgsrad], [rlgssub], [rlgsred], [rlgsprod], [rlgserf], and the
  171. % fluid [rlradmemv!*].
  172. begin scalar al,gp,ipart,npart,w,gprem,gprodal,gatl;
  173. atl := cl_sitheo atl;
  174. if atl eq 'inctheo or acfsf_gsinctheop(atl) then
  175. return 'inctheo;
  176. if (cl_atfp f) or (rl_op f eq 'or) then % degenerated cnf
  177. al := acfsf_gssplit!-cnf {f}
  178. else
  179. al := acfsf_gssplit!-cnf rl_argn f;
  180. if w := lto_catsoc('gprem,al) then <<
  181. gp := acfsf_gsextract!-gp atl;
  182. gprem := acfsf_gsgprem(w,gp);
  183. if gprem eq 'false then return 'false;
  184. >>;
  185. gatl := append(atl,lto_catsoc('gprem,al));
  186. gp := acfsf_gsextract!-gp(gatl);
  187. caar gp := sfto_groebnerf(caar gp);
  188. ipart := lto_catsoc('impl,al);
  189. npart := lto_catsoc('noneq,al);
  190. if ipart then
  191. ipart := acfsf_gspart(ipart,gp);
  192. if npart and gatl then
  193. npart := acfsf_gspart(npart,gp);
  194. if gprem then <<
  195. if null !*rlgsprod then <<
  196. gprodal := lto_catsoc('gprodal,al);
  197. gprem := acfsf_gssimulateprod(gprem,gprodal)
  198. >>;
  199. return rl_smkn('and,gprem . nconc(ipart,npart))
  200. >>;
  201. return rl_smkn('and,nconc(ipart,npart))
  202. end;
  203. procedure acfsf_gsinctheop(atl);
  204. % Algebraically closed field standard form Groebner simplifier
  205. % inconsistent theory predicate. [atl] is a list of atomic
  206. % formulas. [T] or [nil] is returned.
  207. begin scalar w;
  208. if null atl then
  209. return nil;
  210. if !*rlgsvb then ioto_prin2 "Inctheop... ";
  211. w := cl_nnfnot acfsf_gsimplication(
  212. cl_nnfnot rl_smkn('and,atl),'((nil . 1) . nil));
  213. if !*rlgsvb then ioto_prin2t "done.";
  214. return w eq 'false
  215. end;
  216. procedure acfsf_gssplit!-cnf(f);
  217. % Algebraically closed field standard form Groebner simplifier
  218. % split conjunctive normal form. [f] is an list of disjunctions of
  219. % atomic formulas. An assoc list is returned. The returned assoc
  220. % list have the following items. [('impl . imp)] where [imp] is the
  221. % list off all disjunctions containing at least one inequation,
  222. % [('gprem . gprem)] where [gprem] is the list of all atomic
  223. % formulas occuring in [f] and atomic formulas equivalent to
  224. % disjunctions of inequalities occuring in [f], [('noneq . noneq)]
  225. % where [noneq] is a list of disjunctions of atomic formulas
  226. % containing no inequations, and [('gprodal . gprodal)]. The value
  227. % [gprodal] is a assoc list containing to each equation the product
  228. % representation, if the equation was extracted from a disjunction.
  229. begin scalar noneq,imp,prod,gprodal,gprem,w,x;
  230. for each phi in f do
  231. if rl_op phi memq '(and or) then % [phi] is not an atomic formula
  232. if (w := acfsf_gsdis!-type rl_argn phi) eq 'impl then
  233. imp := phi . imp
  234. else if w eq 'noneq then
  235. noneq := phi . noneq
  236. else << % [if w eq 'equal then]
  237. prod := 1;
  238. for each atf in rl_argn phi do
  239. prod := multf(prod,acfsf_arg2l atf);
  240. x := acfsf_0mk2('equal,prod);
  241. gprem := x . gprem;
  242. gprodal := (x . phi) . gprodal
  243. >>
  244. else
  245. gprem := phi . gprem;
  246. if !*rlgsvb then <<
  247. ioto_tprin2t {"global: ",length gprem,"; impl: ",length imp,
  248. "; no neq: ",length noneq, "; glob-prod-al: ",length gprodal,"."}
  249. >>;
  250. return { 'impl . imp, 'noneq . noneq, 'gprem . gprem, 'gprodal . gprodal}
  251. end;
  252. procedure acfsf_gsdis!-type(atl);
  253. % Algebraically closed field standard form Groebner simplifier
  254. % disjunction type. [atl] is a non null list of atomic formulas.
  255. % ['equal], ['impl], or ['noneq] is returned. ['equal] is returned
  256. % if and only if all atomic formulas have the relation [equal];
  257. % [impl] is returned, if and only if one of the atomic formula is
  258. % an equality, otherwise [noneq] is returned.
  259. begin scalar op,w;
  260. if null atl then return 'equal;
  261. op := acfsf_op car atl;
  262. if op eq 'neq then return 'impl;
  263. w := acfsf_gsdis!-type cdr atl;
  264. if w eq 'impl then return 'impl;
  265. if op eq 'equal and w eq 'equal then return 'equal;
  266. return 'noneq
  267. end;
  268. procedure acfsf_gsextract!-gp(atl);
  269. % Algebraically closed field standard form extract global premise.
  270. % [atl] is a list of atomic formulas. A GP is returned.
  271. begin scalar w;
  272. w := acfsf_gsdis2impl(for each at in atl collect acfsf_negateat(at));
  273. return ( (car w . multf(cadr w, caddr w)) . cadddr w)
  274. end;
  275. procedure acfsf_gsgprem(atl,gp);
  276. % Algebraically closed field standard form Groebner simplifier
  277. % simplify global premise. [atl] is a list of atomic formulas; [gp]
  278. % is a GP. A formula is returned.
  279. begin scalar w;
  280. if !*rlgsvb then ioto_prin2 "[GP";
  281. w := cl_nnfnot acfsf_gsimplication(cl_nnfnot rl_smkn('and,atl),gp);
  282. if !*rlgsvb then ioto_prin2 "] ";
  283. return w
  284. end;
  285. procedure acfsf_gspart(part,gp);
  286. % Algebraically closed field standard form Groebner simplify
  287. % simplify part. [part] is a list of disjunctions of atomic
  288. % formulas and atomic formulas. [gp] is a GP. A list [l] of
  289. % disjunctions of atomic formulas and atomic formulas is returned.
  290. % The formula on position $i$ in [l] is somehow simpler than the
  291. % formula on the position $i$ in part. Supposed that the formula
  292. % $\bigwedge(g_i=0)$ is true where $g_i$ are the terms in [gp] then
  293. % the positional corresponding fomulas in the two lists [part] and
  294. % [l] are equivalent.
  295. begin scalar w,curlen,res;
  296. if !*rlgsvb then curlen := length part;
  297. res := for each phi in part collect <<
  298. if !*rlgsvb then ioto_prin2 {"[",curlen};
  299. w := acfsf_gsimplication(phi,gp);
  300. if !*rlgsvb then << curlen := curlen - 1; ioto_prin2 {"] "} >>;
  301. w
  302. >>;
  303. if !*rlgsvb then ioto_cterpri();
  304. return res
  305. end;
  306. procedure acfsf_gsimplication(f,gp);
  307. % Algebraically closed field standard form Groebner simplification
  308. % implication. [f] is a disjunction of atomic formulas or an atomic
  309. % formula. [gp] is a GP. Returns a formula. It is a truth value, an
  310. % atomic formula or a disjunction of atomic formulas, unless the
  311. % simplification of an atomic formula yields a complex formula.
  312. begin scalar prem,prod1,prod2,gprod,rprod,iprem,w,z,atl,natl;
  313. if cl_cxfp f then atl := rl_argn f else atl := {f};
  314. w := acfsf_gsdis2impl atl;
  315. iprem := car w;
  316. prod1 := cadr w;
  317. prod2 := caddr w;
  318. gprod := cdar gp;
  319. prem := append(iprem,caar gp);
  320. if null prem then return f;
  321. prem := sfto_groebnerf prem;
  322. z := numr simp acfsf_gsmkradvar();
  323. rprod := acfsf_gseqprod(prod1,prod2,gprod,prem,z);
  324. if rprod eq 'true then <<
  325. if !*rlgsvb then ioto_prin2 "!";
  326. return 'true
  327. >>;
  328. w := acfsf_gsusepremise(cdr gp,prem,z);
  329. if w eq 'true then <<
  330. if !*rlgsvb then ioto_prin2 "!";
  331. return 'true
  332. >>;
  333. natl := acfsf_gsredatl(atl,prem,z,rprod);
  334. if natl eq 'true then <<
  335. if !*rlgsvb then ioto_prin2 "!";
  336. return 'true
  337. >>;
  338. if rprod and rprod neq 'false then natl := rprod . natl;
  339. natl := nconc(natl,acfsf_gspremise(iprem,caar gp));
  340. return rl_smkn('or,natl)
  341. end;
  342. procedure acfsf_gsredatl(atl,prem,z,rprod);
  343. % Algebraically closed field standard form reduce atomic formula
  344. % list. [atl] is a list of SF's; [prem] is a Groebner basis; [z] is
  345. % a kernel; [rprod] is a flag. Returns ['true] or a list of atomic
  346. % formulas.
  347. begin scalar a,w,natl;
  348. while atl do <<
  349. a := car atl;
  350. atl := cdr atl;
  351. w := acfsf_gsredat(a,prem,z,rprod);
  352. if w eq 'true then
  353. atl := nil
  354. else if w and w neq 'false then
  355. natl := w . natl
  356. >>;
  357. if w eq 'true then return 'true;
  358. return natl
  359. end;
  360. procedure acfsf_gsusepremise(atl,prem,z);
  361. % Algebraically closed field standard form use premise. [atl] is a
  362. % list of atomic formulas; [prem] is a Groebner basis; [z] is a
  363. % kernel. returns [nil] or ['true].
  364. begin scalar w;
  365. while atl do <<
  366. w := acfsf_gsredat(car atl,prem,z,nil);
  367. if w eq 'true then
  368. atl := nil
  369. else
  370. atl := cdr atl;
  371. >>;
  372. if w eq 'true then return 'true;
  373. end;
  374. procedure acfsf_gseqprod(iprod1,iprod2,gprod,prem,z);
  375. % Algebraically closed field standard form equation product.
  376. % [iprod1], [iprod2], and [prem] are SF's; [prem] is a list of
  377. % SF's; [z] is a kernel. Returns [nil] or a formula.
  378. begin scalar p,w;
  379. p := multf(iprod1,multf(iprod2,gprod));
  380. % Comment the test on [!*rlgsrad] out if the radical membership
  381. % test should always be performed for the equation product.
  382. if !*rlgsrad and
  383. (null sfto_greducef(1,addf(1,negf multf(p,z)) . prem))
  384. then
  385. return 'true;
  386. w := acfsf_gstryeval('equal,sfto_preducef(p,prem));
  387. if rl_tvalp w then return w;
  388. if null !*rlgsprod then return nil;
  389. if !*rlgsred then
  390. return acfsf_0mk2('equal,sfto_preducef(iprod1,prem));
  391. return acfsf_0mk2('equal,iprod1);
  392. end;
  393. procedure acfsf_gsmkradvar();
  394. % Algebraically closed field standard form Groebner simplifier make
  395. % radical memebership test variable. Returns an identifier that is
  396. % not used as an algebraic mode variable.
  397. begin scalar w; integer n;
  398. w := 'rlgsradmemv!*;
  399. while get(w,'avalue) do
  400. w := mkid(w,n := n+1);
  401. if !*rlgsutord then
  402. acfsf_gsupdtorder w;
  403. return w;
  404. end;
  405. procedure acfsf_gsupdtorder(v);
  406. % Algebraically closed field standard form Groebner simplifier
  407. % update term order. [v] is a kernel. Inserts the main variable [v]
  408. % into the variable list of the global fixed term order of the
  409. % [groebner] package. Not all torders are supported, if a variable
  410. % list is present. To get over this problem one can insert the tag
  411. % variable [v] in the variable list before calling the Groebner
  412. % simplifier.
  413. begin scalar curtorder,vl,remain,mode;
  414. curtorder := cdr torder('((list) revgradlex));
  415. vl := cdar curtorder;
  416. if null vl or (v memq vl) then <<
  417. torder curtorder;
  418. return nil
  419. >>;
  420. mode := cadr curtorder;
  421. if not(mode memq '(lex gradlex revgradlex gradlexgradlex
  422. gradlexrevgradlex lexgradlex lexrevgradlex weighted))
  423. then
  424. rederr {"term order", mode, "not supported"};
  425. remain := cddr curtorder;
  426. vl := append(vl,{v});
  427. torder (('list . vl) . mode . remain)
  428. end;
  429. procedure acfsf_gstryeval(rel,lhs);
  430. % Algebraically closed field standard form try evaluation. [rel] is
  431. % an acfsf-relation; [lhs] a SF. returns [nil], a truth value or an
  432. % atomic formula. In the first case the atomic formula $([lhs]
  433. % [rel] 0)$ cannot be evaluated or should be ignored. In the other
  434. % case the returned value is equivalent to the the atomic formula.
  435. begin scalar w,!*rlsiexpla;
  436. if !*rlgserf then <<
  437. w := cl_simplat(acfsf_0mk2(rel,lhs),nil);
  438. return if rl_tvalp w then w
  439. >>;
  440. if domainp lhs then
  441. return cl_simplat(acfsf_0mk2(rel,lhs),nil)
  442. end;
  443. procedure acfsf_gsdis2impl(atl);
  444. % Algebraically closed field standard form Groebner simplifier
  445. % disjunction to implication. [atl] is a list of atomic formulas. A
  446. % CIMPL is returned. The classification of the atomic formulas in
  447. % [atl] is done by [acfsf_attype].
  448. begin scalar prem,prod1,prod2,other,w,a;
  449. prod1 := prod2 := 1;
  450. for each at in atl do <<
  451. w := acfsf_gsattype at;
  452. if w then <<
  453. a := car w;
  454. if a eq 'equal then
  455. prod1 := multf(cdr w,prod1)
  456. else if a eq 'cequal then
  457. prod2 := multf(cdr w,prod2)
  458. else if a eq 'neq then
  459. prem := cdr w . prem
  460. else
  461. rederr {"BUG IN ACFSF_GSDIS2IMPL",car w}
  462. >>;
  463. if not (w memq '(equal neq)) then
  464. other := at . other
  465. >>;
  466. return {prem, prod1, prod2, other};
  467. end;
  468. procedure acfsf_gsattype(at);
  469. % Algebraically closed field standard form Groebner simplifier
  470. % atomic formula type. [at] is an atomic formula. [nil] or a pair
  471. % $(\rho,p)$ is returned. $\rho$ is either ['equal], ['neq], or
  472. % ['cequal]; $p$ is a SF.
  473. (if w eq 'equal then
  474. ('equal . acfsf_arg2l at)
  475. else if w memq '(geq leq) then
  476. ('cequal . acfsf_arg2l at)
  477. else if w eq 'neq then
  478. ('neq . acfsf_arg2l at)) where w=acfsf_op at;
  479. procedure acfsf_gsredat(at,gb,z,flag);
  480. % Algebraically closed field standard form Groebner simplifier
  481. % reduce atomic formula. [at] is an atomic formula; [gb] is a
  482. % Groebner basis; [z] is a variable; [flag] is a flag. [nil], a
  483. % truth value or an atomic formula is returned. The behavior of
  484. % this procedure depends on the switches [rl_gsred] and [rl_gsrad].
  485. % [nil] is returned if the atomic formula belongs to the premise or
  486. % [flag] is [T] and [at] is an equation. Is [flag] is non [nil]
  487. % then equations can be ignored. In the other cases the returned
  488. % value is equivalent to [at]. The intention of this procedure is
  489. % the reduction of [at] wrt. the radical generated by [gb].
  490. begin scalar w,x,op,arg,nat;
  491. op := acfsf_op at;
  492. if (op eq 'neq) or (flag and op eq 'equal) then return nil;
  493. arg := acfsf_arg2l at;
  494. w := sfto_preducef(arg,gb);
  495. if !*rlgsred then
  496. nat := cl_simplat(acfsf_0mk2(op,w),nil)
  497. else
  498. if x := acfsf_gstryeval(op,w) then
  499. nat := x
  500. else
  501. nat := at;
  502. if (rl_tvalp nat) or (op eq 'equal) or (null !*rlgsrad) then
  503. return nat;
  504. if null sfto_greducef(1,addf(1,negf multf(w,z)) . gb) then
  505. return cl_simplat(acfsf_0mk2(op,nil),nil);
  506. return nat;
  507. end;
  508. procedure acfsf_gspremise(tl,gp);
  509. % Algebraically closed field standard form Groebner simplify
  510. % premise. [tl] and [gp] are lists of SF's. A list of atomic
  511. % formulas is returned. The behavior of this procedure depends on
  512. % the switches [rl_gsred] and [rl_gssub]. The conjunction over the
  513. % returned formulas is equivalent to the formula $\bigvee(t_i \neq
  514. % 0)$ supposed that $\bigwedge(g_j = 0)$, where $t_i$ are the terms
  515. % in [tl] and $g_j$ are the terms in [gp]. If the switch [rl_gsred]
  516. % is on then all terms $t_i$ are reduced modulo Id([gp]). If the
  517. % switch [!*rl_gssub] is on, the term list is substituted by the
  518. % reduced Groebner base of the term list.
  519. begin scalar gb,rtl,w;
  520. if !*rlgsred then <<
  521. gb := sfto_groebnerf gp;
  522. for each sf in tl do
  523. if w := sfto_preducef(sf,gb) then
  524. rtl := lto_insert(w,rtl);
  525. >> else
  526. rtl := tl;
  527. if !*rlgssub then
  528. return for each sf in sfto_groebnerf rtl collect
  529. acfsf_0mk2('neq,sf);
  530. return for each sf in rtl collect
  531. acfsf_0mk2('neq,sf)
  532. end;
  533. procedure acfsf_gssimulateprod(prem,prodal);
  534. % Algebraically closed field standard form simulate rlprod switch.
  535. % [prem] is a quantifier free formula. [prodal] is an assoc list
  536. % containing to some equations its product representation.
  537. begin scalar w,res;
  538. if rl_tvalp prem then return prem;
  539. if cl_atfp prem and (w := lto_cassoc(prem,prodal)) then
  540. return w;
  541. res := for each f in rl_argn prem collect
  542. if cl_atfp f and (w := lto_cassoc(f,prodal)) then w else f;
  543. return rl_mkn(rl_op prem,res)
  544. end;
  545. endmodule; % [acfsfgs]
  546. end; % of file