ofsfqe.red 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856
  1. % ----------------------------------------------------------------------
  2. % $Id: ofsfqe.red,v 1.23 1999/03/23 07:41:28 dolzmann Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 1995-1999 Andreas Dolzmann and Thomas Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: ofsfqe.red,v $
  7. % Revision 1.23 1999/03/23 07:41:28 dolzmann
  8. % Changed copyright information.
  9. % Changed comments for exc.
  10. %
  11. % Revision 1.22 1999/03/21 13:37:38 dolzmann
  12. % Changed in procedure ofsf_thregen '(false) into {'false}.
  13. % Fixed a bug in ofsf_thregen: ofsf_thregen returned an atomic formula
  14. % instead of a list of atomic formulas for an disjunctive f.
  15. % Corrected comments.
  16. %
  17. % Revision 1.21 1999/03/18 14:08:21 sturm
  18. % Added new service rl_specelim!* in cl_qe for covering the "super
  19. % quadratic special case' for ofsf. This method is toggled by switch
  20. % rlsqsc, which is off by default. Context dvfsf uses cl_specelim which
  21. % is constantly "false." Context acfsf does not use cl_qe at all.
  22. %
  23. % Revision 1.20 1999/01/17 16:10:35 dolzmann
  24. % Added and corrected comments.
  25. %
  26. % Revision 1.19 1998/04/09 11:00:04 sturm
  27. % Added switch rlqeqsc for quadratic special case. This now OFF by default!
  28. %
  29. % Revision 1.18 1997/10/02 09:14:13 sturm
  30. % Fixed a bug in answer computation with shift.
  31. %
  32. % Revision 1.17 1997/08/14 10:10:31 sturm
  33. % Renamed rldecdeg to rldecdeg1.
  34. % Added service rldecdeg.
  35. %
  36. % Revision 1.16 1997/06/27 13:04:51 sturm
  37. % Fixed a bug in ofsf_decdeg1.
  38. %
  39. % Revision 1.15 1997/04/15 11:31:44 dolzmann
  40. % New procedure ofsf_decdeg offers a symbolic mode interface for
  41. % decrementing the degree of variables in formulas.
  42. % Modified procedure ofsf_transform accordingly.
  43. % ofsf_subsimpl now outputs an exclamation mark if it enlarges the
  44. % theory.
  45. %
  46. % Revision 1.14 1997/04/08 14:31:12 sturm
  47. % Sort the answer substitution list wrt. ordp of the right hand side kernels.
  48. %
  49. % Revision 1.13 1996/10/23 11:24:16 dolzmann
  50. % Added and corrected comments.
  51. % Moved procedure ofsf_mkstrict into module ofsf.
  52. %
  53. % Revision 1.12 1996/10/15 15:47:21 dolzmann
  54. % Fixed a bug in ofsf_qefsolset.
  55. %
  56. % Revision 1.11 1996/10/08 13:54:35 dolzmann
  57. % Renamed "degree parity decomposition" to "parity decomposition".
  58. % Adapted names of procedures and switches accordingly.
  59. %
  60. % Revision 1.10 1996/10/07 12:03:30 sturm
  61. % Added fluids for CVS and copyright information.
  62. %
  63. % Revision 1.9 1996/09/30 16:53:54 sturm
  64. % Fixed a bug in ofsf_gelimset.
  65. % Cleaned up the use of several (conditional) negate-relation procedures.
  66. %
  67. % Revision 1.8 1996/09/05 11:15:56 dolzmann
  68. % Added comments.
  69. % Minor changes in ofsf_mksol21q and ofsf_elimsetscq. New handling of
  70. % root expressions with c=1.
  71. % Renamed procedure ofsf_translat1lin to ofsf_translatlin.
  72. % Renamed procedure ofsf_translat1qua to ofsf_translatqua.
  73. % Completely rewritten Gauss elimination code: removed procedures
  74. % ofsf_trygauss, ofsf_findeqsol, and ofsf_bettergaussp. Added
  75. % implementation for black boxes rl_qefsolset, rl_bettergaussp!*,
  76. % rl_bestgaussp, and rl_esetunion.
  77. % Introduced new switch !*rlqegenct and related code.
  78. %
  79. % Revision 1.7 1996/07/07 14:43:06 sturm
  80. % Removed use of fluid zehn!*.
  81. % Call cl_nnfnot instead of cl_nnf1.
  82. % Fixed a bug in ofsf_gelimset.
  83. %
  84. % Revision 1.6 1996/06/07 08:49:54 sturm
  85. % Fixed bugs in ofsf_translat, ofsf_gelimset, and ofsf_decdegat.
  86. %
  87. % Revision 1.5 1996/05/13 13:45:24 dolzmann
  88. % Improved ordering between the several kinds of Gauss elimination.
  89. %
  90. % Revision 1.4 1996/05/12 14:54:27 dolzmann
  91. % Check for occurrence of variable in substitution.
  92. % Modified ofsf_transform: Optimized treatment of atomic formulas x^n*r R 0.
  93. %
  94. % Revision 1.3 1996/05/12 08:27:33 sturm
  95. % Added code for generic branch computation.
  96. % Changes in ofsf_trygauss: Introduced an ordering between the several
  97. % kinds of Gauss elimination.
  98. % Added code for service ofsf_thsimpl.
  99. %
  100. % Revision 1.2 1996/04/18 14:30:47 sturm
  101. % Improved root substitution in procedure ofsf_qesubrord1.
  102. % Fixed a bug in ofsf_getsubrcoeffs.
  103. %
  104. % Revision 1.1 1996/03/22 12:14:14 sturm
  105. % Moved and split.
  106. %
  107. % ----------------------------------------------------------------------
  108. lisp <<
  109. fluid '(ofsf_qe_rcsid!* ofsf_qe_copyright!*);
  110. ofsf_qe_rcsid!* := "$Id: ofsfqe.red,v 1.23 1999/03/23 07:41:28 dolzmann Exp $";
  111. ofsf_qe_copyright!* := "Copyright (c) 1995-1999 by A. Dolzmann and T. Sturm"
  112. >>;
  113. module ofsfqe;
  114. % Ordered field standard form quantifier elimination. Submodule of [ofsf].
  115. %DS
  116. % <variable> ::= <kernel>
  117. procedure ofsf_varsel(f,vl,theo);
  118. % Ordered field standard form variable selection. [vl] is a list
  119. % of variables; [f] is a quantifier-free formula; [theo] is the
  120. % current theory. Returns a variable.
  121. begin scalar v,a,scvl,atl,ifacl,terml;
  122. atl := cl_atl1 f;
  123. scvl := vl;
  124. while scvl and not v do <<
  125. a := car scvl;
  126. scvl := cdr scvl;
  127. if ofsf_linp(atl,a,delq(a,vl)) then v := a
  128. >>;
  129. if v then return v;
  130. scvl := vl;
  131. while scvl and not v do <<
  132. a := car scvl;
  133. scvl := cdr scvl;
  134. if ofsf_qscp(atl,a) then v := a
  135. >>;
  136. if v then return v;
  137. terml := for each x in atl collect ofsf_arg2l x;
  138. scvl := vl;
  139. while scvl and not v do <<
  140. a := car scvl;
  141. scvl := cdr scvl;
  142. if ofsf_pseudp(terml,a,1) then v := a
  143. >>;
  144. if v then return v;
  145. scvl := vl;
  146. while scvl and not v do <<
  147. a := car scvl;
  148. scvl := cdr scvl;
  149. if ofsf_pseudp(terml,a,2) then v := a
  150. >>;
  151. if v then return v;
  152. if !*rlverbose then ioto_prin2 "(SVF";
  153. ifacl := for each x in atl join
  154. for each p in cdr fctrf ofsf_arg2l x collect car x;
  155. if !*rlverbose then ioto_prin2 ")";
  156. scvl := vl;
  157. while scvl and not v do <<
  158. a := car scvl;
  159. scvl := cdr scvl;
  160. if ofsf_pseudp(ifacl,a,1) then v := a
  161. >>;
  162. if v then return v;
  163. scvl := vl;
  164. while scvl and not v do <<
  165. a := car scvl;
  166. scvl := cdr scvl;
  167. if ofsf_pseudp(ifacl,a,2) then v := a
  168. >>;
  169. if v then return v;
  170. return car vl
  171. end;
  172. procedure ofsf_linp(atl,v,vl);
  173. % Ordered field standard form linear formula predicate. [atl] is a
  174. % list of atomic formulas; [v] is a variable; [vl] is a list of
  175. % variables. Returns [T] if every formula containing the atomic
  176. % formulas from [atl] is linear in [v] wrt. to [vl], i.e. the total
  177. % degree of [v] is 1 and no coefficient from [v] contains variables
  178. % from [vl].
  179. begin scalar linp,w,u,g;
  180. linp := T;
  181. w := setkorder {v};
  182. while atl and linp do <<
  183. u := reorder ofsf_arg2l car atl;
  184. atl := cdr atl;
  185. g := degr(u,v);
  186. if g > 1 or (g = 1 and intersection(kernels lc u,vl)) then
  187. linp := nil
  188. >>;
  189. setkorder w;
  190. return linp
  191. end;
  192. procedure ofsf_qscp(atl,v);
  193. % Ordered field standard form quadratic special case predicate.
  194. % [atl] is a list of atomic formulas; [v] is a variable. Returns
  195. % [T] if the quadratic special case is applicable to each formula
  196. % containing the atomic formulas from [atl].
  197. begin scalar a,hit,d;
  198. if not !*rlqeqsc then
  199. return nil;
  200. while atl do <<
  201. a := car atl;
  202. atl := cdr atl;
  203. d := degreef(ofsf_arg2l a,v);
  204. if d>2 then
  205. atl := hit := nil
  206. else if d=2 and ofsf_op a memq '(greaterp lessp geq leq neq) then
  207. if hit then
  208. atl := hit := nil
  209. else
  210. hit := T
  211. >>;
  212. return hit
  213. end;
  214. procedure ofsf_pseudp(ifacl,v,n);
  215. % Ordered field standard form pseudo high degree predicate.
  216. % [ifacl] is a list of SF's; [v] is a variable; [n] is a
  217. % non-negative integer. Returns [T] if the degree of each SF in
  218. % [ifacl] wrt. [v] is less than or equal to [n].
  219. begin scalar ok;
  220. ok := T;
  221. while ifacl and ok do
  222. if degreef(car ifacl,v) > n then
  223. ok := nil
  224. else
  225. ifacl := cdr ifacl;
  226. return ok
  227. end;
  228. %DS root expression
  229. % A list $(a,b,c,d)$ of SF's encoding the expression $(a+b\sqrt{c})/d$
  230. % The denominator of a root expression $r=(a,b,c,d)$ is $d$ and the
  231. % disciminante of $r$ is $c$. A root expression $r$ is called valid
  232. % iff the demominator of $r$ is not equal to zero and the
  233. % discriminante of $r$ is greater then 0.
  234. procedure ofsf_qesubcr1(bvl,theo,f,v,co,u);
  235. % Ordered field standard form quantifier elimination substitute
  236. % conditionally 1 root. [bvl] is a list of variables; [theo] is the
  237. % current theory; [f] is a quantifier-free formula; [v] is a
  238. % variable; [u] is a root expression; [co] is a quantifier-free
  239. % formula which implies that [u] is valid. Returns a pair $(\Theta'
  240. % . \phi)$ where $\Theta'$ is a theory and $\phi$ is a
  241. % quantifier-free formula. $\phi$ is equivalent to $[co] \land
  242. % [f]([v]/[u])$ under the theory $[th] \cup \Theta'$.
  243. begin scalar w;
  244. w := ofsf_subsimpl(bvl,co,theo);
  245. if cdr w eq 'false then
  246. return car w . 'false;
  247. return car w . rl_mkn('and,{cdr w,ofsf_qesubr(f,v,u)})
  248. end;
  249. procedure ofsf_qesubcr2(bvl,theo,f,v,co,u1,u2);
  250. % Ordered field standard form quantifier elimination substitute
  251. % conditionally 1 root. [bvl] is a list of variables; [theo] is the
  252. % current theory; [f] is a quantifier-free formula; [v] is a
  253. % variable; [u1], [u2] are root expression; [co] is a
  254. % quantifier-free formula which implies that both [u1] and [u2] are
  255. % valid. Returns a pair $(\Theta' . \phi)$ where $\Theta'$ is a
  256. % theory and $\phi$ is a quantifier-free formula. $\phi$ is
  257. % equivalent to $[co] \land ([f]([v]/[u1]) \lor [f]([v]/[u2]))$
  258. % under the theory $[th] \cup \Theta'$.
  259. begin scalar w;
  260. w := ofsf_subsimpl(bvl,co,theo);
  261. if cdr w eq 'false then
  262. return car w . 'false;
  263. return car w . rl_mkn('and,{cdr w,rl_mkn('or,{
  264. ofsf_qesubr(f,v,u1),ofsf_qesubr(f,v,u2)})})
  265. end;
  266. procedure ofsf_qesubr(f,v,u);
  267. % Ordered field standard form quantifier elimination substitute
  268. % root. [f] is a quantifier-free formula; [v] is a variable; [u] is
  269. % a root expression. Returns a quantifier-free formula equivalent
  270. % to $[f]([v]/[u])$ provided that [u] is valid..
  271. if caddr u = 1 then
  272. cl_apply2ats1(f,'ofsf_qesubqat,{v,
  273. quotsq(!*f2q addf(car u,cadr u),!*f2q cadddr u)})
  274. else
  275. cl_apply2ats1(f,'ofsf_qesubrat,{v,u});
  276. procedure ofsf_qesubrat(atf,v,u);
  277. % Ordered field standard form quantifier elimination substitute
  278. % root into atomic formula. [atf] is an atomic formula; [v] is a
  279. % variable; [u] is a root expression. Returns a quantifier-free
  280. % formula equivalent to $[f]([v]/[u])$ provided that that [u] is
  281. % valid.
  282. if not (v memq ofsf_varlat atf) then
  283. atf
  284. else
  285. ofsf_qesubrat1(ofsf_op atf,ofsf_arg2l atf,v,u);
  286. procedure ofsf_qesubrat1(r,f,x,rform);
  287. % Ordered field standard form quantifier elimination substitute
  288. % root into atomic formula subroutine. [r] is a relation; [f] is an
  289. % SF; [x] is a variable; [r] is a root expression. Returns a
  290. % quantifier-free formula equivalent to $[r]([f],0)([x]/[rform])$
  291. % that does not contain any root provided [rform] is valid..
  292. begin scalar w,dd;
  293. w := ofsf_getsubrcoeffs(f,x,rform);
  294. if r eq 'equal or r eq 'neq then
  295. return ofsf_qesubreq(r,car w,cadr w,caddr w);
  296. dd := car sfto_pdecf cadddr w;
  297. return ofsf_qesubrord(r,car w,cadr w,caddr w,dd)
  298. end;
  299. procedure ofsf_qesubreq(r,aa,bb,c);
  300. % Ordered field standard form quantifier elimination substitute
  301. % root with equality relation. [r] is one of ['equal], ['neq]; [aa],
  302. % [bb], and [c] are SF's. Returns a quantifier-free formula
  303. % equivalent to $[r](([aa]+[bb]\sqrt{[c]})/d,0)$ for any nonzero
  304. % $d$ provided that $c \geq 0$.
  305. (if r eq 'equal then w else cl_nnfnot w)
  306. where w=ofsf_qesubreq1(aa,bb,c);
  307. procedure ofsf_qesubreq1(aa,bb,c);
  308. % Ordered field standard form quantifier elimination substitute
  309. % root with equation. [aa], [bb], and [c] are SF's. Returns a
  310. % quantifier-free formula equivalent to $([aa]+[bb]\sqrt{[c]})/d=0$
  311. % for any nonzero $d$ provided that $c \geq 0$.
  312. if null bb then
  313. ofsf_0mk2('equal,aa)
  314. else
  315. rl_mkn('and,{ofsf_0mk2('leq,multf(aa,bb)),
  316. ofsf_0mk2('equal,addf(exptf(aa,2),negf multf(exptf(bb,2),c)))});
  317. procedure ofsf_qesubrord(r,aa,bb,c,dd);
  318. % Ordered field standard form quantifier elimination substitute
  319. % root with ordering relation. [r] is any ordering relation;
  320. % [delta] is $0$ or $1$; [aa], [bb], [c], and [dd] are SF's.
  321. % Returns a quantifier-free formula equivalent to
  322. % $[r](([aa]+[bb]\sqrt{[c]})/d^[delta],0)$ provided that $d \neq 0$
  323. % and $c \geq 0$.
  324. if r eq 'leq or r eq 'lessp then
  325. ofsf_qesubrord1(r,aa,bb,c,dd)
  326. else % [r eq 'geq or r eq 'greaterp]
  327. cl_nnfnot ofsf_qesubrord1(ofsf_lnegrel r,aa,bb,c,dd);
  328. procedure ofsf_qesubrord1(r,aa,bb,c,dd);
  329. % Ordered field standard form quantifier elimination substitute
  330. % root with ordering relation subroutine. [r] is one of [leq],
  331. % [lessp]; [delta] is $0$ or $1$; [aa], [bb], [c], and [d] are
  332. % SF's. Returns a quantifier-free formula equivalent to
  333. % $[r](([aa]+[bb]\sqrt{[c]})/d^[delta],0)$ provided that $d \neq 0$
  334. % and $c \geq 0$.
  335. begin scalar ad,a2b2c,w;
  336. ad := multf(aa,dd);
  337. if null bb then
  338. return ofsf_0mk2(r,ad);
  339. a2b2c := addf(exptf(aa,2),negf multf(exptf(bb,2),c));
  340. w := if r eq 'leq then
  341. ofsf_0mk2('leq,a2b2c)
  342. else
  343. rl_mkn('or,{ofsf_0mk2('lessp,ad),ofsf_0mk2('lessp,a2b2c)});
  344. return rl_mkn('or,{
  345. rl_mkn('and,{ofsf_0mk2(r,ad),ofsf_0mk2(ofsf_anegrel r,a2b2c)}),
  346. rl_mkn('and,{ofsf_0mk2('leq,multf(bb,dd)),w})})
  347. end;
  348. procedure ofsf_getsubrcoeffs(f,x,rform);
  349. % Ordered field standard form get coefficients for root
  350. % substitution. [f] is an SF; [x] is a variable; [rform] is a root
  351. % expression $(a,b,c,d)$. Returns a list $(a',b',c,d')$ of SF's
  352. % such that $a'+b'\sqrt{c}/d'$ is $[f]([x]/[rform])$ reduced to
  353. % lowest terms. We assume $d \neq 0$ and $c \geq 0$.
  354. begin scalar w,rpol,aa,bb,dd,a,b,c,d;
  355. a := prepf car rform;
  356. b := prepf cadr rform;
  357. c := caddr rform;
  358. d := prepf cadddr rform;
  359. rpol := {'quotient,{'plus,a,{'times,b,'ofsf_sqrt}},d};
  360. w := subf(f,{x . rpol});
  361. dd := denr w;
  362. w := sfto_reorder(numr w,'ofsf_sqrt);
  363. while not domainp w and mvar w eq 'ofsf_sqrt do <<
  364. if evenp ldeg w then
  365. aa := addf(aa,multf(reorder lc w,exptf(c,ldeg w / 2)))
  366. else
  367. bb := addf(bb,multf(reorder lc w,exptf(c,ldeg w / 2)));
  368. w := red w
  369. >>;
  370. aa := addf(aa,reorder w);
  371. return {aa,bb,c,dd}
  372. end;
  373. procedure ofsf_qesubcq(bvl,theo,f,v,co,u);
  374. % Ordered field standard form quantifier elimination substitute
  375. % conditionally 1 quotient. [bvl] is a list of variables, [theo] is
  376. % the current theory, [f] is a quantifier-free formula; [v] is a
  377. % variable; [co] is a formula which implies that the denominator of
  378. % [u] is nonzero; [u] is an SQ. Returns a pair $(\Theta' . \phi)$
  379. % where $\Theta'$ is a theory and $\phi$ is a quantifier-free
  380. % formula. $\phi$ is equivalent to $[co] \land [f]([v]/[u])$ under
  381. % the theory $[th] \cup \Theta'$.
  382. begin scalar w;
  383. w := ofsf_subsimpl(bvl,co,theo);
  384. if cdr w eq 'false then
  385. return car w . 'false;
  386. return car w . rl_mkn('and,{cdr w,ofsf_qesubq(f,v,u)})
  387. end;
  388. procedure ofsf_qesubq(f,v,u);
  389. % Ordered field standard form quantifier elimination substitute
  390. % quotient. [f] is a quantifier-free formula; [v] is a variable;
  391. % [u] is an SQ. Returns a quantifier-free formula equivalent to
  392. % $[f]([v]/[u])$ provided that the denominator of [u] is nonzero.
  393. cl_apply2ats1(f,'ofsf_qesubqat,{v,u});
  394. procedure ofsf_qesubqat(atf,v,u);
  395. % Ordered field standard form quantifier elimination substitute
  396. % quotient into atomic formula. [atf] is an atomic formula; [v] is
  397. % a variable; [u] is an SQ. Returns a quantifier-free formula
  398. % equivalent to $[atf]([v]/[u])$ provided that the denominator of
  399. % [u] is nonzero.
  400. begin scalar w,op;
  401. if not (v memq ofsf_varlat atf) then return atf;
  402. w := subf(ofsf_arg2l atf,{v . prepsq u});
  403. op := ofsf_op atf;
  404. w := if op eq 'equal or op eq 'neq then numr w else multf(numr w,denr w);
  405. return ofsf_0mk2(op,w)
  406. end;
  407. procedure ofsf_qesubi(bvl,theo,f,v,inf);
  408. % Ordered field standard form quantifier elimination substitute
  409. % infinite element. [bvl] is a list of variables, [theo] is the
  410. % current theory; [f] is a quantifier-free formula; [v] is a
  411. % variable; [inf] is one of ['minf], ['pinf] which stand for
  412. % $-\infty$ and $\infty$ resp. Returns a pair $(\Theta' . \phi)$
  413. % where $\Theta'$ is a theory and $\phi$ is a quantifier-free
  414. % formula. $\phi$ is equivalent to $[f]([v]/[inf])$ under the
  415. % theory $[th] \cup \Theta'$. $\Theta' is currently always [nil].
  416. nil . cl_apply2ats1(f,'ofsf_qesubiat,{v,inf});
  417. procedure ofsf_qesubiat(atf,v,inf);
  418. % Ordered field standard form quantifier elimination substitute
  419. % infinite element into atomic formula. [atf] is an atomic formula;
  420. % [v] is a variable; [inf] is one of ['minf], ['pinf] which stand for
  421. % $-\infty$ and $\infty$ resp. Returns a quantifier-free formula
  422. % equivalent to $[atf]([v]/[inf])$.
  423. begin scalar op,lhs;
  424. if not (v memq ofsf_varlat atf) then return atf;
  425. op := ofsf_op atf;
  426. lhs := ofsf_arg2l atf;
  427. if op eq 'equal or op eq 'neq then
  428. return ofsf_qesubtranseq(op,lhs,v);
  429. % [op] is an ordering relation.
  430. return ofsf_qesubiord(op,lhs,v,inf)
  431. end;
  432. procedure ofsf_qesubtranseq(op,lhs,v);
  433. % Ordered field standard form quantifier elimination substitute
  434. % transcendental element with equality relation. [op] is one of
  435. % ['equal], ['neq]; [lhs] is an SF; [v] is a variable. Returns a
  436. % quantifier-free formula equivalent to $[r]([lhs],0)([v]/\alpha)$
  437. % for any transcendental $\alpha$.
  438. if op eq 'equal then
  439. ofsf_qesubtransequal(lhs,v)
  440. else % [op eq 'neq]
  441. cl_nnfnot ofsf_qesubtransequal(lhs,v);
  442. procedure ofsf_qesubtransequal(lhs,v);
  443. % Ordered field standard form quantifier elimination substitute
  444. % transcendental element into equation. [lhs] is an SF; [v] is a
  445. % variable. Returns a quantifier-free formula equivalent to
  446. % $[lhs]([v]/\alpha)=0$ for any transcendental $\alpha$.
  447. ofsf_qesubtransequal1(sfto_reorder(lhs,v),v);
  448. procedure ofsf_qesubtransequal1(lhs,v);
  449. % Ordered field standard form quantifier elimination substitute
  450. % transcendental element into equation. [lhs] is an SF reordered
  451. % wrt. [v]; [v] is a variable. Returns a quantifier-free formula
  452. % equivalent to $[lhs]([v]/\alpha)=0$ for any transcendental
  453. % $\alpha$.
  454. begin scalar cl;
  455. while not domainp lhs and mvar lhs eq v do <<
  456. cl := ofsf_0mk2('equal,reorder lc lhs) . cl;
  457. lhs := red lhs
  458. >>;
  459. cl := ofsf_0mk2('equal,reorder lhs) . cl;
  460. return rl_smkn('and,cl)
  461. end;
  462. procedure ofsf_qesubiord(op,f,v,inf);
  463. % Ordered field standard form quantifier elimination substitute
  464. % infinite element with ordering relation. [op] is an ordering
  465. % relation. [f] is an SF; [v] is a variable; [inf] is one of
  466. % ['minf], ['pinf] which stand for $-\infty$ and $\infty$ resp.
  467. % Returns a quantifier-free formula equivalent to
  468. % $[op]([lhs]([v]/[inf]),0)$.
  469. ofsf_qesubiord1(op,sfto_reorder(f,v),v,inf);
  470. procedure ofsf_qesubiord1(op,f,v,inf);
  471. % Ordered field standard form quantifier elimination substitute
  472. % infinite element with ordering relation subroutine. [op] is an
  473. % ordering relation. [f] is an SF, which is reordered wrt. [v]; [v]
  474. % is a variable; [inf] is one of ['minf], ['pinf] which stand for
  475. % $-\infty$ and $\infty$ resp. Returns a quantifier-free formula
  476. % equivalent to $[op]([lhs]([v]/[inf]),0)$.
  477. begin scalar an;
  478. if domainp f or mvar f neq v then
  479. return ofsf_0mk2(op,reorder f);
  480. an := if inf eq 'minf and not evenp ldeg f then
  481. negf reorder lc f
  482. else
  483. reorder lc f;
  484. % The use of [an] is correct in the equal case. % Generic QE!
  485. return rl_mkn('or,{ofsf_0mk2(ofsf_mkstrict op,an),rl_mkn(
  486. 'and,{ofsf_0mk2('equal,an),ofsf_qesubiord1(op,red f,v,inf)})})
  487. end;
  488. procedure ofsf_qesubcrpe1(bvl,theo,f,v,co,r);
  489. % Ordered field standard form quantifier elimination substitute
  490. % conditionally 1 root plus epsilon. [bvl] is a list of variables;
  491. % [theo] is the current theory; [f] is a quantifier-free formula;
  492. % [v] is a variable; [r] is a root expression; [co] is a formula
  493. % which implies that [r] is valid. Returns a pair $(\Theta' .
  494. % \phi)$ where $\Theta'$ is a theory and $\phi$ is a
  495. % quantifier-free formula. $\phi$ is equivalent to $[co] \land
  496. % [f]([v]/[r1]+\epsilon)$ under the theory $[th] \cup \Theta'$.
  497. begin scalar w;
  498. w := ofsf_subsimpl(bvl,co,theo);
  499. if cdr w eq 'false then
  500. return car w . 'false;
  501. return car w . rl_mkn('and,{cdr w,ofsf_qesubrpe(f,v,r)})
  502. end;
  503. procedure ofsf_qesubcrme1(bvl,theo,f,v,co,r);
  504. % Ordered field standard form quantifier elimination substitute
  505. % conditionally 1 root minus epsilon. [bvl] is a list of variables;
  506. % [theo] is the current theory; [f] is a quantifier-free formula;
  507. % [v] is a variable; [r] is a root expression; [co] is a formula
  508. % which implies that [r] is valid. Returns a pair $(\Theta' .
  509. % \phi)$ where $\Theta'$ is a theory and $\phi$ is a
  510. % quantifier-free formula. $\phi$ is equivalent to $[co] \land
  511. % [f]([v]/[r1]-\epsilon)$ under the theory $[th] \cup \Theta'$.
  512. begin scalar w;
  513. w := ofsf_subsimpl(bvl,co,theo);
  514. if cdr w eq 'false then
  515. return car w . 'false;
  516. return car w . rl_mkn('and,{cdr w,ofsf_qesubrme(f,v,r)})
  517. end;
  518. procedure ofsf_qesubcrpe2(bvl,theo,f,v,co,r1,r2);
  519. % Ordered field standard form quantifier elimination substitute
  520. % conditionally 2 roots plus epsilon. [bvl] is a list of variables;
  521. % [theo] is the current theory; [f] is a quantifier-free formula;
  522. % [v] is a variable; [r1] and [r2] are root expression; [co] is a
  523. % formula which implies that both [r1] and [r2] are valid. Returns
  524. % a pair $(\Theta' . \phi)$ where $\Theta'$ is a theory and $\phi$
  525. % is a quantifier-free formula. $\phi$ is equivalent to $[co] \land
  526. % ([f]([v]/[r1]+\epsilon) \lor [f]([v]/[r2]+\epsilon))$ under the
  527. % theory $[th] \cup \Theta'$.
  528. begin scalar w;
  529. w := ofsf_subsimpl(bvl,co,theo);
  530. if cdr w eq 'false then
  531. return car w . 'false;
  532. return car w . rl_mkn('and,{cdr w,rl_mkn('or,{
  533. ofsf_qesubrpe(f,v,r1),ofsf_qesubrpe(f,v,r2)})})
  534. end;
  535. procedure ofsf_qesubcrme2(bvl,theo,f,v,co,r1,r2);
  536. % Ordered field standard form quantifier elimination substitute
  537. % conditionally 2 roots minus epsilon. [bvl] is a list of variables;
  538. % [theo] is the current theory; [f] is a quantifier-free formula;
  539. % [v] is a variable; [r1] and [r2] are root expression; [co] is a
  540. % formula which implies that both [r1] and [r2] are valid. Returns
  541. % a pair $(\Theta' . \phi)$ where $\Theta'$ is a theory and $\phi$
  542. % is a quantifier-free formula. $\phi$ is equivalent to $[co] \land
  543. % ([f]([v]/[r1]-\epsilon) \lor [f]([v]/[r2]-\epsilon))$ under the
  544. % theory $[th] \cup \Theta'$.
  545. begin scalar w;
  546. w := ofsf_subsimpl(bvl,co,theo);
  547. if cdr w eq 'false then
  548. return car w . 'false;
  549. return car w . rl_mkn('and,{cdr w,rl_mkn('or,{
  550. ofsf_qesubrme(f,v,r1),ofsf_qesubrme(f,v,r2)})})
  551. end;
  552. procedure ofsf_qesubrpe(f,v,r);
  553. % Ordered field standard form quantifier elimination substitute
  554. % root plus epsilon. [f] is a quantifier-free formula; [v] is a
  555. % variable; [r] is a root expression- Returns a formula equivalent
  556. % to $[f]([v]/[r]+\epsilon)$ provided that [r] is valid.
  557. cl_apply2ats1(f,'ofsf_qesubpmeat,{v,r,'ofsf_qesubr,T});
  558. procedure ofsf_qesubrme(f,v,r);
  559. % Ordered field standard form quantifier elimination substitute
  560. % root minus epsilon. [f] is a quantifier-free formula; [v] is a
  561. % variable; [r] is a root expression- Returns a formula equivalent
  562. % to $[f]([v]/[r]-\epsilon)$ provided that [r] is valid.
  563. cl_apply2ats1(f,'ofsf_qesubpmeat,{v,r,'ofsf_qesubr,nil});
  564. procedure ofsf_qesubcqpe(bvl,theo,f,v,co,q);
  565. % Ordered field standard form quantifier elimination substitute
  566. % conditionally 1 quotient plus epsilon. [bvl] is a list of
  567. % variables, [theo] is the current theory, [f] is a quantifier-free
  568. % formula; [v] is a variable; [co] is a formula which implies that
  569. % the denominator of [q] is nonzero; [q] is an SQ. Returns a pair
  570. % $(\Theta' . \phi)$ where $\Theta'$ is a theory and $\phi$ is a
  571. % quantifier-free formula. $\phi$ is equivalent to $[co] \land
  572. % [f]([v]/[q]+\epsilon)$ under the theory $[th] \cup \Theta'$.
  573. begin scalar w;
  574. w := ofsf_subsimpl(bvl,co,theo);
  575. if cdr w eq 'false then
  576. return car w . 'false;
  577. return car w . rl_mkn('and,{cdr w,ofsf_qesubqpe(f,v,q)})
  578. end;
  579. procedure ofsf_qesubcqme(bvl,theo,f,v,co,q);
  580. % Ordered field standard form quantifier elimination substitute
  581. % conditionally 1 quotient minus epsilon. [bvl] is a list of
  582. % variables, [theo] is the current theory, [f] is a quantifier-free
  583. % formula; [v] is a variable; [co] is a formula which implies that
  584. % the denominator of [q] is nonzero; [q] is an SQ. Returns a pair
  585. % $(\Theta' . \phi)$ where $\Theta'$ is a theory and $\phi$ is a
  586. % quantifier-free formula. $\phi$ is equivalent to $[co] \land
  587. % [f]([v]/[q]-\epsilon)$ under the theory $[th] \cup \Theta'$.
  588. begin scalar w;
  589. w := ofsf_subsimpl(bvl,co,theo);
  590. if cdr w eq 'false then
  591. return car w . 'false;
  592. return car w . rl_mkn('and,{cdr w,ofsf_qesubqme(f,v,q)})
  593. end;
  594. procedure ofsf_qesubqpe(f,v,q);
  595. % Ordered field standard form quantifier elimination substitute
  596. % quotient plus epsilon. [f] is a quantifier-free formula; [v] is a
  597. % variable; [q] is an SQ. Returns a quantifier-free formula
  598. % equivalent to $[f]([v]/[q]+\epsilon)$ provided that the
  599. % denominator of [q] is nonzero.
  600. cl_apply2ats1(f,'ofsf_qesubpmeat,{v,q,'ofsf_qesubq,T});
  601. procedure ofsf_qesubqme(f,v,q);
  602. % Ordered field standard form quantifier elimination substitute
  603. % quotient minus epsilon. [f] is a quantifier-free formula; [v] is a
  604. % variable; [q] is an SQ. Returns a quantifier-free formula
  605. % equivalent to $[f]([v]/[q]-\epsilon)$ provided that the
  606. % denominator of [q] is nonzero.
  607. cl_apply2ats1(f,'ofsf_qesubpmeat,{v,q,'ofsf_qesubq,nil});
  608. procedure ofsf_qesubpmeat(atf,v,u,finsub,ple);
  609. % Ordered field standard form quantifier elimination substitute
  610. % plus/minus epsilon into atomic formula. [atf] is an atomic
  611. % formula; [v] is a variable; [u] is any field element;
  612. % [finsub(atf,v,u)] is a procedure that can substitute [u] into a
  613. % formula; [ple] is Boolean, non-[nil] means $+\epsilon$. Returns a
  614. % quantifier-free formula equivalent to $[atf]([v]/[u]\pm\epsilon)$
  615. % provided that the denominator of [u] is nonzero.
  616. begin scalar op,lhs;
  617. if not (v memq ofsf_varlat atf) then return atf;
  618. op := ofsf_op atf;
  619. lhs := ofsf_arg2l atf;
  620. if op eq 'equal or op eq 'neq then
  621. return ofsf_qesubtranseq(op,lhs,v);
  622. % [op] is an ordering relation.
  623. return apply(finsub,{ofsf_qesubpmeord(op,lhs,v,ple),v,u})
  624. end;
  625. procedure ofsf_qesubpmeord(op,f,v,ple);
  626. % Ordered field standard form quantifier elimination substitute
  627. % plus/minus epsilon with ordering relation. [op] is an ordering
  628. % relation. [f] is an SF; [v] is a variable; [ple] is Boolean,
  629. % non-[nil] means $+\epsilon$. Returns a quantifier-free formula
  630. % $\phi$ such that $\phi(v/u)$ is equivalent to
  631. % $[op]([f]([v]/u\pm\epsilon),0)$ for any field element $u$ with
  632. % nonzero denominator.
  633. if degreef(f,v) eq 0 then
  634. ofsf_0mk2(op,f)
  635. else
  636. rl_mkn('or,{ofsf_0mk2(ofsf_mkstrict op,f),rl_mkn('and,{
  637. ofsf_0mk2('equal,f),ofsf_qesubpmeord(
  638. op,if ple then diff(f,v) else negf diff(f,v),v,ple)})});
  639. procedure ofsf_subsimpl(bvl,f,th);
  640. % Ordered field standard form substitution condition
  641. % simplification. [bvl] is a list of variables; [f] is a formula;
  642. % [th] is the current theory. Returns a pair $(\Theta'.\phi)$, such
  643. % that $phi$ is equivalent to [f] under the theory
  644. % $[th]\cup\Theta'$. All atomic formulas in $\Theta'$ contain only
  645. % terms [u] such that [ofsf_valassp(bvl,u)] holds.
  646. begin scalar nth;
  647. f := cl_simpl(f,th,-1);
  648. if not !*rlqegen then
  649. return nil . f;
  650. nth := for each atf in cl_atl1 f join
  651. if ofsf_op atf='equal and ofsf_valassp(bvl,ofsf_arg2l atf) then
  652. {ofsf_0mk2('neq,ofsf_arg2l atf)};
  653. if nth then <<
  654. ioto_prin2 "!";
  655. return nth . cl_simpl(f,append(nth,th),-1)
  656. >>;
  657. return nil . f
  658. end;
  659. procedure ofsf_valassp(bvl,sf);
  660. % Ordered field standard form valid assumption. [bvl] is a list of
  661. % variables; [sf] is a standard form. Returns [T] if an assumption
  662. % containing [sf] is valid. Depends on switch [!*rlqegenct].
  663. (!*rlqegenct or sfto_monfp sf) and null intersection(bvl,kernels sf);
  664. %DS ALP
  665. % A pair of ALIST's encoding the set of possible elimination terms.
  666. % Keys created by ofsf_translat1:
  667. % equal1: linear equations
  668. % equal21q: quadratic equations 1 quotient
  669. % equal22r: quadratic equations 2 roots
  670. % neq1: linear inequalities
  671. % neq21q: quadratic inequalities 1 quotient
  672. % neq22r: quadratic inequalities 2 roots
  673. % geq1: linear weak lower bounds
  674. % leq1: linear weak upper bounds
  675. % greaterp1: linear strong lower bounds
  676. % lessp1: linear strong upper bounds
  677. % wo1: linear weak orderings
  678. % wo21q: quadratic weak orderings 1 quotient
  679. % wo22r: quadratic weak orderings 2 roots
  680. % so1: linear strong orderings
  681. % so21q: quadratic strong orderings 1 quotient
  682. % so22r: quadratic strong orderings 2 roots
  683. smacro procedure ofsf_mkalp(tag,l);
  684. % Ordered field standard form make alist pair. [tag] is a key; [l]
  685. % is an entry. Returns an ALP.
  686. {tag . l} . {tag . 1};
  687. smacro procedure ofsf_ceterm1a(m,u);
  688. % Ordered field standard form conditional elimination term 1
  689. % condition atomic other parameter. [m] is a SF; [u] is an
  690. % elimination term.
  691. {ofsf_0mk2('neq,m),u};
  692. smacro procedure ofsf_ceterm2a(a,m,u);
  693. % Ordered field standard form conditional elimination term 2
  694. % conditions atomic other parameter. [a], [m] are SF's; [u] is an
  695. % elimination term.
  696. if a then
  697. {rl_mkn('and,{ofsf_0mk2('equal,a),ofsf_0mk2('neq,m)}),u}
  698. else
  699. {ofsf_0mk2('neq,m),u};
  700. smacro procedure ofsf_ceterm1l(a,l);
  701. % Ordered field standard form conditional elimination term 1
  702. % condition parameter list.
  703. ofsf_0mk2('neq,a) . l;
  704. smacro procedure ofsf_ceterm2l(a,d,l);
  705. % Ordered field standard form conditional elimination term 2
  706. % conditions parameter list. [a], [d] are SF's; [l] is a list of
  707. % elimination terms.
  708. rl_mkn('and,{ofsf_0mk2('neq,a),ofsf_0mk2('geq,d)}) . l;
  709. smacro procedure ofsf_mktag1(x);
  710. % Ordered field standard form make tag linear case. [x] is an
  711. % identifier. Returns the interned identifier [x]1.
  712. intern compress(nconc(explode x,'(!1)));
  713. smacro procedure ofsf_mktag2(x,y);
  714. % Ordered field standard form make tag quadratic case. [x], [y] are
  715. % identifiers. Returns the interned identifier [x]2[y].
  716. intern compress(nconc(explode x,'!2 . explode y));
  717. procedure ofsf_translat(atf,v,theo,pos,ans);
  718. % Ordered field standard form translate atomic formula. [atf] is an
  719. % atomic formula $\rho(t,0)$; [v] is a variable; [theo] is the
  720. % current theory; [pos], [ans] are Bool. Returns an ALP. If [pos]
  721. % is non-[nil] [atf] is consided as [not(atf)]. The switch [rlqesr]
  722. % is turned on if [ans] is non-[nil]. If [v] is not in $t$ the
  723. % result is $([nil] . [nil])$. Else $t$ is of the form $\prod_i
  724. % a_i[v]^2+b_i[v]+c_i$, and the result is $(((\rho' . (-b . a))) .
  725. % ((\rho' . 1)))$ where $\rho'=\rho$ for non-[nil] [pos] and the
  726. % negation of $\rho$ else.
  727. begin scalar svrlqesr,res;
  728. if ans then <<
  729. svrlqesr := !*rlqesr;
  730. on1 'rlqesr
  731. >>;
  732. if v memq ofsf_varlat atf then <<
  733. res := if pos then
  734. ofsf_translat1(atf,v,theo)
  735. else
  736. ofsf_translat1(ofsf_negateat atf,v,theo);
  737. if res = '(nil . nil) then
  738. res := {'anypoint . nil} . {'anypoint . 1}
  739. >> else
  740. res := nil . nil;
  741. if ans and null svrlqesr then
  742. off1 'rlqesr;
  743. return res
  744. end;
  745. procedure ofsf_translat1(atf,v,theo);
  746. % Ordered field standard form translate atomic formula subroutine.
  747. % [atf] is an atomic formula; [v] is a variable; [theo] is the
  748. % current theory. Returns an ALP or a pair of the key ['failed] and
  749. % an error message.
  750. begin scalar w,rel;
  751. w := ofsf_mktriplel(ofsf_arg2l atf,v);
  752. if car w eq 'failed then return w;
  753. rel := ofsf_op atf;
  754. if null car w then
  755. return ofsf_translat2(rel,cadr w,theo);
  756. return cl_alpunion for each x in cdr w join
  757. if rel memq '(geq leq lessp greaterp) then
  758. {ofsf_translat2(rel,x,theo),
  759. ofsf_translat2(ofsf_anegrel rel,x,theo)}
  760. else
  761. {ofsf_translat2(rel,x,theo)}
  762. end;
  763. procedure ofsf_translat2(rel,trip,theo);
  764. % Ordered field standard form translate atomic formula subroutine.
  765. % [rel] is a relation, [trip] is a triple; [theo] is the current
  766. % theory. Returns an ALP.
  767. if null car trip then
  768. ofsf_translatlin(rel,cadr trip,caddr trip,theo,nil)
  769. else
  770. ofsf_translatqua(rel,car trip,cadr trip,caddr trip,theo);
  771. procedure ofsf_translatlin(r,m,b,theo,xc);
  772. % Ordered field standard form translate atomic formula linear case.
  773. % [r] is a relation; [m], [b] are the 2nd and 3rd constituent of a
  774. % triple generated from a linear term; [theo] is the current
  775. % theory; [xc] is a SF encoding an extra condition. Returns an ALP.
  776. ofsf_mkalp(ofsf_tlltag(r,m,theo),{ofsf_ceterm2a(xc,m,ofsf_mksol1(m,b))});
  777. procedure ofsf_tlltag(r,m,theo);
  778. % Ordered field standard form translate atomic formula linear case
  779. % make tag. [r] is a relation; [m] is the 2nd constituent of a
  780. % triple generated from a linear term; [theo] is the current
  781. % theory. Returns a tag.
  782. if r eq 'equal or r eq 'neq then
  783. ofsf_mktag1 r
  784. else if ofsf_surep(ofsf_0mk2('geq,m),theo) then
  785. ofsf_mktag1 r
  786. else if ofsf_surep(ofsf_0mk2('leq,m),theo) then
  787. ofsf_mktag1 ofsf_anegrel r
  788. else if r eq 'lessp or r eq 'greaterp then
  789. 'so1
  790. else % [r memq '(leq geq)]
  791. 'wo1;
  792. procedure ofsf_translatqua(r,a,b,c,theo);
  793. % Ordered field standard form translate atomic formula subroutine
  794. % quadratic case. [r] is a relation; [a], [b], and [c] are the
  795. % constituent of a triple; [theo] is the current theory. Returns an
  796. % ALP.
  797. begin scalar w,tagbase,tag,eset;
  798. w := ofsf_mksol2(a,b,c);
  799. if w eq 'failed then
  800. return nil . nil;
  801. tagbase := if r memq '(lessp greaterp) then
  802. 'so
  803. else if r memq '(leq geq) then
  804. 'wo
  805. else % [if r memq '(equal neq) then]
  806. r;
  807. if car w eq 'onequot then <<
  808. tag := ofsf_mktag2(tagbase,'!1q);
  809. eset := {ofsf_ceterm1a(a,cdr w)}
  810. >> else if car w eq 'tworoot then <<
  811. if !*rlqesr then <<
  812. tag := ofsf_mktag2(tagbase,'!1r);
  813. eset := {ofsf_ceterm2l(a,cadr w,{caddr w}),
  814. ofsf_ceterm2l(a,cadr w,{cadddr w})}
  815. >> else <<
  816. tag := ofsf_mktag2(tagbase,'!2r);
  817. eset := {ofsf_ceterm2l(a,cadr w,{caddr w,cadddr w})}
  818. >>
  819. >>;
  820. if not null b then <<
  821. w := ofsf_translatlin(r,b,c,theo,a);
  822. return {tag . eset,caar w} . {tag . 1,cadr w}
  823. >>;
  824. return ofsf_mkalp(tag,eset)
  825. end;
  826. procedure ofsf_surep(f,theo);
  827. % Ordered field standard form sure predicat. [f] is a formula;
  828. % [theo] is a theory. Returns [T] if $f$ holds under the theory
  829. % [theo].
  830. cl_simpl(f,theo,-1) eq 'true;
  831. procedure ofsf_mktriplel(u,v);
  832. % Ordered field standard form make triple list. [v] is a variable,
  833. % [u] is a SF containing [v]. Returns a pair $k . l$, where $k$ is
  834. % one off ['failed], ['fac], [nil] and $l$ is a list. If $k$ is
  835. % [nil], then the degree of [u] in [v] is less than or equal to 2,
  836. % if [k] is ['fac] then the degree of all irreducible factors of
  837. % [u] in [v] is less than or equal to 2, and if $k$ is ['failed]
  838. % then at least one factor of [u] has an degree greater than 2 in
  839. % [v]. If $k$ is not ['failed] then $l$ is the list of all triples
  840. % of the factors of [u]. If $k$ is ['failed] then $l$ encodes a
  841. % warning-message. Notice that if $k$ is [nil] the list $l$
  842. % contains only one element.
  843. begin scalar w,g,fl,a,ul;
  844. w := setkorder {v};
  845. u := reorder u;
  846. if ldeg u <= 2 then <<
  847. setkorder w;
  848. return nil . {ofsf_reotrip ofsf_mktriple u}
  849. >>;
  850. % Try to factorize.
  851. if !*rlverbose then ioto_prin2{"."};
  852. fl := cdr fctrf u;
  853. while fl do <<
  854. a := car fl;
  855. fl := cdr fl;
  856. g := degr(car a,v);
  857. if g > 2 then <<
  858. ul := 'failed . {"degree of",v,"is",g,"in",prepf car a};
  859. fl := nil
  860. >> else if g > 0 then
  861. ul := car a . ul
  862. >>;
  863. setkorder w;
  864. if car ul = 'failed then return ul;
  865. return 'fac . for each x in ul collect ofsf_reotrip ofsf_mktriple x
  866. end;
  867. procedure ofsf_mktriple(x);
  868. % Ordered field standard form make triple. [x] is a SF of the form
  869. % $a[v]^2+b[v]+c$, not necessarily in the current kernel order.
  870. % Returns the triple $(a,b,c)$.
  871. begin scalar a,v;
  872. v := mvar x;
  873. if ldeg x eq 2 then <<
  874. a := lc x;
  875. x := red x
  876. >>;
  877. return if not domainp x and mvar x eq v then
  878. {a,lc x,red x}
  879. else
  880. {a,nil,x}
  881. end;
  882. procedure ofsf_reotrip(trip);
  883. % Orderd field standard form reorder triple. [trip] is a triple
  884. % $(a,b,c)$ of SF's. Returns the triple $(a',b',c')$ of SF's, where
  885. % $a'$, $b'$, and $c'$ are reorderd wrt. the current kernel order.
  886. {reorder car trip,reorder cadr trip,reorder caddr trip};
  887. procedure ofsf_mksol1(m,b);
  888. % Orderd field standard form make solution linear case. [m] and [b]
  889. % are standard forms. Returns $-[b]/m$ as SQ.
  890. quotsq(!*f2q negf b,!*f2q m);
  891. procedure ofsf_mksol2(a,b,c);
  892. % Orderd field standard form make solution quadratic case. [a],
  893. % [b], and [c] are SF's. Returns either ['failed] or a pair $(k .
  894. % f)$. $k$ is one of ['onequot], ['tworoot]. If $k$ is ['onequot]
  895. % then $[b]^2-4[a][c]=0$ and $f$ is the SQ $-[b]/2[a]$. If $k$ is
  896. % ['tworoot] then $f$ is a pair $(\delta . l)$ where $\delta$ is
  897. % the discriminante of $a x^2+b x+c$ and $l$ is a list of the two
  898. % root expressions coding $(-[b]\pm\sqrt{[b]^2-4[a][c]})/2[a]$.
  899. begin scalar disc,w,c;
  900. disc := addf(exptf(b,2),negf multf(4,multf(a,c)));
  901. if domainp disc and minusf disc then
  902. return 'failed;
  903. a := multf(2,a);
  904. b := negf b;
  905. if null disc then
  906. return 'onequot . quotsq(!*f2q b,!*f2q a);
  907. w := sfto_sqrtf disc;
  908. if w then
  909. return 'tworoot . nil . ofsf_mksol21q(b,w,a);
  910. return 'tworoot . disc . ofsf_mksol21r(b,disc,a)
  911. end;
  912. procedure ofsf_mksol21q(mb,discr,ta);
  913. % Orderd field standard form make solution quadratic case 1
  914. % quotient. [mb], [discr] and [ta] are SF's. Returns a list of the
  915. % two root expressions $([mb],\pm[discr],1,ta)$.
  916. {{mb,negf discr,1,ta},{mb,discr,1,ta}};
  917. procedure ofsf_mksol21r(mb,disc,ta);
  918. % Orderd field standard form make solution quadratic case 1 root.
  919. % [mb], [disc] and [ta] are SF's. Returns a list of the two root
  920. % expressions $([mb],\pm1,[disc],ta)$.
  921. {{mb,-1,disc,ta},{mb,1,disc,ta}};
  922. %DS elimination_set
  923. % A list $(...,(p . (l_1,...,l_n)),...)$ where the $p$ are procedures
  924. % and the $l_i$ are parameter lists $(l_{i1},...,l_{im})$ such that
  925. % there is $p(f,v,l_{i1},...,l_{im})$ called for substitution, where
  926. % $f$ is the considered formula, and $v$ the considered variable.
  927. procedure ofsf_elimset(v,alp);
  928. % Ordered field standard form elimination set. [v] is a variable;
  929. % [alp] is a pair of alists. Returns an elimination set.
  930. begin scalar atfal,w,lpart,qpart,npart;
  931. atfal := car alp;
  932. if null cdr atfal and caar atfal = 'anypoint then
  933. return '((ofsf_qesubcq . ((true (nil . nil)))));
  934. % Treat some special cases.
  935. w := ofsf_elimsetscq(atfal);
  936. if w then <<
  937. if !*rlverbose then ioto_prin2 "#q";
  938. return w
  939. >>;
  940. w := ofsf_elimsetscl(atfal);
  941. if w then <<
  942. if !*rlverbose then ioto_prin2 "#l";
  943. return w
  944. >>;
  945. w := ofsf_elimsetlin1s(atfal);
  946. lpart := cdr w;
  947. qpart := ofsf_elimsetqua(atfal,car w);
  948. npart := ofsf_elimsetneq(atfal,car w);
  949. return lto_nconcn {lpart,qpart,npart}
  950. end;
  951. procedure ofsf_elimsetscq(atfal);
  952. % Elimination set computation quadratic special case. [atfal] is an
  953. % alist. Returns an elimination set or [nil]. Check if there is
  954. % exactly one point coming from a quadratic non-equation. If so, we
  955. % test the zero of the corresponding derivative, $\pm \infty$, and
  956. % all linear upper and lower bounds. Equations and inequations are
  957. % treated as usual.
  958. begin scalar w,l,a,nzf,zero,d,dfzero,hl;
  959. if not !*rlqeqsc then
  960. return nil;
  961. l := '(neq21q neq22r wo21q wo22r so21q so22r neq21r wo21r so21r);
  962. while l do <<
  963. a := car l;
  964. l := cdr l;
  965. if (w := lto_catsoc(a,atfal)) then
  966. if nzf or a memq '(neq21r wo21r so21r) and cddr w or
  967. a memq '(neq21q neq22r wo21q wo22r so21q so22r) and cdr w
  968. then <<
  969. l := nil;
  970. a := 'failed
  971. >> else <<
  972. zero := car w; % The only entry in w
  973. nzf := car reversip explode a
  974. >>
  975. >>;
  976. if a eq 'failed or null nzf then return nil;
  977. % Construct the zero of the derivative from [zero] which is a
  978. % zero of the polynomial itself.
  979. if nzf = 'q then % bad, but not relevant with !*rlsipd on
  980. dfzero := zero
  981. else << % [nzf = 'r]
  982. zero := cadr zero; % first solution
  983. d := cadddr zero;
  984. dfzero := {ofsf_0mk2('neq,d),ofsf_mksol1(d,negf car zero)}
  985. >>;
  986. hl := {'ofsf_qesubcq . (dfzero . lto_catsoc('equal21q,atfal)),
  987. 'ofsf_qesubcr2 . lto_catsoc('equal22r,atfal),
  988. '(ofsf_qesubi (pinf) (minf))};
  989. return lto_nconcn {hl,ofsf_elimsetlinbs(atfal),ofsf_elimsetneqbs(atfal)}
  990. end;
  991. smacro procedure ofsf_setvlin();
  992. % Ordered field standard form set variables for elimination set
  993. % computation linear case.
  994. <<
  995. equal1 := lto_catsoc('equal1,atfal);
  996. leq1 := lto_catsoc('leq1,atfal);
  997. geq1 := lto_catsoc('geq1,atfal);
  998. greaterp1 := lto_catsoc('greaterp1,atfal);
  999. lessp1 := lto_catsoc('lessp1,atfal);
  1000. wo1 := lto_catsoc('wo1,atfal);
  1001. so1 := lto_catsoc('so1,atfal)
  1002. >>;
  1003. procedure ofsf_elimsetlinbs(atfal);
  1004. % Ordered field standard form elimination set linear case both
  1005. % sides. [atfal] is an alist. Returns an elimination set.
  1006. begin
  1007. scalar equal1,leq1,geq1,greaterp1,lessp1,wo1,so1,qesubcql,
  1008. qesubcqmel,qesubcqpel;
  1009. ofsf_setvlin();
  1010. qesubcql := 'ofsf_qesubcq . lto_nconcn{equal1,leq1,geq1,wo1};
  1011. qesubcqmel := 'ofsf_qesubcqme . lto_nconcn{so1,lessp1};
  1012. qesubcqpel := 'ofsf_qesubcqpe . lto_nconcn{so1,greaterp1};
  1013. return {qesubcql,qesubcqmel,qesubcqpel}
  1014. end;
  1015. procedure ofsf_elimsetneqbs(atfal);
  1016. % Elimination set [neq] test both sides.
  1017. begin scalar neq1,neq21q,neq21r,neq22r;
  1018. neq1 := lto_catsoc('neq1,atfal);
  1019. neq21q := lto_catsoc('neq21q,atfal);
  1020. neq22r := lto_catsoc('neq22r,atfal);
  1021. neq21r := lto_catsoc('neq21r,atfal);
  1022. return {'ofsf_qesubcqme . nconc(neq1,neq21q),'ofsf_qesubcrme2 . neq22r,
  1023. 'ofsf_qesubcrme1 . neq21r,'ofsf_qesubcrpe1 . neq21r,
  1024. 'ofsf_qesubcqpe . nconc(neq1,neq21q),'ofsf_qesubcrpe2 . neq22r}
  1025. end;
  1026. smacro procedure ofsf_setvscl();
  1027. % Ordered field standard form set variables for elimination set
  1028. % computation linear special case.
  1029. <<
  1030. equal1 := lto_catsoc('equal1,atfal);
  1031. equal21q := lto_catsoc('equal21q,atfal);
  1032. equal21r := lto_catsoc('equal21r,atfal);
  1033. equal22r := lto_catsoc('equal22r,atfal);
  1034. leq1 := lto_catsoc('leq1,atfal);
  1035. geq1 := lto_catsoc('geq1,atfal);
  1036. greaterp1 := lto_catsoc('greaterp1,atfal);
  1037. lessp1 := lto_catsoc('lessp1,atfal);
  1038. wo1 := lto_catsoc('wo1,atfal);
  1039. so1 := lto_catsoc('so1,atfal);
  1040. o2p := lto_catsoc('wo21q,atfal) or lto_catsoc('wo21r,atfal) or
  1041. lto_catsoc('wo22r,atfal) or lto_catsoc('so21q,atfal) or
  1042. lto_catsoc('so21r,atfal) or lto_catsoc('so22r,atfal)
  1043. >>;
  1044. procedure ofsf_elimsetscl(atfal);
  1045. % Elimination set computation linear special case. [atfal] is an
  1046. % alist. Returns an elimination set or [nil]. Computes an
  1047. % elimination set for the following two special cases: (1) There is
  1048. % no quadratic bound, the linear bounds there are either all upper
  1049. % bounds or all lower bounds. Then the opposite inifinity can be
  1050. % tested. The inequations can be ignored. (2) There is exactly one
  1051. % bound, which is linear and parametric. Then $\pm \infty$ can be
  1052. % tested. The inequations can be ignored. In both cases the
  1053. % equations are treated as usual.
  1054. begin
  1055. scalar equal1,equal21q,equal21r,equal22r,leq1,geq1,greaterp1,lessp1,
  1056. o2p,nub,nlb,infsubl,wo1,so1;
  1057. ofsf_setvscl();
  1058. if o2p then return nil; % Any quadratic bound
  1059. nub := null (leq1 or lessp1); % No concrete upper bound
  1060. nlb := null (geq1 or greaterp1); % No concrete lower bound
  1061. if null (wo1 or so1) then % No parametric bound
  1062. (if nub then
  1063. infsubl := '(ofsf_qesubi . ((pinf)))
  1064. else if nlb then
  1065. infsubl := '(ofsf_qesubi . ((minf))))
  1066. else if nub and nlb and
  1067. (null wo1 and null cdr so1 or null so1 and null cdr wo1)
  1068. then % Exactly one bound, which is linear and parametric.
  1069. infsubl := '(ofsf_qesubi . ((pinf) (minf)));
  1070. if infsubl then
  1071. return {infsubl,'ofsf_qesubcr1 . equal21r,
  1072. 'ofsf_qesubcq . nconc(equal1,equal21q),'ofsf_qesubcr2 . equal22r}
  1073. end;
  1074. procedure ofsf_elimsetlin1s(atfal);
  1075. % Ordered field standard form elimination set linear part decide
  1076. % for one side. [atfal] is an alist. Returns a pair $a . d$ where
  1077. % $d$ is an elimination set, and $a$ is one of [T], [nil] which
  1078. % means we have decided to test lower bounds or upper bound resp.
  1079. begin
  1080. scalar equal1,leq1,geq1,greaterp1,lessp1,wo1,so1,qesubcql,qesubil,esubl;
  1081. integer l1n,g1n;
  1082. ofsf_setvlin();
  1083. l1n := length leq1 + length lessp1;
  1084. g1n := length geq1 + length greaterp1;
  1085. if l1n <= g1n then <<
  1086. qesubcql := 'ofsf_qesubcq . lto_nconcn{equal1,leq1,wo1};
  1087. esubl := 'ofsf_qesubcqme . nconc(so1,lessp1);
  1088. qesubil := '(ofsf_qesubi . ((pinf)));
  1089. return nil . {qesubcql,esubl,qesubil}
  1090. >>;
  1091. qesubcql := 'ofsf_qesubcq . lto_nconcn{equal1,geq1,wo1};
  1092. esubl := 'ofsf_qesubcqpe . nconc(so1,greaterp1);
  1093. qesubil := '(ofsf_qesubi . ((minf)));
  1094. return T . {qesubcql,esubl,qesubil}
  1095. end;
  1096. procedure ofsf_elimsetqua(atfal,ple);
  1097. % Ordered field standard form elimination set quadratic part.
  1098. % [atfal] is an alist; [ple] is bool where [T] means we have
  1099. % decided for lower bounds in the linear part. Returns an
  1100. % elimination set.
  1101. begin
  1102. scalar equal21q,equal22r,wo21q,wo22r,so21q,so22r,qesubcql,qesubcr1l,
  1103. qesubcr2l,esubcql,esubcr1l,esubcr2l,equal21r,wo21r,so21r;
  1104. equal21q := lto_catsoc('equal21q,atfal);
  1105. equal21r := lto_catsoc('equal21r,atfal);
  1106. equal22r := lto_catsoc('equal22r,atfal);
  1107. wo21q := lto_catsoc('wo21q,atfal);
  1108. wo21r := lto_catsoc('wo21r,atfal);
  1109. wo22r := lto_catsoc('wo22r,atfal);
  1110. so21q := lto_catsoc('so21q,atfal);
  1111. so21r := lto_catsoc('so21r,atfal);
  1112. so22r := lto_catsoc('so22r,atfal);
  1113. if ple then <<
  1114. esubcql := 'ofsf_qesubcqpe . so21q;
  1115. esubcr1l := 'ofsf_qesubcrpe1 . so21r;
  1116. esubcr2l := 'ofsf_qesubcrpe2 . so22r
  1117. >> else <<
  1118. esubcql := 'ofsf_qesubcqme . so21q;
  1119. esubcr1l := 'ofsf_qesubcrme1 . so21r;
  1120. esubcr2l := 'ofsf_qesubcrme2 . so22r
  1121. >>;
  1122. qesubcql := 'ofsf_qesubcq . nconc(equal21q,wo21q);
  1123. qesubcr1l := 'ofsf_qesubcr1 . nconc(equal21r,wo21r);
  1124. qesubcr2l := 'ofsf_qesubcr2 . nconc(equal22r,wo22r);
  1125. return {qesubcql,qesubcr1l,qesubcr2l,esubcql,esubcr1l,esubcr2l}
  1126. end;
  1127. smacro procedure ofsf_setvneq();
  1128. % Ordered field standard form set variables for elimination set
  1129. % computation [neq] treatment.
  1130. <<
  1131. neq1 := lto_catsoc('neq1,atfal);
  1132. neq21q := lto_catsoc('neq21q,atfal);
  1133. neq21r := lto_catsoc('neq21r,atfal);
  1134. neq22r := lto_catsoc('neq22r,atfal);
  1135. leq1 := lto_catsoc('leq1,atfal);
  1136. geq1 := lto_catsoc('geq1,atfal);
  1137. wo1 := lto_catsoc('wo1,atfal);
  1138. wo21q := lto_catsoc('wo21q,atfal);
  1139. wo21r := lto_catsoc('wo21r,atfal);
  1140. wo22r := lto_catsoc('wo22r,atfal)
  1141. >>;
  1142. procedure ofsf_elimsetneq(atfal,ple);
  1143. % Ordered field standard form elimination set treatment of ['neq].
  1144. % [atfal] is an alist; [ple] is bool where [T] means we have
  1145. % decided for lower bounds in the linear part. Returns an
  1146. % elimination set.
  1147. begin
  1148. scalar neq1,neq21q,neq21r,neq22r,leq1,geq1,wo1,wo21q,wo21r,wo22r,
  1149. neqn,wbn,esubcq,esubcr1,esubcr2,wb1;
  1150. ofsf_setvneq();
  1151. neqn := length neq1 + length neq21q + length neq21r + 2*(length neq22r);
  1152. if neqn = 0 then return nil;
  1153. wbn := length wo1 + length wo21q + length wo21r +
  1154. 2*(length wo22r); % + ...
  1155. if ple then <<
  1156. esubcq := 'ofsf_qesubcqpe;
  1157. esubcr1 := 'ofsf_qesubcrpe1;
  1158. esubcr2 := 'ofsf_qesubcrpe2;
  1159. wb1 := geq1;
  1160. wbn := wbn + length geq1
  1161. >> else <<
  1162. esubcq := 'ofsf_qesubcqme;
  1163. esubcr1 := 'ofsf_qesubcrme1;
  1164. esubcr2 := 'ofsf_qesubcrme2;
  1165. wb1 := leq1;
  1166. wbn := wbn + length leq1
  1167. >>;
  1168. if neqn < wbn then
  1169. return {esubcq .
  1170. nconc(neq1,neq21q),esubcr1 . neq21r,esubcr2 . neq22r};
  1171. if !*rlverbose then ioto_prin2 {"(ANEQ:",neqn,"|",wbn,")"};
  1172. return {esubcq . lto_nconcn{wb1,wo1,wo21q},esubcr1 . wo21r,
  1173. esubcr2 . wo22r}
  1174. end;
  1175. procedure ofsf_bettergaussp(grv1,grv2);
  1176. % Ordered field standard form better Gauss predicate. [grv1] and
  1177. % [grv2] are GRV's. Returns [T] if [grv1] encodes a better Gauss
  1178. % application than [grv2] encodes.
  1179. begin scalar w1,w2;
  1180. if car grv1 eq 'failed then
  1181. return nil;
  1182. if car grv2 eq 'failed then
  1183. return T;
  1184. w1 := cadar grv1;
  1185. w2 := cadar grv2;
  1186. if w1 neq w2 then
  1187. return (w1 memq cdr (w2 memq '(fac quar qua2q quaq lin)));
  1188. w1 := caddar grv1;
  1189. w2 := caddar grv2;
  1190. if w1 neq w2 then
  1191. return w1 memq cdr (w2 memq '(gen td con));
  1192. w1 := ofsf_esetlength cadr grv1;
  1193. w2 := ofsf_esetlength cadr grv2;
  1194. if w1 neq w2 then
  1195. return w1 < w2;
  1196. w1 := caddar grv1;
  1197. w2 := caddar grv2;
  1198. % if w1 neq w2 then
  1199. return w1 memq cdr (w2 memq '(gen td con));
  1200. end;
  1201. procedure ofsf_esetlength(e);
  1202. % Ordered field standard form elimination set length. [e] is an
  1203. % elimination set. Returns the number of elimination terms in [e].
  1204. for each p in e sum
  1205. for each x in p sum
  1206. length cdr p;
  1207. procedure ofsf_esetunion(e1,e2);
  1208. % Ordered field standard form elimination set union. [e1] and [e2]
  1209. % are elimination sets. Returns the union of [e1] and [e2].
  1210. lto_alunion({e1,e2});
  1211. procedure ofsf_bestgaussp(grv);
  1212. % Ordered field standard form best Gauss predicate. [grv] is a GRV.
  1213. % Returns [T] if the Gauss application encoded in GRV is the best
  1214. % Gauss application under all possible Gauss applications.
  1215. not(car grv eq 'failed) and not(car grv eq 'gignore) and
  1216. cadar grv eq 'lin and caddar grv eq 'con and % Linear, concrete coeff.
  1217. null cdr cadr grv and null cddar cadr grv; % Only one elim. term
  1218. procedure ofsf_qefsolset(a,v,theo,ans,bvl);
  1219. % Ordered field standard form quantifier elimination finite
  1220. % solution set. [a] is an atomic formula; [v] is a variable; [theo]
  1221. % is the current theory; [ans] is Boolean; [bvl] is a list of
  1222. % variables. Returns an IGRV.
  1223. begin scalar w;
  1224. if ofsf_op a neq 'equal then
  1225. return '(failed . nil);
  1226. w := ofsf_varlat a;
  1227. if v memq w then
  1228. return ofsf_findeqsol(a,v,theo,ans,bvl);
  1229. if !*rlqegen and ofsf_valassp(bvl,ofsf_arg2l a) then
  1230. return ('gignore . (nil . {ofsf_0mk2('neq,ofsf_arg2l a)}));
  1231. return '(failed . nil);
  1232. end;
  1233. procedure ofsf_findeqsol(a,v,theo,ans,bvl);
  1234. % Ordered field standard form find solution of non-trivial equation
  1235. % subroutine. [a] is an atomic formula; [v] is a variable; [theo]
  1236. % is a list of atomic formulas, the current theory; [ans] is
  1237. % Boolean; [bvl] is a list of variables that are considered
  1238. % non-parametric. Returns $[failed] . [nil]$ or a form $(\tau . (e
  1239. % . \theta))$ where $\tau$ is an identifier tag encoding the degree
  1240. % of the Gauss application, [e] is an elimination set, and $\theta$
  1241. % is the new theory. If [!*rlqegen] is off, we know
  1242. % $\theta'=[nil]$.
  1243. begin scalar w,d,theop,tag;
  1244. w := ofsf_pnontrivial(ofsf_arg2l a,v,theo,bvl);
  1245. tag := car w;
  1246. if not tag then
  1247. return '(failed . nil);
  1248. if cdr w then
  1249. theop := {cdr w};
  1250. d := degreef(ofsf_arg2l a,v);
  1251. w := ofsf_gelimset ofsf_translat(a,v,theo,T,ans);
  1252. if w eq 'failed then return '(failed . nil);
  1253. return ofsf_mkgtag(d,tag,w,theo) . (w . theop)
  1254. end;
  1255. procedure ofsf_mkgtag(d,tag,eset,theo);
  1256. % Ordered field standard form make Gauss tag. [d] is positive
  1257. % integer; [tag] is an identifier; [eset] is an elimination set;
  1258. % [theo] is the current theory.
  1259. begin scalar w,v;
  1260. w := if d=1 then 'lin else if d=2 then ofsf_mkgtagq(eset,theo) else 'fac;
  1261. v := if d=1 then v := "l" . v else if d=2 then v := "q" . v;
  1262. if tag eq 'gen then v := "!" . v;
  1263. return {v,w,tag}
  1264. end;
  1265. procedure ofsf_mkgtagq(eset,theo);
  1266. % Ordered field standard form make Gauss tag quadratic case. [eset]
  1267. % is an elimination set; [theo] is the current theory.
  1268. begin scalar a;
  1269. if null cdr eset and caar eset eq 'ofsf_qesubcq then
  1270. return 'quaq;
  1271. a := atsoc('ofsf_qesubcr2,eset) or atsoc('ofsf_qesubcr1,eset);
  1272. % We know [a neq nil].
  1273. if null cadr cadr cadr a then % $b$ of the first root expression.
  1274. return 'qua2q;
  1275. return 'quar
  1276. end;
  1277. procedure ofsf_gelimset(alp);
  1278. % Gauss elimination set. [alp] is a pair of alists obtained from
  1279. % [ofsf_translat]. Returns an elimination set.
  1280. begin scalar eset;
  1281. eset := car alp;
  1282. if eset = 'failed then return 'failed;
  1283. if null cdr eset and caar eset = 'anypoint then
  1284. return {'ofsf_qesubcq . {'(true (nil . nil))}};
  1285. for each x in eset do
  1286. if car x memq '(equal1 equal21q) then
  1287. car x := 'ofsf_qesubcq
  1288. else if car x = 'equal21r then
  1289. car x := 'ofsf_qesubcr1
  1290. else if car x = 'equal22r then
  1291. car x := 'ofsf_qesubcr2
  1292. else
  1293. rederr "BUG IN ofsf_gelimset";
  1294. return eset
  1295. end;
  1296. procedure ofsf_pnontrivial(u,v,theo,bvl);
  1297. % Possibly non-trivial. [u] is an SF; [v] is a variable; [theo] is
  1298. % a list of atomic formulas, the current theory; [bvl] is a list of
  1299. % variables that are considered non-parametric. Returns a pair $p .
  1300. % \theta'$ where $\theta'$ is an inequation or [nil], and $p$ is
  1301. % non-[nil] iff one of the coefficients of [u] wrt. [v] may be
  1302. % assumed nonzero under the assumption $[theo] \cup \{\theta'\}$.
  1303. % If [!*rlqegen] is off, we know $\theta'=[nil]$.
  1304. begin scalar vcoeffs;
  1305. vcoeffs := for each x in coeffs sfto_reorder(u,v) collect reorder x;
  1306. return ofsf_maybenonzerol(vcoeffs,theo,bvl)
  1307. end;
  1308. procedure ofsf_maybenonzerol(l,theo,bvl);
  1309. % Maybe not a list of zero SF's. [l] is a list of SF's; [theo] is a
  1310. % list of atomic formulas, the current theory; [bvl] is a list of
  1311. % variables that are considered non-parametric. Returns a pair $p .
  1312. % \theta'$ where $\theta'$ is an inequation or [nil], and $p$ is
  1313. % non-[nil] iff one of the elements of [l] may be assumed nonzero under
  1314. % the assumption $[theo] \cup \{\theta'\}$. If [!*rlqegen] is
  1315. % off, we know $\theta'=[nil]$.
  1316. begin scalar w,result;
  1317. result := '(nil . nil);
  1318. while l do <<
  1319. w := ofsf_maybenonzero(car l,theo,bvl);
  1320. l := cdr l;
  1321. if car w then <<
  1322. result := w;
  1323. l := nil
  1324. >>
  1325. >>;
  1326. return result
  1327. end;
  1328. procedure ofsf_maybenonzero(u,theo,bvl);
  1329. % Maybe a non-zero SF's. [u] is an SF's; [theo] is a list of atomic
  1330. % formulas, the current theory; [bvl] is a list of variables that
  1331. % are considered non-parametric. Returns a pair $p . \theta'$ where
  1332. % $\theta'$ is an inequation or [nil], and $p$ is non-[nil] iff [u] may
  1333. % be assumed nonzero under the assumption $[theo] \cup
  1334. % \{\theta'\}$. If [!*rlqegen] is off, we know $\theta'=[nil]$.
  1335. if domainp u then
  1336. if null u then
  1337. '(nil . nil)
  1338. else
  1339. '(con . nil) % con = concrete
  1340. else if cl_simpl(ofsf_0mk2('equal,u),theo,-1) eq 'false then
  1341. '(td . nil) % td = theory derived
  1342. else if !*rlqegen and ofsf_valassp(bvl,u) then
  1343. 'gen . ofsf_0mk2('neq,u) % gen = generic
  1344. else
  1345. '(nil . nil);
  1346. procedure ofsf_qemkans(an,atr);
  1347. sort(
  1348. ofsf_qeapplyatr ofsf_qebacksub ofsf_qemkans1 an,
  1349. function(lambda(x,y); ordp(cadr x,cadr y)));
  1350. procedure ofsf_qemkans1(an);
  1351. % Ordered field standard form quantifier elimination make answer
  1352. % subroutine. [an] is an answer. Returns a list $((e,a),...)$,
  1353. % where $e$ is an equation and $a$ is an answer translation.
  1354. begin scalar v,sub,xargl,w,atr;
  1355. return for each y in an collect <<
  1356. v := car y;
  1357. sub := cadr y;
  1358. xargl := caddr y;
  1359. atr := cadddr y;
  1360. w := if sub eq 'ofsf_qesubi then <<
  1361. atr := nil;
  1362. (if car xargl = 'pinf then
  1363. 'infinity
  1364. else if car xargl = 'minf then
  1365. '(minus infinity))
  1366. >> else if sub eq 'ofsf_qesubcq then
  1367. prepsq cadr xargl
  1368. else if sub eq 'ofsf_qesubcr1 then
  1369. ofsf_preprexpr(cadr xargl)
  1370. else if sub eq 'ofsf_qesubcqme then
  1371. {'difference,prepsq cadr xargl,'epsilon}
  1372. else if sub eq 'ofsf_qesubcqpe then
  1373. {'plus,prepsq cadr xargl,'epsilon}
  1374. else if sub eq 'ofsf_qesubcrme1 then
  1375. {'difference,ofsf_preprexpr(cadr xargl),'epsilon}
  1376. else if sub eq 'ofsf_qesubcrpe1 then
  1377. {'plus,ofsf_preprexpr(cadr xargl),'epsilon}
  1378. else
  1379. rederr "BUG IN ofsf_qemkans";
  1380. {{'equal,v,w},atr}
  1381. >>
  1382. end;
  1383. procedure ofsf_qebacksub(eql);
  1384. % Quantifier elimination back substitution. [eql] is a list
  1385. % $((e,a),...)$, where $e$ is an equation and $a$ is an answer
  1386. % translation. Returns a list of the same form.
  1387. begin scalar subl,rhs,ioe,atr,e; integer ic,ec;
  1388. return for each w in eql collect <<
  1389. e := car w;
  1390. atr := cadr w;
  1391. rhs := simp caddr e;
  1392. if smemq('infinity,rhs) then <<
  1393. ic := ic+1;
  1394. ioe := mkid('infinity,ic);
  1395. rhs := subsq(rhs,{'infinity . ioe})
  1396. >>;
  1397. if smemq('epsilon,rhs) then <<
  1398. ec := ec+1;
  1399. ioe := mkid('epsilon,ec);
  1400. flag({ioe},'constant);
  1401. put(ioe,'!:rd!:,'rdzero!*);
  1402. rhs := subsq(rhs,{'epsilon . ioe})
  1403. >>;
  1404. e := {'equal,cadr e,prepsq subsq(rhs,subl)};
  1405. subl := (cadr e . caddr e) . subl;
  1406. {e,atr}
  1407. >>
  1408. end;
  1409. procedure ofsf_qeapplyatr(eql);
  1410. % Ordered field standard form quantifier elimination apply answer
  1411. % translation. [eql] is a list $((e,a),...)$, where $e$ is an
  1412. % equation and $a$ is an answer translation. Returns a list of
  1413. % equations.
  1414. begin scalar rhs,atr,pow,eqn;
  1415. return for each w in eql collect <<
  1416. eqn := car w;
  1417. rhs := caddr eqn;
  1418. atr := cadr w;
  1419. if null atr then
  1420. eqn
  1421. else <<
  1422. pow := lto_catsoc(cadr eqn,atr) or 1;
  1423. {'equal,cadr eqn,ofsf_croot(rhs,pow)}
  1424. >>
  1425. >>
  1426. end;
  1427. procedure ofsf_croot(u,n);
  1428. if null n then u else reval {'expt,u,{'quotient,1,n}};
  1429. procedure ofsf_preprexpr(r);
  1430. {'quotient,{'plus,prepf car r,{'times,prepf cadr r,{'sqrt,prepf caddr r}}},
  1431. prepf cadddr r};
  1432. procedure ofsf_decdeg(f);
  1433. % Ordered field standard form decrease degrees. [f] is a formula.
  1434. % Returns a formula equivalent to [f], hopefully decreasing the
  1435. % degrees of the bound variables.
  1436. ofsf_decdeg0 cl_rename!-vars f;
  1437. procedure ofsf_decdeg0(f);
  1438. begin scalar op,w,gamma,newmat;
  1439. op := rl_op f;
  1440. if rl_boolp op then
  1441. return rl_mkn(op,for each subf in rl_argn f collect
  1442. ofsf_decdeg0 subf);
  1443. if rl_quap op then <<
  1444. w := ofsf_decdeg1(ofsf_decdeg0 rl_mat f,{rl_var f});
  1445. newmat := if null cdr w or not evenp cdr car cdr w then
  1446. car w
  1447. else <<
  1448. gamma := ofsf_0mk2('geq,numr simp car car cdr w);
  1449. rl_mkn(if op eq 'ex then 'and else 'impl,{gamma,car w})
  1450. >>;
  1451. return rl_mkq(op,rl_var f,newmat)
  1452. >>;
  1453. % [f] is not complex.
  1454. return f
  1455. end;
  1456. procedure ofsf_decdeg1(f,vl);
  1457. % Ordered field standard form decremet degrees. [f] is a formula;
  1458. % [vl] is a list of variables $v$ such that $v$ does not occur
  1459. % boundly in [f], or ['fvarl]. Returns a pair $(\phi . l)$; $\phi$
  1460. % is a formula, and $l$ is a list of pairs $(v . d)$ where $v$ in
  1461. % [vl] and $d$ is an integer. We have $\exists [vl] [f]$ equivalent
  1462. % to $\exists [vl] (\phi \land \bigwedge_{(v . d) \in [vl]}(v^d
  1463. % \geq 0))$, where $\phi$ is obtained from [f] by substituting $v$
  1464. % for $v^d$ for each $(v . d)$ in $l$. ['fvarl] stands for the list
  1465. % of all free variables in [f].
  1466. begin scalar dvl; integer n;
  1467. if vl eq 'fvarl then
  1468. vl := cl_fvarl1 f;
  1469. for each v in vl do <<
  1470. n := ofsf_decdeg2(f,v);
  1471. if n>1 then <<
  1472. f := ofsf_decdeg3(f,v,n);
  1473. dvl := (v . n) . dvl
  1474. >>
  1475. >>;
  1476. return f . dvl
  1477. end;
  1478. procedure ofsf_decdeg2(f,v);
  1479. % Ordered field standard form decrement degree subroutine. [f] is a
  1480. % formula; [v] is a variable. Returns an INTEGER $n$. The degree of [v]
  1481. % in [f] can be decremented using the substitution $[v]^n=v$.
  1482. begin scalar a,w,atl,dgcd,!*gcd,oddp;
  1483. !*gcd := T;
  1484. atl := cl_atl1 f;
  1485. dgcd := 0;
  1486. while atl and dgcd neq 1 do <<
  1487. a := car atl;
  1488. atl := cdr atl;
  1489. w := ofsf_ignshift(a,v);
  1490. if w eq 'odd and null oddp then
  1491. oddp := 'odd
  1492. else if null w then <<
  1493. a := sfto_reorder(ofsf_arg2l a,v);
  1494. while (not domainp a) and (mvar a eq v) and dgcd neq 1 do <<
  1495. dgcd := gcdf(dgcd,ldeg a);
  1496. a := red a
  1497. >>
  1498. >>;
  1499. if dgcd > 0 and oddp eq 'odd then <<
  1500. oddp := T;
  1501. while w := quotf(dgcd,2) do
  1502. dgcd := w
  1503. >>
  1504. >>;
  1505. if dgcd = 0 then
  1506. return 1;
  1507. return dgcd
  1508. end;
  1509. procedure ofsf_transform(f,v);
  1510. % Ordered field standard form transform formula. [f] is a
  1511. % quantifier-free formula; [v] is a variable. Returns a pair $(\phi
  1512. % . a)$. $\phi$ is a formula such that $\exists [v]([f])$ is
  1513. % equivalent to $\exists [v](\phi)$. $a$ is either [nil] or a pair
  1514. % $([v] . d)$. If $a$ is not [nil] then the degree $d'$ of [v] in
  1515. % [f] is reduced to $d'/d$. If $a$ is nil then $[f]=\phi$.
  1516. begin scalar dgcd;
  1517. dgcd := ofsf_decdeg2(f,v);
  1518. if dgcd = 1 then
  1519. return f . nil;
  1520. if !*rlverbose then ioto_prin2 {"(",v,"^",dgcd,")"};
  1521. f := ofsf_decdeg3(f,v,dgcd);
  1522. if evenp dgcd then
  1523. f := rl_mkn('and,{ofsf_0mk2('geq,numr simp v),f});
  1524. return f . (v . dgcd)
  1525. end;
  1526. procedure ofsf_ignshift(at,v);
  1527. % Orderd field standard form ignore shift. [at] is an atomic
  1528. % formula; [v] is a variable. Returns [nil], ['ignore], or ['odd].
  1529. begin scalar w;
  1530. w := sfto_reorder(ofsf_arg2l at,v);
  1531. if not domainp w and null red w and mvar w eq v then
  1532. if ofsf_op at memq '(equal neq) or evenp ldeg w then
  1533. return 'ignore
  1534. else
  1535. return 'odd
  1536. end;
  1537. procedure ofsf_decdeg3(f,v,n);
  1538. % Ordered field standard form decrement degree. [f] is a formula;
  1539. % [v] is a variable; [n] is an integer. Returns a formula.
  1540. cl_apply2ats1(f,'ofsf_decdegat,{v,n});
  1541. procedure ofsf_decdegat(atf,v,n);
  1542. % Ordered field standard form decrement degree atomic formula. [f]
  1543. % is an atomic formula; [v] is a variable; [n] is an integer. Returns
  1544. % an atomic formula.
  1545. if ofsf_ignshift(atf,v) then
  1546. atf
  1547. else
  1548. ofsf_0mk2(ofsf_op atf,sfto_decdegf(ofsf_arg2l atf,v,n));
  1549. procedure ofsf_updatr(atr,upd);
  1550. % Ordered field standard form update answer translation. [atr] is
  1551. % an answer translation; [upd] is information which has to be added
  1552. % to [atr]. Returns an answer translation.
  1553. upd . atr;
  1554. procedure ofsf_thsimpl(atl);
  1555. % Ordered field standard form theory simplification. [atl] is a
  1556. % theory. Returns an equivalent theory. The returned theory is
  1557. % hopefully somehow simpler than the original one.
  1558. begin scalar !*rlsiexpla,!*rlsipo;
  1559. !*rlsiexpla := T;
  1560. return sort(ofsf_thregen cl_simpl(rl_smkn('and,atl),nil,-1),'rl_ordatp)
  1561. end;
  1562. procedure ofsf_thregen(f);
  1563. % Ordered field standard form re-generate theory. [f] is a formula.
  1564. % Returns a possibly empty list of atomic formulas equivalent to
  1565. % [f] or the list [{'false}] if [f] is recognized as a
  1566. % contradiction.
  1567. begin scalar op;
  1568. op := rl_op f;
  1569. if op = 'and then
  1570. return for each x in rl_argn f collect ofsf_thregen!-or x;
  1571. if op = 'or then
  1572. return {ofsf_thregen!-or f};
  1573. if op = 'true then
  1574. return nil;
  1575. if op = 'false then
  1576. {'false};
  1577. % [f] is atomic.
  1578. return {f}
  1579. end;
  1580. procedure ofsf_thregen!-and(f);
  1581. % Ordered field standard form re-generate theory conjunction case.
  1582. % [f] is a conjunction. Returns an atomic formula equivalent to
  1583. % [f].
  1584. cl_nnfnot ofsf_thregen!-or cl_nnfnot f;
  1585. procedure ofsf_thregen!-or(f);
  1586. % Ordered field standard form re-generate theory disjunction case.
  1587. % [f] is a disjunction. Returns an atomic formula equivalent to
  1588. % [f].
  1589. begin scalar w;
  1590. if cl_atfp f then
  1591. return f;
  1592. w := car rl_argn f;
  1593. if rl_op w = 'and then
  1594. w := ofsf_thregen!-and w;
  1595. if rl_op w = 'equal then
  1596. return ofsf_thregen!-equal(w . cdr rl_argn f);
  1597. if rl_op w = 'neq then
  1598. return ofsf_thregen!-neq(w . cdr rl_argn f);
  1599. rederr "BUG IN ofsf_thregen!-or"
  1600. end;
  1601. procedure ofsf_thregen!-equal(eql);
  1602. % Ordered field standard form re-generate theory equality
  1603. % disjunction case. [eql] is a list of equations or complex
  1604. % formulas which can be contracted to one equation. The list is
  1605. % considered disjunctive. Returns an atomic formula equivalent to
  1606. % $\bigvee [eql]$ constructed by multiplication of the left hand
  1607. % sides.
  1608. begin scalar w;
  1609. w := 1;
  1610. for each x in eql do <<
  1611. if rl_op x = 'and then
  1612. x := ofsf_thregen!-and x;
  1613. if rl_op x neq 'equal then
  1614. rederr "BUG IN ofsf_thregen!-equal";
  1615. w := multf(w,ofsf_arg2l x)
  1616. >>;
  1617. return ofsf_0mk2('equal,w)
  1618. end;
  1619. procedure ofsf_thregen!-neq(neql);
  1620. % Ordered field standard form re-generate theory [neq] disjunction
  1621. % case. [neql] is a list of inequalities or complex formulas which
  1622. % can be contracted to one inequality. The list is considered
  1623. % disjunctive. Returns an atomic formula equivalent to $\bigvee
  1624. % [neql]$ constructed by addition of the squares of the left hand
  1625. % sides.
  1626. begin scalar w;
  1627. for each x in neql do <<
  1628. if rl_op x = 'and then
  1629. x := ofsf_thregen!-and x;
  1630. if rl_op x neq 'neq then
  1631. rederr "BUG IN ofsf_thregen!-neq";
  1632. w := addf(w,exptf(ofsf_arg2l x,2))
  1633. >>;
  1634. return ofsf_0mk2('neq,w)
  1635. end;
  1636. procedure ofsf_specelim(f,vl,theo,ans,bvl);
  1637. % Ordered field standard form special elimination.
  1638. if (not !*rlqesqsc) or ans or !*rlqegen then
  1639. 'failed
  1640. else
  1641. ofsf_sqsc(f,vl,theo,ans,bvl);
  1642. procedure ofsf_sqsc(f,vl,theo,ans,bvl);
  1643. % Ordered field standard form super quadratic special case.
  1644. begin scalar w,atl,scvl,lin,a,at;
  1645. atl := cl_atl1 f;
  1646. scvl := if !*rlqevarsel then vl else {car vl};
  1647. while scvl and not lin do <<
  1648. a := car scvl;
  1649. scvl := cdr scvl;
  1650. lin := ofsf_linp(atl,a,delq(a,vl))
  1651. >>;
  1652. if lin then
  1653. return 'failed;
  1654. scvl := if !*rlqevarsel then vl else {car vl};
  1655. while scvl and not at do <<
  1656. a := car scvl;
  1657. scvl := cdr scvl;
  1658. at := ofsf_sqsc!-test(atl,a)
  1659. >>;
  1660. if not at then
  1661. return 'failed;
  1662. if !*rlverbose then
  1663. ioto_prin2 "#Q";
  1664. vl := delq(a,vl);
  1665. f := cl_simpl(ofsf_sqsc1(f,at,a,theo),theo,-1);
  1666. return (t . {cl_mkcoel(vl,f,nil,nil)}) . theo
  1667. end;
  1668. procedure ofsf_sqsc1(f,at,v,theo);
  1669. if cl_cxfp f then
  1670. rl_mkn(rl_op f,for each x in rl_argn f collect ofsf_sqsc1(x,at,v,theo))
  1671. else if f eq at then
  1672. ofsf_sqsc1at(at,v,theo)
  1673. else
  1674. f;
  1675. procedure ofsf_sqsc1at(at,v,theo);
  1676. begin scalar op,w,a,b,c,discr;
  1677. op := ofsf_op at;
  1678. w := ofsf_mktriple(sfto_reorder(ofsf_arg2l at,v));
  1679. a := reorder car w;
  1680. b := reorder cadr w;
  1681. c := reorder caddr w;
  1682. if op eq 'neq then
  1683. return rl_mkn('or,
  1684. {ofsf_0mk2('neq,a),ofsf_0mk2('neq,b),ofsf_0mk2('neq,c)});
  1685. discr := addf(exptf(b,2),negf multf(4,multf(a,c)));
  1686. if op eq 'equal then <<
  1687. if ofsf_surep(ofsf_0mk2('neq,a),theo) then
  1688. return ofsf_0mk2('geq,discr);
  1689. return rl_mkn('or,
  1690. {ofsf_0mk2('greaterp,discr),ofsf_0mk2('equal,c),
  1691. rl_mkn('and,{ofsf_0mk2('equal,discr),ofsf_0mk2('neq,b)})})
  1692. >>;
  1693. if op eq 'leq then <<
  1694. if ofsf_surep(ofsf_0mk2('greaterp,a),theo) then
  1695. return ofsf_0mk2('geq,discr);
  1696. return rl_mkn('or,
  1697. {ofsf_0mk2('lessp,a),ofsf_0mk2('leq,c),
  1698. rl_mkn('and,{ofsf_0mk2('geq,discr),ofsf_0mk2('neq,b)})})
  1699. >>;
  1700. if op eq 'geq then <<
  1701. if ofsf_surep(ofsf_0mk2('lessp,a),theo) then
  1702. return ofsf_0mk2('geq,discr);
  1703. return rl_mkn('or,
  1704. {ofsf_0mk2('greaterp,a),ofsf_0mk2('geq,c),
  1705. rl_mkn('and,{ofsf_0mk2('geq,discr),ofsf_0mk2('neq,b)})})
  1706. >>;
  1707. if op eq 'lessp then <<
  1708. if ofsf_surep(ofsf_0mk2('greaterp,a),theo) then
  1709. return ofsf_0mk2('greaterp,discr);
  1710. return rl_mkn('or,{ofsf_0mk2('greaterp,discr),
  1711. ofsf_0mk2('lessp,a),ofsf_0mk2('lessp,c)})
  1712. >>;
  1713. if op eq 'greaterp then <<
  1714. if ofsf_surep(ofsf_0mk2('lessp,a),theo) then
  1715. return ofsf_0mk2('greaterp,discr);
  1716. return rl_mkn('or,{ofsf_0mk2('greaterp,discr),
  1717. ofsf_0mk2('greaterp,a),ofsf_0mk2('greaterp,c)})
  1718. >>;
  1719. rederr {"ofsf_sqsc1at: unknown operator ",op}
  1720. end;
  1721. procedure ofsf_sqsc!-test(atl,v);
  1722. begin scalar hit,a,d;
  1723. while atl do <<
  1724. a := car atl;
  1725. atl := cdr atl;
  1726. d := degreef(ofsf_arg2l a,v);
  1727. if d=1 then
  1728. atl := hit := nil
  1729. else if d=2 then
  1730. if hit then
  1731. atl := hit := nil
  1732. else
  1733. hit := a
  1734. >>;
  1735. return hit
  1736. end;
  1737. endmodule; % [ofsfqe]
  1738. end; % of file