cgb.red 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541
  1. % ----------------------------------------------------------------------
  2. % $Id: cgb.red,v 1.30 2004/05/03 16:38:25 sturm Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 1999-2003 Andreas Dolzmann and Thomas Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: cgb.red,v $
  7. % Revision 1.30 2004/05/03 16:38:25 sturm
  8. % Hopefully clean solution for deadlock with CGB/REDLOG compilation.
  9. %
  10. % Revision 1.29 2003/10/21 10:24:36 gilch
  11. % Incorporated new module gbsc.
  12. %
  13. % Revision 1.28 2003/10/12 14:50:30 sturm
  14. % The bootstrapping technique via remflag('(load!-package),'eval); does
  15. % not work for CSL. Added corresponding preprocessing directive for now.
  16. % As a consequence, under CSL "redlog" has to be loaded explicitly when
  17. % using CGB.
  18. %
  19. % Revision 1.27 2003/07/17 06:30:38 dolzmann
  20. % Added new argument xvarl to Groebner system computation. xvarl is a list
  21. % of variables. If cgbgen is on gsys makes no assumptions on variaboles
  22. % in xvarl.
  23. %
  24. % Revision 1.26 2003/05/20 08:17:38 dolzmann
  25. % Moved cd_init to the beginning of cgb_interface!$.
  26. % This may be neccessary for the a2s procedures.
  27. %
  28. % Revision 1.25 2003/05/20 07:38:26 dolzmann
  29. % Do not load modules belongig to this package.
  30. %
  31. % Revision 1.24 2003/05/20 07:24:46 dolzmann
  32. % Moved macro *_mkinterface to the right place.
  33. %
  34. % Revision 1.23 2003/05/19 10:27:18 dolzmann
  35. % Adapted to the Groebner simplifier using gb.
  36. % Added interface generator as in gb.
  37. % Used interface generator for creating all interfaces.
  38. % Added first version of a wrapper for non-parametric input.
  39. % Removed old interface code.
  40. % Introduced initial theory for Gröbner and green Gröbner system
  41. % computation.
  42. %
  43. % Revision 1.22 2003/04/17 16:14:45 dolzmann
  44. % Added AM interface ggsys for computing green Groebner systems.
  45. % Added switch cgbsgreen. If it is on then the green Groebner system is
  46. % computed by computing a regular Groebner system and finally colorying
  47. % it green. If off (derfault) the green groebner system is computed by a
  48. % modified Groebner system computation.
  49. % Renamed cgb_greengsysf(u) to cgb_ggsysf(u);
  50. %
  51. % Revision 1.21 2003/04/16 09:43:18 dolzmann
  52. % Added (inefficient) procedure for computing green Groebner systems.
  53. % Added procedure for computing groebner systems for SFs.
  54. % Added and corrected some comments.
  55. %
  56. % Revision 1.20 1999/04/13 20:56:04 dolzmann
  57. % Added default setting for switches.
  58. %
  59. % Revision 1.19 1999/04/13 18:41:21 dolzmann
  60. % Dropped zeroes and duplicates in the input system.
  61. % Sort Groebner systems, conditions, and (partial) bases.
  62. % Removed switch gsugar.
  63. % Removed main variable list and parameter list arguments from the
  64. % entire call tree.
  65. % Renamed all gb switches and fluids to cgb.
  66. %
  67. % Revision 1.18 1999/04/11 11:31:37 dolzmann
  68. % Introduced wrappers for using the gb package in case of non-parametric
  69. % problems.
  70. %
  71. % Revision 1.17 1999/04/11 09:49:05 dolzmann
  72. % Completely rewritten the interface code for the AM and the standard
  73. % form interface.
  74. %
  75. % Revision 1.16 1999/04/07 15:54:16 dolzmann
  76. % Fixed a bug in cgb_gsys2cgb: Rewritten procedure cgb_rtgsys to handle
  77. % the case of no main variable.
  78. %
  79. % Revision 1.15 1999/04/07 12:37:00 dolzmann
  80. % Fixed a bug in cgp_monp.
  81. % Added comments to all procedures.
  82. %
  83. % Revision 1.14 1999/04/07 09:27:08 dolzmann
  84. % Added switch cgbgen and related code for computing only the generic branch.
  85. %
  86. % Revision 1.13 1999/04/06 12:13:59 dolzmann
  87. % Moved procedures dip_append, dip_cp, dip_dcont, and dip_dcont1 from
  88. % module dipto into module dip.
  89. % Moved procedures bc_mkat, bc_dcont, and bc_2d from module bcto into the
  90. % bc modules of the dip package.
  91. %
  92. % Revision 1.12 1999/04/05 09:16:46 sturm
  93. % Do not load Redlog during complilation.
  94. %
  95. % Revision 1.11 1999/04/05 09:06:09 sturm
  96. % Locally bind !*rlgsvb for calls to rl_gsd.
  97. %
  98. % Revision 1.10 1999/04/04 18:30:52 sturm
  99. % Provide a standard form interface cgb_cgbf to cgb's.
  100. %
  101. % Revision 1.9 1999/04/04 16:46:07 sturm
  102. % Changed cgb_groebnereval into cgb_gsys.
  103. % Added copyright and CVS fluids.
  104. % Added create!-package.
  105. %
  106. % Revision 1.8 1999/04/04 14:50:37 sturm
  107. % Implemented switch tdusetorder.
  108. %
  109. % Revision 1.7 1999/04/04 14:09:31 sturm
  110. % Moved dip_ilcomb and dip_ilcombr from cgb.red to dp.red.
  111. % Created vdp_ilcomb and vdp_ilcombr for gb.red.
  112. %
  113. % Revision 1.6 1999/04/04 12:20:00 dolzmann
  114. % The counter gb_hzerocount!* works now.
  115. % Fixed a bug in cgp_2scpl: It was possible that the condition becomes
  116. % inconsistent.
  117. %
  118. % Revision 1.5 1999/04/03 13:37:21 sturm
  119. % cgb_groebner1a runs under errorset.
  120. % Adapted to new dip_init/dip_cleanup.
  121. % Bind !*msg during rl_set.
  122. % Replaced cgb_surep and cgb_gsd by correct versions with non-renamed dipoly
  123. % fluids.
  124. %
  125. % Revision 1.4 1999/04/03 11:07:29 dolzmann
  126. % Fixed some bugs.
  127. % The test file runs without Reduce errors.
  128. %
  129. % Revision 1.3 1999/04/03 10:16:16 dolzmann
  130. % Code completely rewritten:
  131. % Introduced splitted polynomials, data types for the Groebner system,
  132. % for branches, and for critical pairs.
  133. % Procedure cgb_groebner1 sets the Redlog context for the condition
  134. % handling.
  135. %
  136. % Revision 1.2 1999/03/31 14:05:22 sturm
  137. % Simple examples run.
  138. % cgb_spolsc is mathematically not correct.
  139. %
  140. % Revision 1.1 1999/03/24 15:10:23 sturm
  141. % Initial check-in. Copy of gb.red 1.16.
  142. %
  143. % ----------------------------------------------------------------------
  144. lisp <<
  145. fluid '(cgb_rcsid!* cgb_copyright!*);
  146. cgb_rcsid!* := "$Id: cgb.red,v 1.30 2004/05/03 16:38:25 sturm Exp $";
  147. cgb_copyright!* := "Copyright (c) 1999-2003 by A. Dolzmann and T. Sturm"
  148. >>;
  149. % TODO:
  150. % - Normalize green groebner systems: Detect branches containing a unit
  151. % - Detect green monomials in RP
  152. % - Final simplification with groebner simplifier
  153. % - Computing reduced or pseudo reduced groeber systems.
  154. % - Computing relatively generic and local groebner systems.
  155. module cgb;
  156. create!-package('(cgb gb dp gbsc),nil);
  157. load!-package 'ezgcd;
  158. if 'psl member lispsystem!* then
  159. if filestatus("$reduce/lisp/psl/$MACHINE/red/redlog.b",nil) then
  160. load!-package 'redlog;
  161. if 'csl member lispsystem!* then
  162. if modulep 'redlog then
  163. load!-package 'redlog;
  164. switch cgbstat,cgbfullred,cgbverbose,cgbcontred,cgbgs,cgbreal,cgbgen,
  165. cgbsgreen;
  166. fluid '(!*cgbstat !*cgbfullred !*cgbverbose !*cgbcontred !*cgbgs !*cgbreal
  167. !*cgbgen !*cgbsloppy !*cgbcdsimpl);
  168. off1 'cgbstat;
  169. on1 'cgbfullred;
  170. off1 'cgbverbose;
  171. off1 'cgbcontred;
  172. off1 'cgbgs;
  173. off1 'cgbreal;
  174. off1 'cgbgen;
  175. off1 'cgbsgreen; % Simulate green. Compute Gsys and colore it green
  176. !*cgbsloppy := T;
  177. !*cgbcdsimpl := T;
  178. fluid '(!*cgbgreen); % pseudo switch for computing green Gsys'
  179. fluid '(!*gcd !*ezgcd !*factor !*exp dmode!* !*msg !*backtrace);
  180. fluid '(cgp_pcount!* cgb_hashsize!*);
  181. cgb_hashsize!* := 65521; % The size of the hash table for BETA (in gbsc).
  182. fluid '(cgb_hcount!* cgb_hzerocount!* cgb_tr1count!* cgb_tr2count!*
  183. cgb_tr3count!* cgb_b4count!* cgb_strangecount!* cgb_paircount!*
  184. cgb_gcount!* cgb_gbcount!*);
  185. fluid '(cgb_cd!* cgb_mincontred!* cgb_contcount!*);
  186. cgb_mincontred!* := 20; % originally 10
  187. fluid '(!*rlgsvb !*rlspgs !*rlsithok);
  188. %DS
  189. % <AMCGB> ::= <AMPSYS>
  190. % <AMPSYS> ::= ('list,...,<Lisp-prefix-form>,...)
  191. % <AMGSYS> ::= ('list,...,<AMBRANCH>,...)
  192. % <AMBRANCH> ::= ('list,<RL-Formula>,<AMPSYS>)
  193. % <FPSYS> ::= (...,<SF>,...)
  194. % <FGSYS> ::= (...,<FBRANCH>,...)
  195. % <FBRANCH> ::= (<CDLIST>,<FPSYS>)
  196. % <CDLIST> ::= (...,<RL_Formula>,...)
  197. macro procedure cgb_mkinterface(argl);
  198. begin
  199. scalar a2sl1,a2sl2,defl,xvfn,s2a,s2s,s,
  200. args,bname,len,sm,prgn,ami,smi,psval,postfix,modes;
  201. bname := eval nth(argl,2);
  202. a2sl1 := eval nth(argl,3);
  203. a2sl2 := eval nth(argl,4);
  204. defl := eval nth(argl,5);
  205. xvfn := eval nth(argl,6);
  206. s2a := eval nth(argl,7);
  207. s2s := eval nth(argl,8);
  208. s := eval nth(argl,9);
  209. postfix := eval nth(argl,10);
  210. modes := eval nth(argl,11);
  211. len := length a2sl1;
  212. args := for i := 1:len+3 collect mkid('a,i);
  213. if (null modes or modes eq 'sm) then <<
  214. sm := intern compress append('(!c !g !b !_),explode bname);
  215. % Define the symbolic mode interface
  216. smi := intern compress nconc(explode sm,explode postfix);
  217. prgn := {'put,mkquote smi,''number!-of!-args,len+3} . prgn;
  218. prgn := {'de,smi,args,{'cgb_interface!$,mkquote sm, mkquote a2sl1,
  219. mkquote a2sl2,mkquote defl,mkquote xvfn,mkquote
  220. s2a,mkquote s2s,mkquote s,T,'list . args}} . prgn
  221. >>;
  222. if (null modes or modes eq 'am) then <<
  223. % Define the algebraic mode interface
  224. ami := bname;
  225. % ami := intern compress append('(!g !b),explode bname);
  226. psval := intern compress nconc(explode ami,'(!! !$));
  227. prgn := {'put,mkquote ami,''psopfn,mkquote psval} . prgn;
  228. prgn := {'put,mkquote psval,''number!-of!-args,1} . prgn;
  229. prgn := {'put,mkquote psval,''cleanupfn,''cgb_cleanup} . prgn;
  230. prgn := {'de,psval,'(argl),{'cgb_interface!$,mkquote sm,
  231. mkquote a2sl1,mkquote a2sl2,mkquote defl,mkquote
  232. xvfn,mkquote s2a,mkquote s2s,mkquote s,nil,'argl}} . prgn;
  233. >>;
  234. return 'progn . prgn
  235. end;
  236. cgb_mkinterface('cgb,'(cgb_a2s!-psys),'(cgb_a2s2!-psys),
  237. nil,'cgb_xvars!-psys,'cgb_s2a!-cgb,'cgb_s2s!-cgb,T,'f,nil);
  238. cgb_mkinterface('gsys,'(cgb_a2s!-psys cgb_a2s!-cd cgb_a2s!-varl),
  239. '(cgb_a2s2!-psys cgb_a2s2!-cd cgb_a2s2!-varl),
  240. {'true,'(list)},'cgb_xvars!-psys3,'cgb_s2a!-gsys,'cgb_s2s!-gsys,T,'f,nil);
  241. %cgb_mkinterface('gsys,'(cgb_a2s!-psys cgb_a2s!-cd),
  242. % '(cgb_a2s2!-psys cgb_a2s2!-cd),
  243. % {'true},'cgb_xvars!-psys2,'cgb_s2a!-gsys,'cgb_s2s!-gsys,T,'f,nil);
  244. cgb_mkinterface('ggsys,'(cgb_a2s!-psys cgb_a2s!-cd cgb_a2s!-varl),
  245. '(cgb_a2s2!-psys cgb_a2s2!-cd cgb_a2s2!-varl),
  246. {'true,'(list)},'cgb_xvars!-psys3,'cgb_s2a!-gsys,'cgb_s2s!-gsys,T,'f,nil);
  247. cgb_mkinterface('gsys2cgb,'(cgb_a2s!-gsys),'(cgb_a2s2!-gsys),
  248. nil,'cgb_xvars!-gsys,'cgb_s2a!-cgb,'cgb_s2s!-cgb,T,'f,nil);
  249. put('cgb_cgb,'gb_wrapper,{'gb_gb,'(gb_a2s!-psys),'(gb_a2s2!-psys),
  250. nil,'gb_xvars!-psys,'gb_s2a!-gbx,'gb_s2s!-gb,T});
  251. put('cgb_gsys,'gb_wrapper,{'gb_gbgsys,'(gb_a2s!-psys),'(gb_a2s2!-psys),
  252. nil,'gb_xvars!-psys,'gb_s2a!-gsys,'gb_s2s!-gsys,T});
  253. procedure cgb_a2s!-psys(l);
  254. % Comprehensive Groebner bases algebraic mode to symbolic mode
  255. % polynomial system. [l] is an AMPSYS. Returns an FPSYS.
  256. begin scalar w,resl;
  257. for each j in getrlist reval l do <<
  258. w := numr simp j;
  259. if w and not(w member resl) then
  260. resl := w . resl
  261. >>;
  262. return sort(resl,'ordp)
  263. end;
  264. procedure cgb_a2s2!-psys(fl);
  265. for each x in fl collect cgp_f2cgp x;
  266. procedure cgb_xvars!-psys(l,vl);
  267. cgb_vars(l,vl);
  268. procedure cgb_xvars!-psys2(l,cd,vl);
  269. cgb_vars(l,vl);
  270. procedure cgb_xvars!-psys3(l,cd,xvl,vl);
  271. cgb_vars(l,vl);
  272. procedure cgb_s2a!-cgb(u);
  273. % Comprehensive Groebner bases symbolic mode to algebraic mode CGB.
  274. % [u] is a list of CGP's. Returns an AMPSYS.
  275. 'list . for each x in u collect cgp_2a x;
  276. procedure cgb_s2s!-cgb(l);
  277. cgb_cgb!-sfl l;
  278. procedure cgb_s2a!-gsys(u);
  279. % Comprehensive Groebner bases symbolic mode to algebraic mode
  280. % Groebner system. [u] is a GSY. Returns an AMGSYS.
  281. 'list . for each bra in u collect cgb_s2a!-bra bra;
  282. procedure cgb_s2a!-bra(bra);
  283. % Comprehensive Groebner bases symbolic mode to algebraic mode
  284. % branch. [u] is a BRA. Returns an AMBRANCH.
  285. {'list,rl_mk!*fof rl_smkn('and,bra_cd bra),
  286. 'list . for each x in bra_system bra collect cgp_2a x};
  287. procedure cgb_s2s!-gsys(u);
  288. for each bra in u collect cgb_s2s!-bra bra;
  289. procedure cgb_s2s!-bra(bra);
  290. {bra_cd bra,cgb_s2s!-cgb bra_system bra};
  291. procedure cgb_a2s!-gsys(u);
  292. % Comprehensive Groebner bases algebraic mode to symbolic mode
  293. % Groebner system. [u] is AMGSYS. Returns an FGSYS.
  294. begin scalar sys,w;
  295. sys := getrlist reval u;
  296. return for each bra in sys collect <<
  297. w := getrlist bra;
  298. bra_mk(cd_for2cd rl_simp car w,cgb_a2s!-psys cadr w,nil)
  299. >>
  300. end;
  301. procedure cgb_a2s2!-gsys(sys);
  302. for each bra in sys collect
  303. bra_mk(car bra,cgb_a2s2!-psys cadr bra,nil);
  304. procedure cgb_xvars!-gsys(sys,vl);
  305. begin scalar w;
  306. w := for each bra in sys join
  307. bra_system bra;
  308. return cgb_vars(w,vl)
  309. end;
  310. procedure cgb_a2s!-cd(cd);
  311. cd_for2cd rl_simp reval cd;
  312. procedure cgb_a2s2!-cd(cd);
  313. cd;
  314. procedure cgb_a2s!-varl(varl);
  315. cdr varl;
  316. procedure cgb_a2s2!-varl(varl);
  317. varl;
  318. procedure cgb_cleanup(u,v); % Do not use reval.
  319. u;
  320. procedure cgb_interface!$(fname,a2sl1,a2sl2,defl,xvfn,s2a,s2s,s,smp,argl);
  321. % fname is a function, the name of the procedure to be called;
  322. % [a2sl1] and [as2sl2] are a list of functions, called to be
  323. % transform algebraic arguments to symbolic arguments; [defl] is a
  324. % list of algebraic defualt arguments; xvfn is a procedure for
  325. % extracting the variables from all arguments; [s2a] is procedure
  326. % for transforming the symbolic return value to an algebraic mode
  327. % return value; [argl] is the list of arguments; [s] is a flag;
  328. % [smp] is a flag. Return an S-expr. If [s] is on then second stage
  329. % of argument processing is done with the results of the first one.
  330. begin scalar w,vl,nargl,oenv,ocdenv,m,c,x;
  331. ocdenv := cd_init(); % early setup for a2s procedures...
  332. if not smp then <<
  333. nargl := cgb_am!-pargl(fname,a2sl1,argl,defl);
  334. vl := apply(xvfn,append(nargl,{td_vars()}));
  335. if null cdr vl and (w:=get(fname,'gb_wrapper)) then <<
  336. cd_cleanup ocdenv;
  337. return apply('gb_interface!$,append(w,{smp,argl}))
  338. >>;
  339. oenv := cgp_init(car vl,td_sortmode(),td_sortextension());
  340. >> else <<
  341. w := cgb_sm!-pargl argl;
  342. nargl := car w;
  343. m := cadr w;
  344. c := caddr w;
  345. x := cadddr w;
  346. vl := apply(xvfn,append(nargl,{m}));
  347. if null cdr vl and (w:=get(fname,'gb_wrapper)) then <<
  348. cd_cleanup ocdenv;
  349. return apply('gb_interface!$,append(w,{smp,argl}))
  350. >>;
  351. oenv := cgp_init(car vl,c,x);
  352. >>;
  353. w := errorset({'cgb_interface1!$,
  354. mkquote fname,mkquote a2sl2,mkquote s2a,mkquote s2s,mkquote s,
  355. mkquote smp,mkquote argl, mkquote nargl,mkquote car vl,
  356. mkquote cdr vl},T,!*backtrace);
  357. cd_cleanup ocdenv;
  358. cgp_cleanup oenv;
  359. if errorp w then
  360. rederr {"Error during ",fname};
  361. return car w
  362. end;
  363. procedure cgb_sm!-pargl(argl);
  364. begin scalar nargl,m,c,x;
  365. nargl := reverse argl;
  366. x := car nargl;
  367. nargl := cdr nargl;
  368. c := car nargl;
  369. nargl := cdr nargl;
  370. m := car nargl;
  371. nargl := cdr nargl;
  372. nargl := reversip nargl;
  373. return {nargl,m,c,x}
  374. end;
  375. procedure cgb_am!-pargl(fname,a2sl1,argl,defl);
  376. % process argument list for algebraic mode.
  377. begin integer l1,l2,l3,noa,da; scalar w,nargl,scargl,scdefl;
  378. l1 := length argl;
  379. l2 := length a2sl1;
  380. l3 := l2 - length defl;
  381. if l1 < l3 or l1 > l2 then
  382. rederr {fname,"called with",l1,"arguments instead of",l3,"-",l2};
  383. scargl := argl;
  384. scdefl := defl;
  385. da := l2 - length defl;
  386. noa := 1;
  387. nargl := for each x in a2sl1 collect <<
  388. if scargl then <<
  389. w := car scargl;
  390. scargl := cdr scargl
  391. >> else <<
  392. w := car scdefl;
  393. >>;
  394. if noa>da then
  395. scdefl := cdr scdefl;
  396. noa := noa+1;
  397. apply(x,{w})
  398. >>;
  399. return nargl
  400. end;
  401. procedure cgb_interface1!$(fname,a2sl2,s2a,s2s,s,smp,argl,nargl,m,p);
  402. begin scalar w,pl;
  403. pl := if s then nargl else argl;
  404. argl := for each x in a2sl2 collect <<
  405. w := car pl;
  406. pl := cdr pl;
  407. apply(x,{w})
  408. >>;
  409. % w := apply(fname,nconc(argl,{m,p}));
  410. w := apply(fname,argl);
  411. w := if smp then
  412. apply(s2s,{w})
  413. else
  414. apply(s2a,{w});
  415. return w
  416. end;
  417. procedure cgb_greengsysf(u,m,sm,sx,theo,xvarl);
  418. cgb_ggsysf(u,m,sm,sx,theo,xvarl);
  419. procedure cgb_gsys2green(u,theo);
  420. % Comprehensive Groebner bases Groebner system to gree Groebner
  421. % system. [u] is a GSY; [theo] is a CD. Returns a GSY, in which
  422. % all polynomials are colored green, i.e., the green colore head
  423. % part is deleted.
  424. for each bra in u collect
  425. bra_mk(bra_cd bra,cgb_cgpl2green(bra_system bra,append(theo,bra_cd bra)),
  426. bra_cprl bra);
  427. procedure cgb_cgpl2green(l,theo); % TODO: delete green monomials in RP.
  428. % Comprehensive Groebner bases CGP list 2 green CGP list. [l] is a
  429. % list of CGP's; [theo] is a CD. Returns a list of CGP's. All CGP's
  430. % in the returned list are colred green, i.e., the green colored
  431. % head part is deleted.
  432. for each cgp in l collect
  433. cgp_green cgp;
  434. procedure cgb_domainchk();
  435. % Comprehensive Groebner bases domain check. No argument. Return
  436. % value not defined. Raises an error if the current domain is not
  437. % valid for CGB computations.
  438. if not memq(dmode!*,'(nil)) then
  439. rederr bldmsg("cgb does not support domain: %w",get(dmode!*,'dname));
  440. procedure cgb_vars(l,vl);
  441. % Comprehensive Groebner bases variables. [l] is a list of SF's;
  442. % [vl] is the list of main variables. Returns a pair $(m . p)$
  443. % where $m$ and $p$ are list of variables. $m$ is the list of used
  444. % main variables and $p$ is the list of used parameters.
  445. begin scalar w,m,p;
  446. for each f in l do
  447. w := union(w,kernels f);
  448. if vl then <<
  449. m := cgb_intersection(vl,w);
  450. p := setdiff(w,vl)
  451. >> else
  452. m := w;
  453. return m . p
  454. end;
  455. procedure cgb_varsgsys(gsys,vl);
  456. % Comprehensive Groebner bases variables in a Groebner system.
  457. % [gsys] is FGSYS; [vl] is the list of main variables . Returns a
  458. % pair $(m . p)$ where $m$ and $p$ are list of variables. $m$ is
  459. % the list of used main variables and $p$ is the list of used
  460. % parameters.
  461. begin scalar w,m,p;
  462. for each bra in gsys do
  463. for each f in bra_system bra do
  464. w := union(w,kernels f);
  465. m := cgb_intersection(vl,w);
  466. p := setdiff(w,vl);
  467. return m . p
  468. end;
  469. procedure cgb_intersection(a,b);
  470. % Comprehensive Groebner bases intersection. [a] and [b] are lists.
  471. % Returns a list. The returned list contains all elements occuring
  472. % in [a] and in [b]. The order of the elements is the same as in
  473. % [a].
  474. for each x in a join
  475. if x member b then
  476. {x};
  477. procedure cgb_cgb(u);
  478. % Comprehensive Groebner bases CGB computation. [u] is a list of
  479. % CGP's. Returns a list of CGP's.
  480. cgb_gsys2cgb cgb_gsys(u,nil,nil);
  481. procedure cgb_gsys2cgb(u);
  482. % Comprehensive Groebner bases CGB to Groebner system conversion.
  483. % [u] is a GSY. Returns a list of CGP's.
  484. begin scalar cgbase;
  485. for each bra in u do
  486. for each p in bra_system bra do
  487. if not (p member cgbase) then % TODO: cgp_member?
  488. cgbase := p . cgbase;
  489. return cgp_lsort cgbase
  490. end;
  491. procedure cgb_cgb!-sfl(u);
  492. % Comprehensive Groebner bases CGB to SF list. [u] is a list of
  493. % CGP's. Returns a list of SF's.
  494. for each p in u collect cgp_2f p;
  495. smacro procedure cgb_tt(s1,s2);
  496. % Comprehensive Groebner bases tt. [s1] and [s2] are CGP's. Returns
  497. % an EV, the lcm of the leading terms of [s1] and [s2].
  498. ev_lcm(cgp_evlmon s1,cgp_evlmon s2);
  499. procedure cgb_gsys(u,theo,xvarl);
  500. % Comprehensive Groebner bases Groebner system computation. [u] is
  501. % a list of CGP's; [theo] is the inital theory. Returns a GSY, the
  502. % Groebner system of [u].
  503. gsy_normalize cgb_gsys1(cgp_lsort u,theo,xvarl);
  504. procedure cgb_ggsys(u,theo,xvarl);
  505. % Comprehensive Groebner bases green Groebner system computation.
  506. % [u] is a list of CGP's; [theo] is the initial theory. Returns a
  507. % GSY, the green Groebner system of [u].
  508. begin scalar w,!*cgbgreen,sgreen;
  509. if !*cgbsgreen then
  510. return gsy_normalize
  511. cgb_gsys2green(cgb_gsys1(cgp_lsort u,theo,xvarl),theo);
  512. sgreen := !*cgbgreen;
  513. !*cgbgreen := T;
  514. w := cgb_gsys(u,theo,xvarl);
  515. !*cgbgreen := sgreen;
  516. return w
  517. end;
  518. procedure cgb_gsys1(u,theo,xvarl);
  519. % Comprehensive Groebner bases Groebner system computation
  520. % subroutine. [u] is a list of CGP's; [theo] is the initaila
  521. % theory. Returns a GSY, the Groebner system of [u].
  522. begin
  523. scalar spac,stime,p1,!*factor,!*exp,!*gcd,!*ezgcd,cgb_cd!*,!*cgbverbose;
  524. integer cgp_pcount!*,cgb_contcount!*,cgb_hcount!*,cgb_hzerocount!*,
  525. cgb_tr1count!*,cgb_tr2count!*,cgb_tr3count!*,cgb_b4count!*,
  526. cgb_strangecount!*,cgb_paircount!*,cgb_gbcount!*,cgb_contcount!*;
  527. !*exp := !*gcd := !*ezgcd := t;
  528. cgb_contcount!* := cgb_mincontred!*;
  529. if !*cgbstat then <<
  530. spac := gctime();
  531. stime := time()
  532. >>;
  533. p1 := cgb_traverso(u,theo,xvarl);
  534. if !*cgbstat then <<
  535. ioto_tprin2t "Statistics for GB computation:";
  536. ioto_prin2t {"Time: ",time() - stime," ms plus GC time: ",
  537. gctime() - spac," ms"};
  538. ioto_prin2t {"H-polynomials total: ",cgb_hcount!*};
  539. ioto_prin2t {"H-polynomials zero: ",cgb_hzerocount!*};
  540. ioto_prin2t {"Crit Tr1 hits: ",cgb_tr1count!*};
  541. ioto_prin2t {"Crit B4 hits: ",cgb_b4count!*," (Buchberger 1)"};
  542. ioto_prin2t {"Crit Tr2 hits: ",cgb_tr2count!*};
  543. ioto_prin2t {"Crit Tr3 hits: ",cgb_tr3count!*};
  544. % ioto_prin2t {"Strange reductions: ",cgb_strangecount!*}
  545. >>;
  546. return p1
  547. end;
  548. procedure cgb_traverso(g0,theo,xvars);
  549. % Comprehensive Groebner bases Traverso. [g0] is a list of CGP's;
  550. % [theo] is a initial theory. Returns a GSY of [g0].
  551. begin scalar bra,gsys,resl,bral;
  552. g0 := for each fj in g0 collect
  553. cgp_simpdcont fj;
  554. gsys := gsy_init(g0,theo,xvars);
  555. while gsys do <<
  556. bra := car gsys;
  557. gsys := cdr gsys;
  558. if bra_cprl bra eq 'final or null bra_cprl bra then
  559. resl := bra . resl
  560. else <<
  561. bral := cgb_traverso1(bra,xvars);
  562. gsys := nconc(bral,gsys)
  563. >>
  564. >>;
  565. return resl % TODO: reduction
  566. end;
  567. procedure cgb_traverso1(bra,xvars);
  568. % Comprehensive Groebner bases Traverso subroutine. [bra] is a BRA.
  569. % Returns a GSY. Performs one step in the computation of a GSY.
  570. begin scalar g,d,s,h,p;
  571. cgb_cd!* := bra_cd bra;
  572. g := bra_system bra;
  573. d := bra_cprl bra;
  574. if !*cgbverbose then <<
  575. ioto_prin2 {"[",cgb_paircount!*,"] "};
  576. cgb_paircount!* := cgb_paircount!* #- 1
  577. >>;
  578. p := car d;
  579. d := cdr d;
  580. s := cgb_spolynomial p;
  581. h := cgb_normalform(s,g,xvars);
  582. h := cgp_simpdcont h;
  583. if !*cgbstat then
  584. cgb_hcount!* := cgb_hcount!* #+ 1;
  585. if cgp_zerop h then
  586. cgb_hzerocount!* := cgb_hzerocount!* #+ 1;
  587. return bra_split(bra_mk(cgb_cd!*,g,d),h,xvars)
  588. end;
  589. procedure cgb_spolynomial(pr);
  590. % Comprehensive Groebner bases S-polynomial. [pr] is a CPR. Returns
  591. % a CGP the S-polynomial of [pr] possibly reduced wrt. the
  592. % polynomials in [pr].
  593. begin scalar s;
  594. s := cgb_spolynomial1 pr; % TODO: updcondition
  595. return s; % TODO: Strange reduction
  596. end;
  597. procedure cgb_spolynomial1(pr);
  598. % Comprehensive Groebner bases S-polynomial subroutine. [pr] is a
  599. % CPR. Returns a CGP. the S-polynomial of [pr].
  600. begin scalar p1,p2,ep,ep1,ep2,rp1,rp2,db1,db2,x,spol;
  601. p1 := cpr_p1 pr;
  602. p2 := cpr_p2 pr;
  603. ep := cpr_lcm pr;
  604. ep1 := cgp_evlmon p1;
  605. ep2 := cgp_evlmon p2;
  606. rp1 := cgp_mred p1;
  607. rp2 := cgp_mred p2;
  608. if cgp_greenp rp1 and cgp_greenp rp2 then
  609. return cgp_zero();
  610. db1 := cgp_lbc p1;
  611. db2 := cgp_lbc p2;
  612. x := bc_gcd(db1,db2);
  613. db1 := bc_quot(db1,x);
  614. db2 := bc_quot(db2,x);
  615. spol := cgp_ilcomb(rp1,db2,ev_dif(ep,ep1),rp2,bc_neg db1,ev_dif(ep,ep2));
  616. if cgp_greenp spol then
  617. return cgp_zero();
  618. return spol
  619. end;
  620. procedure cgb_normalform(f,g,xvars);
  621. % Comprehensive Groebner bases normal form computation. [f] is a
  622. % CGP; [g] is a list of CGP's with red HT's. Returns a CGP $p$.
  623. % Depends on switch [!*cgbfullred]. $p$ is computed by
  624. % reducing [f] with polynomials in [g].
  625. begin scalar fold,c,tai,divisor;
  626. if null g then
  627. return f;
  628. if cgp_greenp f then
  629. return cgp_zero();
  630. fold := f;
  631. f := cgp_hpcp f;
  632. f := cgp_shift(f,xvars);
  633. c := T; while c and cgp_rp f do <<
  634. divisor := cgb_searchinlist(cgp_evlmon f,g);
  635. if divisor then <<
  636. tai := T;
  637. f := cgb_reduce(f,divisor)
  638. >> else if !*cgbfullred then
  639. f := cgp_shiftwhite f
  640. else
  641. c := nil;
  642. if c then
  643. f := cgp_shift(f,xvars)
  644. >>;
  645. if not tai then
  646. return fold;
  647. return cgp_backshift f % TODO: updccondition
  648. end;
  649. procedure cgb_searchinlist(vev,g);
  650. % Comprehensive Groebner bases search for a polynomial in a list.
  651. % [vev] is a EV; [g] is a CGP. Returns a CGP $p$, such that the RP
  652. % of [g] is reducible wrt. $p$.
  653. if null g then
  654. nil
  655. else if cgb_buch!-ev_divides!?(cgp_evlmon car g,vev) then
  656. car g
  657. else
  658. cgb_searchinlist(vev,cdr g);
  659. procedure cgb_buch!-ev_divides!?(vev1,vev2);
  660. % Comprehensive Groebner bases Buchberger exponent vector divides.
  661. % [vev1] and [vev2] are EV's. Returns non-[nil] if [vev1] divides
  662. % [vev2].
  663. ev_mtest!?(vev2,vev1);
  664. procedure cgb_reduce(f,g1);
  665. % Comprehensive Groebner bases reduce. [f] is a CGP; [g1] is a CGP,
  666. % such that the RP of [f] is reducible wrt. [g1]. Returns a CGP
  667. % $p$. $p$ is computed by reducing [f] with [g1].
  668. if cgp_monp g1 then
  669. cgp_cancelmev(cgp_bcprod(f,cgp_lbc g1),cgp_evlmon g1) % TODO: numberp
  670. else
  671. cgb_reduceonestep(f,g1); % TODO: Content reduction
  672. procedure cgb_reduceonestep(f,g);
  673. % Comprehensive Groebner bases reduce one step. [f] is a CGP; [g]
  674. % is a CGP, such that the RP of [f] is top-reducible wrt. [g].
  675. % Returns a CGP $p$. $p$ is computed by performing one
  676. % top-reduction.
  677. begin scalar cot,hcf,hcg,x,a,b;
  678. cot := ev_dif(cgp_evlmon f,cgp_evlmon g);
  679. hcf := cgp_lbc f;
  680. hcg := cgp_lbc g;
  681. x := bc_gcd(hcf,hcg);
  682. a := bc_quot(hcg,x);
  683. b := bc_quot(hcf,x);
  684. return cgp_setci(cgp_ilcombr(f,a,g,bc_neg b,cot),cgp_ci f)
  685. end; % TODO: updccondition
  686. endmodule; % cgb;
  687. module cd;
  688. % Conditions.
  689. % DS
  690. % <CD> ::= (...,<Atomic Formula>,...)
  691. procedure cd_init();
  692. % Condition init. No argument. Return value describes the current
  693. % context. Depends on switch [!*cgbreal]. Sets up the environment
  694. % for handling conditions in the choosen context.
  695. (if !*cgbreal then rl_set '(ofsf) else rl_set '(acfsf)) where !*msg=nil;
  696. procedure cd_cleanup(oc);
  697. % Condition clean-up. [oc] decsribes the context wich should be
  698. % selected. Return value unspecified.
  699. rl_set oc where !*msg=nil;
  700. procedure cd_falsep(cd);
  701. % Condion false predicate. [cd] is a CD. Returns bool. If [t] is
  702. % retunred then the condion [cd] is inconsistent.
  703. eqcar(cd,'false);
  704. procedure cd_siadd(atl,sicd);
  705. % Condion simplify add. [atl] is a list of atomic formulas; [sicd]
  706. % is a CD. Returns a CD, the union of [cd] and [atl].
  707. begin scalar w;
  708. if not !*cgbcdsimpl then
  709. return nconc(atl,sicd);
  710. w := if !*cgbgs then
  711. cd_gsd(rl_smkn('and,nconc(atl,sicd)),nil)
  712. else
  713. rl_siaddatl(atl,rl_smkn('and,sicd));
  714. return cd_for2cd w
  715. end;
  716. procedure cd_for2cd(f);
  717. % Condition formula to condition. [f] is either ['false] , ['true],
  718. % or a conjunction of atomic formulas. Returns a CD equivalent to
  719. % [f]. Formula to condition.
  720. if f eq 'true then
  721. nil
  722. else if f eq 'false then
  723. '(false)
  724. else if cl_cxfp f then
  725. rl_argn f
  726. else
  727. {f};
  728. procedure cd_surep(f,cd);
  729. % Condition sure predicate. [f] is an atomic formuls; [cd] is a CD.
  730. % If [T] is returned, then [cd] implies [f].
  731. begin scalar !*rlgsvb;
  732. return rl_surep(f,cd) where !*rlspgs=!*cgbgs,!*rlsithok=T;
  733. end;
  734. procedure cd_gsd(f,cd);
  735. % Condition Groebner simplifier. [f] is a formula; [cd] is a
  736. % condition. Simplies [f] wrt. the theory [cd].
  737. begin scalar !*rlgsvb;
  738. return rl_gsd(f,cd)
  739. end;
  740. procedure cd_ordp(cd1,cd2);
  741. % Condition order predicate. [cd1] and [cd2] are conditions sorted
  742. % wrt. ['cd_ordatp]. Returns bool.
  743. if null cd1 then
  744. T
  745. else if null cd2 then
  746. nil
  747. else if car cd1 neq car cd2 then
  748. cd_ordatp(car cd1,car cd2)
  749. else
  750. cd_ordp(cdr cd1,cdr cd2);
  751. procedure cd_ordatp(a1,a2);
  752. % Condition order atomic formula predicate. [a1] and [a2] are
  753. % atomic formulas. Returns bool.
  754. if car a1 eq 'neq and car a2 eq 'equal then
  755. T
  756. else if car a1 eq 'equal and car a2 eq 'neq then
  757. nil
  758. else
  759. ordp(cadr a1,cadr a2);
  760. endmodule; % cd
  761. module cpr;
  762. % Critical pairs.
  763. %DS
  764. % <CPRL> ::= (...,<CPR>,...)
  765. % <CPR> ::= (<LCM>,<P1>,<P2>,<SUGAR>);
  766. procedure cpr_mk(f,h);
  767. % Critical pair make. [f], and [h] are CGP's. Returns a CPR.
  768. % Construct a pair from polynomials [f] and [h].
  769. begin scalar ttt,sf,sh;
  770. ttt := cgb_tt(f,h);
  771. sf := cgp_sugar(f) #+ ev_tdeg ev_dif(ttt,cgp_evlmon f);
  772. sh := cgp_sugar(h) #+ ev_tdeg ev_dif(ttt,cgp_evlmon h);
  773. return cpr_mk1(ttt,f,h,ev_max!#(sf,sh))
  774. end;
  775. procedure cpr_mk1(lcm,p1,p2,sugar);
  776. % Critical pair make subroutine. [lcm] is an EV, the lcm of [evlmon
  777. % p1] and [evlmon p2]; [p1] and [p2] are CGP's with red HC; [sugar]
  778. % is a machine integer, the sugar of the S-polynomials of [p1] and
  779. % [p2]. Returns a CPR.
  780. {lcm,p1,p2,sugar};
  781. procedure cpr_lcm(cpr);
  782. % Critical pair lcm. [cpr] is a critical pair. Returns the lcm part
  783. % of [cpr].
  784. car cpr;
  785. procedure cpr_p1(cpr);
  786. % Critical pair p1. [cpr] is a critical pair. Returns the p1 part
  787. % of [cpr].
  788. cadr cpr;
  789. procedure cpr_p2(cpr);
  790. % Critical pair p2. [cpr] is a critical pair. Returns the p2 part
  791. % of [cpr].
  792. caddr cpr;
  793. procedure cpr_sugar(cpr);
  794. % Critical pair suger. [cpr] is a critical pair. Returns the sugar
  795. % part of [cpr].
  796. cadddr cpr;
  797. procedure cpr_traverso!-pairlist(gk,g,d);
  798. % Critical pair Travero pair list. [gk] is a CGP with red HT; [g]
  799. % is a list of CGP's with red HT's; [d] is a sorted list of CPR's.
  800. % Returns a sorted list of CPR's the result of updating [w] with
  801. % critical pairs construction by combining [gk] with polynomials in
  802. % [g].
  803. begin scalar ev,r,n;
  804. d := cpr_traverso!-pairs!-discard1(gk,d);
  805. % build new pair list:
  806. ev := cgp_evlmon gk;
  807. for each p in g do
  808. if not cpr_buchcrit4t(ev,cgp_evlmon p) then <<
  809. if !*cgbstat then
  810. cgb_b4count!* := cgb_b4count!* #+ 1;
  811. r := ev_lcm(ev,cgp_evlmon p) . r
  812. >> else
  813. n := cpr_mk(p,gk) . n;
  814. n := cpr_tr2crit(n,r);
  815. n := cpr_listsort(n,!*cgbsloppy);
  816. n := cpr_tr3crit n;
  817. if !*cgbverbose and n then <<
  818. cgb_paircount!* := cgb_paircount!* #+ length n;
  819. ioto_cterpri();
  820. ioto_prin2 {"(",cgb_gbcount!*,") "}
  821. >>;
  822. return cpr_listmerge(d,reversip n)
  823. end;
  824. procedure cpr_tr2crit(n,r);
  825. % Critical pair Travero 2 criterion. [n] is a list of CPR's; [r] is
  826. % a list of EV's. Returns a list of CPR's. Delete equivalents to
  827. % coprime lcm
  828. for each p in n join
  829. if ev_member(cpr_lcm p,r) then <<
  830. if !*cgbstat then
  831. cgb_tr2count!* := cgb_tr2count!* #+ 1;
  832. nil
  833. >> else
  834. {p};
  835. procedure cpr_tr3crit(n);
  836. % Critical pair Travero 3 criterion. [n] is a sorted list of CPR's;
  837. % [r] is a list of EV's. Returns a sorted list of CPR's.
  838. begin scalar newn,scannewn,q;
  839. for each p in n do <<
  840. scannewn := newn;
  841. q := nil;
  842. while scannewn do
  843. if ev_divides!?(cpr_lcm car scannewn,cpr_lcm p) then <<
  844. q := t;
  845. scannewn := nil;
  846. if !*cgbstat then
  847. cgb_tr3count!* := cgb_tr3count!* #+ 1
  848. >> else
  849. scannewn := cdr scannewn;
  850. if not q then
  851. newn := cpr_listsortin(p,newn,nil)
  852. >>;
  853. return newn
  854. end;
  855. procedure cpr_traverso!-pairs!-discard1(gk,d);
  856. % Critical pairs Traverso pairs discard 1. [gk] is a CGP with red
  857. % HT; [d] is a sorted list of CPR's. Returns a list of [cpr]'s.
  858. % Criterion B. Delete triange relations.
  859. for each pij in d join
  860. if cpr_traverso!-trianglep(cpr_p1 pij,cpr_p2 pij,gk,cpr_lcm pij) then <<
  861. if !*cgbstat then
  862. cgb_tr1count!* := cgb_tr1count!* #+ 1;
  863. if !*cgbverbose then
  864. cgb_paircount!* := cgb_paircount!* #- 1;
  865. nil
  866. >> else
  867. {pij};
  868. procedure cpr_traverso!-trianglep(gi,gj,gk,tij);
  869. % Critical pairs Traverso triangle predicate. [gi], [gj], and [gk]
  870. % are CGP's with red HT; [tij] is an EV.
  871. ev_sdivp(cgb_tt(gi,gk),tij) and ev_sdivp(cgb_tt(gj,gk),tij);
  872. procedure cpr_buchcrit4t(e1,e2);
  873. % Critical pair Buchbergers criterion 4. [e1], [e2] are EV's.
  874. % Returns [T] if [e1] and [e2] are disjoint.
  875. not ev_disjointp(e1,e2);
  876. procedure cpr_listsort(g,sloppy);
  877. % Critical pair list sort. [g] is a list of CPR's, [sloppy] is
  878. % bool. Returns a list of CPR'S. Destructively sorts [g]
  879. begin scalar gg;
  880. for each p in g do
  881. gg := cpr_listsortin(p,gg,sloppy);
  882. return gg
  883. end;
  884. procedure cpr_listsortin(p,pl,sloppy);
  885. % Critical pair list sort into. [p] is a CPR; [pl] is a sorted list
  886. % of CPR's, [sloppy] is bool. Destructively sorts [p] into [pl].
  887. if null pl then
  888. {p}
  889. else <<
  890. cpr_listsortin1(p,pl,sloppy);
  891. pl
  892. >>;
  893. procedure cpr_listsortin1(p,pl,sloppy);
  894. % Critical pair list sort into. [p] is a CPR; [pl] is a non-empty,
  895. % sorted list of CPR's; [sloppy] is bool. Destructively sorts [p]
  896. % into [pl].
  897. if not cpr_lessp(car pl,p,sloppy) then <<
  898. rplacd(pl,car pl . cdr pl);
  899. rplaca(pl,p)
  900. >> else if null cdr pl then
  901. rplacd(pl,{p})
  902. else
  903. cpr_listsortin1(p,cdr pl,sloppy);
  904. procedure cpr_lessp(pr1,pr2,sloppy);
  905. % Critical pair less predicate. [p1] and [p2] are CPR's; [sloppy]
  906. % is bool. Returns [T] is [p1] is less than [p2]. Compare 2 pairs
  907. % wrt. their sugar or their lcm.
  908. if sloppy then
  909. ev_compless!?(cpr_lcm pr1,cpr_lcm pr2)
  910. else
  911. cpr_lessp1(pr1,pr2,cpr_sugar pr1 #- cpr_sugar pr2,
  912. ev_comp(cpr_lcm pr1,cpr_lcm pr2));
  913. procedure cpr_lessp1(pr1,pr2,d,q);
  914. % Critical pair less predicate subroutine. [p1] and [p2] are CPR's.
  915. % Returns [T] is [p1] is less than [p2]. Compare 2 pairs wrt. their
  916. % sugar or their lcm.
  917. if not(d #= 0) then
  918. d #< 0
  919. else if not(q #= 0) then
  920. q #< 0
  921. else
  922. cgp_number cpr_p2 pr1 #< cgp_number cpr_p2 pr2;
  923. procedure cpr_listmerge(pl1,pl2); % TODO: Rekursiv, konstruktiv !!!
  924. % Critical pair list merge. [pl1] and [pl2] are sorted list of
  925. % CPR's. Returns a sorted list of CPR's the restult of merging the
  926. % lists [pl1] and [pl2].
  927. begin scalar cpl1,cpl2;
  928. if null pl1 then
  929. return pl2;
  930. if null pl2 then
  931. return pl1;
  932. cpl1 := car pl1;
  933. cpl2 := car pl2;
  934. return if cpr_lessp(cpl1,cpl2,nil) then
  935. cpl1 . cpr_listmerge(cdr pl1,pl2)
  936. else
  937. cpl2 . cpr_listmerge(pl1,cdr pl2)
  938. end;
  939. endmodule; % cpr
  940. module bra;
  941. %DS
  942. % <BRA> ::= (<CD>,<SYSTEM>,<CPRL>)
  943. procedure bra_cd(br);
  944. % Branch condition. [br] is a BRA. Returns a CD, the condition part
  945. % of [br].
  946. car br;
  947. procedure bra_system(br);
  948. % Branch system. [br] is a BRA. Returns a list of CGP's, the
  949. % system part of [br].
  950. cadr br;
  951. procedure bra_cprl(br);
  952. % Branch critical pair list. [br] is a BRA. Returns a list of
  953. % CPR's, the pairs part of [br].
  954. caddr br;
  955. procedure bra_mk(cd,system,cprl);
  956. % Branch make. [cd] is a CD; [system] is a list of CGP's with red
  957. % HT's; [cprl] is a list of CPR's. Returns a BRA.
  958. {cd,system,cprl};
  959. procedure bra_split(bra,p,xvars);
  960. % Branch split. [bra] is a BRA; [p] is a CGP. Returns a GSY.
  961. if cgp_greenp p then
  962. {bra}
  963. else if bra_cprl bra eq 'final then
  964. {bra}
  965. else
  966. bra_split1(bra,cgp_enumerate cgp_condense p,xvars);
  967. procedure bra_split1(bra,p,xvars);
  968. % Branch split subroutine. [bra] is a BRA; [p] is a CGP. Returns a GSY.
  969. for each pr in cgp_2scpl(p,bra_cd bra,xvars) collect
  970. bra_ext(bra,car pr,cdr pr);
  971. procedure bra_ext(bra,cd,scp);
  972. % Branch extend. [bra] is a BRA; [cd] is a CD; [scp] is CGP with
  973. % red HT. Returns a BRA.
  974. begin scalar sy,d;
  975. if cgp_unitp scp then
  976. return bra_mk(cd,{scp},'final);
  977. sy := for each p in bra_system bra collect cgp_cp p; % TODO: Copy?
  978. d := for each pr in bra_cprl bra collect pr; % TODO: Copy?
  979. if cgp_greenp scp then
  980. return bra_mk(cd,sy,d);
  981. d := cpr_traverso!-pairlist(scp,sy,d);
  982. return bra_mk(cd,nconc(sy,{scp}),d)
  983. end;
  984. procedure bra_ordp(b1,b2);
  985. % Branch order predicate. [b1] and [b2] are branches. Returns bool.
  986. cd_ordp(bra_cd b1,bra_cd b2);
  987. endmodule; % bra
  988. module gsy;
  989. % Groebner system.
  990. %DS
  991. % <GSY> ::= (...,<BRA>,...)
  992. procedure gsy_init(l,theo,xvars);
  993. % Groebner system initialize. [l] is a list of CGP's. Returns a
  994. % GSY. We construct a case distinction wrt. to the parametric
  995. % coefficients in the elements of [l].
  996. begin scalar s;
  997. s := {bra_mk(theo,nil,nil)};
  998. for each x in l do
  999. s := for each y in s join
  1000. bra_split(y,x,xvars);
  1001. return s
  1002. end;
  1003. procedure gsy_normalize(l);
  1004. % Groebner system normalize. [l] is a GSY. Returns a GSY.
  1005. sort(gsy_normalize1 l,'bra_ordp);
  1006. procedure gsy_normalize1(l);
  1007. % Groebner system normalize subroutine. [l] is a GSY. Returns a GSY.
  1008. for each bra in l collect
  1009. bra_mk(sort(bra_cd bra,'cd_ordatp),
  1010. cgp_lsort for each x in bra_system bra collect cgp_normalize x,
  1011. bra_cprl bra);
  1012. endmodule; % gsy
  1013. module cgp;
  1014. % Comprehensive Groebner basis polynomial.
  1015. %DS
  1016. % <CGP> ::= ('cgp,<HP>,<RP>,<SUGAR>,<NUMBER>,<CI>)
  1017. % <HP> ::= <DIP>
  1018. % <RP> ::= <DIP>
  1019. % <SUGAR> ::= <Machine Integer> | nil
  1020. % <NUMBER> ::= <Machine Integer> | nil
  1021. % <CI> ::= 'unknown | 'red | 'green | 'zero | ('mixed . <WTL>) | green_colored
  1022. % <WTL> ::= (...,<EV>,...)
  1023. procedure cgp_mk(hp,rp,sugar,number,ci);
  1024. % CGP make. [hp] and [rp] are DIP's; [sugar] and [number] are
  1025. % machine numbers; [ci] is an S-expr.
  1026. {'cgp,hp,rp,sugar,number,ci};
  1027. procedure cgp_hp(cgp);
  1028. % CGP head polynomial. [cgp] is a CGP. Returns a DIP, the head
  1029. % polynomial part of [cgp].
  1030. cadr cgp;
  1031. procedure cgp_rp(cgp);
  1032. % CGP rest polynomial. [cgp] is a CGP. Returns a DIP, the rest
  1033. % polynomial part of [cgp].
  1034. caddr cgp;
  1035. procedure cgp_sugar(cgp);
  1036. % CGP sugar. [cgp] is a CGP. Returns a machine number, the sugar
  1037. % part of [cgp].
  1038. cadddr cgp;
  1039. procedure cgp_number(cgp);
  1040. % CGP number. [cgp] is a CGP. Returns a machine number, the number
  1041. % part of [cgp].
  1042. nth(cgp,5);
  1043. procedure cgp_ci(cgp);
  1044. % CGP number. [cgp] is a CGP. Returns an S-expr, the coloring %
  1045. % information of [cgp].
  1046. nth(cgp,6);
  1047. procedure cgp_init(vars,sm,sx);
  1048. % CGP init. [vars] is a list of variables. Returns an S-expr.
  1049. % Initializing the DIP package.
  1050. dip_init(vars,sm,sx);
  1051. procedure cgp_cleanup(l);
  1052. % CGP clean-up. [l] is an S-expr returned by calling [cgp_init].
  1053. dip_cleanup(l);
  1054. procedure cgp_lbc(u);
  1055. % CGP leading base coefficient. [u] is a CGP. Returns the HC of the
  1056. % rest part of [u].
  1057. dip_lbc cgp_rp u;
  1058. procedure cgp_evlmon(u);
  1059. % CGP exponent vector of leading monomial. [u] is a CGP. Returns
  1060. % the HT of the rest part of [u].
  1061. dip_evlmon cgp_rp u;
  1062. procedure cgp_zerop(u);
  1063. % CGP zero predicate. [u] is a CGP. Returns [T] if [u] is the zero
  1064. % polynomial.
  1065. null cgp_hp u and null cgp_rp u;
  1066. procedure cgp_greenp(u);
  1067. % CGP green predicate. [u] is a CGP. Returns [T] if [u] is
  1068. % completely green colored.
  1069. null cgp_rp u;
  1070. procedure cgp_monp(u);
  1071. % CGP monomial predicate. [u] is a CGP. Returns [T] if [u] is a monomial.
  1072. null cgp_hp u and dip_monp cgp_rp u;
  1073. procedure cgp_zero();
  1074. % CGP zero. No argument. Returns the zero polynomial.
  1075. cgp_mk(nil,nil,nil,nil,'zero);
  1076. procedure cgp_one();
  1077. % CGP one. No argument. Returns a CGP, the polynomial one in CGP
  1078. % representation.
  1079. cgp_mk(nil,dip_one(),0,nil,'red);
  1080. procedure cgp_tdeg(u);
  1081. % CGP total degree. [u] is a CGP. Returns the total degree of the
  1082. % rest polynomial of [u].
  1083. dip_tdeg cgp_rp u;
  1084. procedure cgp_mred(cgp);
  1085. % CGP monomial reductum. [cgp] is a CGP. Returns a CGP $p$. $p$ is
  1086. % computed from [cgp] by deleting the HM of the rest part of [cgp].
  1087. cgp_mk(cgp_hp cgp,dip_mred cgp_rp cgp,cgp_sugar cgp,nil,'unknown);
  1088. procedure cgp_cp(cgp);
  1089. % CGP copy. [cgp] is a CGP. Returns a CGP, the top-level copy of
  1090. % [cgpl
  1091. cgp_mk(cgp_hp cgp,cgp_rp cgp,cgp_sugar cgp,cgp_number cgp,cgp_ci cgp);
  1092. procedure cgp_f2cgp(u);
  1093. % CGP form to cgp. [u] is a SF. Returns a CGP.
  1094. cgp_mk(nil,dip_f2dip u,nil,nil,'unknown);
  1095. procedure cgp_2a(u);
  1096. % CGP to algebraic. [u] is a CGP. Returns the AM representation of
  1097. % [u].
  1098. dip_2a dip_append(cgp_hp u,cgp_rp u);
  1099. procedure cgp_2f(u);
  1100. % CGP to algebraic. [u] is a CGP. Returns the AM representation of
  1101. % [u].
  1102. dip_2f dip_append(cgp_hp u,cgp_rp u);
  1103. procedure cgp_enumerate(p);
  1104. % CGP enumerate. [p] is a CGP. Returns a CGP. Sets the number of
  1105. % [p] destructively to the next free number.
  1106. cgp_setnumber(p,cgp_pcount!* := cgp_pcount!* #+ 1);
  1107. procedure cgp_unitp(p);
  1108. % CGP unit predicate. [p] is a CGP with red HT. Returns [T] if [p]
  1109. % is a unit.
  1110. cgp_rp p and ev_zero!? cgp_evlmon p;
  1111. procedure cgp_setnumber(p,n);
  1112. % CGP set number. [p] is a CGP; [n] is a machine number. Returns a
  1113. % CGP. Sets the number of [p] destructively to [n].
  1114. <<
  1115. nth(p,5) := n;
  1116. p
  1117. >>;
  1118. procedure cgp_setsugar(p,s);
  1119. % CGP set sugar. [p] is a CGP; [s] is a machine number. Returns a
  1120. % CGP. Sets the sugar of [p] destructively to [s].
  1121. <<
  1122. nth(p,4) := s;
  1123. p
  1124. >>;
  1125. procedure cgp_setci(p,tg);
  1126. % CGP set coloring information. [p] is a CGP; [tg] is an S-expr.
  1127. % Returns a CGP. Sets the coloring information of [p] destructively
  1128. % to [s].
  1129. <<
  1130. nth(p,6) := tg;
  1131. p
  1132. >>;
  1133. procedure cgp_condense(p);
  1134. % CGP condense. [p] is a CGP. Returns a CGP. Condenses both the
  1135. % head and the rest polynomial of [p].
  1136. <<
  1137. dip_condense cgp_hp p;
  1138. dip_condense cgp_rp p;
  1139. p
  1140. >>;
  1141. procedure cgp_2scpl(p,cd,xvars);
  1142. % CGP to strong cpl. [p] is a CGP; [cd] is a CD. Returns a list of
  1143. % pairs $(...,(\gamma . p'),...)$, where $\gamma$ is a condition
  1144. % and $p'$ is a CGP with red HC.
  1145. if !*cgbgen and null xvars then
  1146. cgp_2scpl!-gen(p,cd)
  1147. else
  1148. cgp_2scpl1(p,cd,xvars);
  1149. procedure cgp_2scpl1(p,cd,xvars);
  1150. % CGP to strong cpl subroutine. [p] is a CGP; [cd] is a CD. Returns
  1151. % a list of pairs $(...,(\gamma . p'),...)$, where $\gamma$ is a
  1152. % condition and $p'$ is a CGP with red HC.
  1153. begin scalar hp,rp,s,n,hc,ht,l,ncdeq,ncdneq;
  1154. hp := cgp_hp p;
  1155. if !*cgbgreen and hp then
  1156. rederr {"cgp_2scpl1: Non empty hp",p};
  1157. rp := cgp_rp p;
  1158. s := cgp_sugar p;
  1159. n := cgp_number p;
  1160. while rp do <<
  1161. hc := dip_lbc rp;
  1162. ht := dip_evlmon rp;
  1163. ncdeq := ncdneq := nil;
  1164. if cd_surep(bc_mkat('neq,hc),cd) or
  1165. eqcar(ncdeq := cd_siadd({bc_mkat('equal,hc)},cd),'false)
  1166. then <<
  1167. l := (cd . cgp_mk(hp,rp,s or dip_tdeg rp,n,'red)) . l;
  1168. hc := 'break;
  1169. rp := nil
  1170. >> else if !*cgbgen and null intersection(xvars,bc_vars hc) then <<
  1171. ncdneq := cd_siadd({bc_mkat('neq,hc)},cd);
  1172. l := (ncdneq . cgp_mk(hp,rp,s or dip_tdeg rp,n,'red)) . l;
  1173. hc := 'break;
  1174. rp := nil
  1175. >> else <<
  1176. if not (cd_surep(bc_mkat('equal,hc),cd) or
  1177. eqcar(ncdneq := cd_siadd({bc_mkat('neq,hc)},cd),'false))
  1178. then <<
  1179. ncdneq := ncdneq or cd_siadd({bc_mkat('neq,hc)},cd);
  1180. ncdeq := ncdeq or cd_siadd({bc_mkat('equal,hc)},cd);
  1181. l := (ncdneq . cgp_mk(hp,rp,s or dip_tdeg rp,n,'red)) . l;
  1182. cd := ncdeq;
  1183. >>;
  1184. rp := dip_mred rp;
  1185. if not(!*cgbgreen) then
  1186. hp := dip_appendmon(hp,hc,ht);
  1187. >>
  1188. >>;
  1189. if hc neq 'break then
  1190. l := (cd . cgp_zero()) . l;
  1191. return reversip l
  1192. end;
  1193. procedure cgp_2scpl!-gen(p,cd);
  1194. % CGP to strong cpl generic case. [p] is a CGP; [cd] is a CD. Returns
  1195. % a list of one pair $((\gamma . p'))$, where $\gamma$ is a
  1196. % condition and $p'$ is a CGP with red HC.
  1197. begin scalar hp,rp;
  1198. hp := cgp_hp p;
  1199. rp := cgp_rp p;
  1200. if null rp then
  1201. return {cd . cgp_zero()};
  1202. cd := cd_siadd({bc_mkat('neq,dip_lbc rp)},cd);
  1203. return {cd . cgp_mk(hp,rp,cgp_sugar p or dip_tdeg rp,cgp_number p,'red)}
  1204. end;
  1205. procedure cgp_ilcomb(p1,c1,t1,p2,c2,t2);
  1206. % CGP integer linear combination. [p1], [p2] are CGP's; [c1], [c2]
  1207. % are BC's; [t1], [t2] are EV's. Returns a CGP. Computes
  1208. % $p1*c1^t1+p2*c2^t2$.
  1209. begin scalar hp,rp,s;
  1210. hp := dip_ilcomb(cgp_hp p1,c1,t1,cgp_hp p2,c2,t2);
  1211. rp := dip_ilcomb(cgp_rp p1,c1,t1,cgp_rp p2,c2,t2);
  1212. s := ev_max!#(cgp_sugar p1 #+ ev_tdeg t1,cgp_sugar p2 #+ ev_tdeg t2);
  1213. return cgp_mk(hp,rp,s,nil,'unknown) % TODO: Summe ?????
  1214. end;
  1215. procedure cgp_ilcombr(p1,c1,p2,c2,t2);
  1216. % CGP integer linear combination for reduction. [p1], [p2] are
  1217. % CGP's; [c1], [c2] are BC's; [t2] is a EV's. Returns a CGP.
  1218. % Computes $p1*c1+p2*c2^t2$.
  1219. begin scalar hp,rp,s;
  1220. hp := dip_ilcombr(cgp_hp p1,c1,cgp_hp p2,c2,t2);
  1221. rp := dip_ilcombr(cgp_rp p1,c1,cgp_rp p2,c2,t2);
  1222. s := ev_max!#(cgp_sugar p1,cgp_sugar p2 #+ ev_tdeg t2);
  1223. return cgp_mk(hp,rp,s,nil,'unknown)
  1224. end;
  1225. procedure cgp_hpcp(cgp);
  1226. % CGP head polynomial copy. [cgp] is a CGP. Returns a CGP, in which
  1227. % the head polynomial is copied.
  1228. cgp_mk(dip_cp cgp_hp cgp,cgp_rp cgp,cgp_sugar cgp,
  1229. cgp_number cgp,cgp_ci cgp);
  1230. procedure cgp_shift(p,xvars);
  1231. % CGP shift. [p] is a CGP, which is neither zero nor green. Returns
  1232. % a [CGP]. Shifts all leading green monomials from the rest part
  1233. % into the head part.
  1234. if !*cgbgen and null xvars then
  1235. cgp_shift!-gen p
  1236. else
  1237. cgp_shift1(p,xvars);
  1238. procedure cgp_shift1(p,xvars);
  1239. % CGP shift subroutine. [p] is a CGP, which is neither zero nor
  1240. % green. Returns a [CGP]. Shifts all leading green monomials from
  1241. % the rest part into the head part.
  1242. begin scalar hp,rp,ht,hc,c;
  1243. hp := cgp_hp p;
  1244. rp := cgp_rp p;
  1245. c := T;
  1246. while c and rp do <<
  1247. ht := dip_evlmon rp;
  1248. hc := dip_lbc rp;
  1249. if cd_surep(bc_mkat('equal,hc),cgb_cd!*) then <<
  1250. if not(!*cgbgreen) then
  1251. hp := dip_nconcmon(hp,hc,ht);
  1252. rp := dip_mred rp
  1253. >> else
  1254. c := nil
  1255. >>;
  1256. if null rp and idp cgp_ci p then
  1257. return cgp_zero();
  1258. return cgp_mk(hp,rp,cgp_sugar p,cgp_number p,cgp_ci p)
  1259. end;
  1260. procedure cgp_shift!-gen(p);
  1261. % CGP shift generic case. [p] is a CGP, which is neither zero nor
  1262. % green. Returns a [CGP]. Shifts all leading green monomials from
  1263. % the rest part into the head part, i.e. we do nothing because
  1264. % there are no green BC's.
  1265. p;
  1266. procedure cgp_shiftwhite(p);
  1267. % CGP shift white. [p] is a CGP, which is neither zero nor green.
  1268. % Returns a [CGP]. Shifts the leading white monomials from the rest
  1269. % part into the head part and set the wtl accordingly.
  1270. begin scalar nhp,nci;
  1271. nhp := dip_nconcmon(cgp_hp p,cgp_lbc p,cgp_evlmon p);
  1272. nci := cgp_ci p;
  1273. nci := 'mixed . (cgp_evlmon p . if idp nci then nil else cdr nci);
  1274. return cgp_mk(nhp,dip_mred cgp_rp p,cgp_sugar p,cgp_number p,nci)
  1275. end;
  1276. procedure cgp_backshift(p);
  1277. % CGP back shift. [p] is a CGP. Returns a CGP. Shifts all white
  1278. % monomials from the head part into the rest part using the wtl.
  1279. begin scalar ci;
  1280. ci := cgp_ci p;
  1281. if not pairp ci or pairp ci and null cdr ci then
  1282. return p;
  1283. if cgp_rp p then
  1284. rederr "cgp_backshift: Rest polynomial must be zero";
  1285. return cgp_backshift1 p
  1286. end;
  1287. procedure cgp_backshift1(p);
  1288. % CGP back shift subroutine. [p] is a CGP. Returns a CGP. Shifts
  1289. % all white monomials from the head part into the rest part using
  1290. % the wtl.
  1291. begin scalar hp,wtl,nhp;
  1292. hp := cgp_hp p;
  1293. wtl := cdr cgp_ci p;
  1294. % TODO: Update condition
  1295. while hp and not ev_member(dip_evlmon hp,wtl) do << % TODO: Destructive?
  1296. nhp := dip_nconcmon(nhp,dip_lbc hp,dip_evlmon hp);
  1297. hp := dip_mred hp
  1298. >>;
  1299. if hp then
  1300. return cgp_mk(nhp,hp,cgp_sugar p,cgp_number p,'unknown);
  1301. return cgp_zero()
  1302. end;
  1303. procedure cgp_cancelmev(p,ev);
  1304. % CGP cancel monomoial ev's. [p] is a CGP; [ev] is an EV. Returns a
  1305. % CGP. Cancels all monomials in f which are multiples of [ev].
  1306. cgp_mk(cgp_hp p,dip_cancelmev(cgp_rp p,ev),
  1307. cgp_sugar p,cgp_number p,cgp_ci p);
  1308. procedure cgp_bcquot(p,c);
  1309. % CGP base coefficient procuct. [p] is a CGP; [c] is a BC. Returns
  1310. % a CGP. Computes $(1/[c])[p]$.
  1311. cgp_mk(dip_bcquot(cgp_hp p,c),dip_bcquot(cgp_rp p,c),
  1312. cgp_sugar p,cgp_number p,cgp_ci p);
  1313. procedure cgp_bcprod(p,c);
  1314. % CGP base coefficient procuct. [p] is a CGP; [c] is a BC. Returns
  1315. % a CGP. Computes $[c][p]$.
  1316. cgp_mk(dip_bcprod(cgp_hp p,c),dip_bcprod(cgp_rp p,c),
  1317. cgp_sugar p,cgp_number p,cgp_ci p);
  1318. procedure cgp_simpdcont(p);
  1319. % CGP simplify domain content. [p] is a CGP. Returns a CGP $p'$
  1320. % such that $p'$ is primitive as a multivariate polynomial over Z
  1321. % and there is an integer $c$ such that $[p]=cp'$.
  1322. begin scalar c;
  1323. if cgp_zerop p then
  1324. return p;
  1325. c := cgp_dcont p;
  1326. if bc_minus!? cgp_rlbc p then
  1327. c := bc_neg c;
  1328. return cgp_mk(dip_bcquot(cgp_hp p,c),dip_bcquot(cgp_rp p,c),
  1329. cgp_sugar p,cgp_number p,cgp_ci p)
  1330. end;
  1331. procedure cgp_rlbc(p);
  1332. % CGP real leading base coefficient. [p] is a CGP. Returns a BC,
  1333. % the coefficient of the largest term in both the head polynomial
  1334. % and the rest polynomial part.
  1335. if cgp_zerop p then
  1336. bc_fd 0
  1337. else if cgp_hp p then
  1338. dip_lbc cgp_hp p
  1339. else
  1340. cgp_lbc p;
  1341. procedure cgp_dcont(p);
  1342. % CGP domain content. [p] is a CGP. Returns a BC, the domain
  1343. % content of [p], i.e. the content of [p] considered as an
  1344. % multivariate polynomial over Z.
  1345. begin scalar c;
  1346. c := dip_dcont cgp_hp p;
  1347. if bc_one!? c then
  1348. return c;
  1349. return dip_dcont1(cgp_rp p,c)
  1350. end;
  1351. procedure cgp_normalize(u);
  1352. % CGP normalize. [u] is a CGP. Returns a unique representation of
  1353. % [u] as a CGP.
  1354. cgp_mk(nil,dip_append(cgp_hp u,cgp_rp u),nil,nil,'unknown);
  1355. procedure cgp_green(u);
  1356. % CGP green. [u] is A CGP. Returns a green CGP, i.e. a CGP in which
  1357. % the green head part is cancelled.
  1358. cgp_mk(nil,cgp_rp u,nil,nil,'green_colored);
  1359. procedure cgp_lsort(pl);
  1360. % CGP list sort. pl is a list of CGP's. Returns a list of CGP's.
  1361. sort(pl,function cgp_comp);
  1362. procedure cgp_comp(p1,p2);
  1363. dip_comp(cgp_rp p1,cgp_rp p2);
  1364. endmodule; % cgp
  1365. end; % of file