buchbg.red 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. module buchbg;% Central Groebner base code: Buchberger algorithm.
  2. % Authors: H. Melenk,H. M. Moeller,W. Neun
  3. % ZIB Berlin,August 2000
  4. flag('(groebrestriction groebresmax gvarslast groebmonfac
  5. groebprotfile glterms),'share);
  6. groebrestriction:=nil;groebresmax:=300;groebmonfac:=1;
  7. groecontcount!*:=10;
  8. !*gsugar:=t;
  9. !*groelterms:=t;
  10. !*groebfullreduction:=t;
  11. !*groebdivide:=t;
  12. switch groebopt,trgroeb,trgroebs,trgroeb1,
  13. trgroebr,groebfullreduction,groebstat,groebprot;
  14. % Variables for counting and numbering.
  15. % Option'groebopt'"optimizes" the given input
  16. % polynomial set(variable ordering).
  17. % option'trgroeb'Prints intermediate
  18. % results on the output file.
  19. % option'trgroeb1'Prints internal representation
  20. % of critical pair list d.
  21. % option'trgroebs'Prints's'- polynomials
  22. % on the output file.
  23. % option'trgroebr'Prints(intermediate)results and
  24. % computation statistics.
  25. % option'groebstat'The statistics are printed.
  26. %
  27. % option'groebrm'Multiplicities of factors in h-polynomials are reduced
  28. % to simple factors .
  29. % option'groebdivide'The algorithm avoids all divisions(only for modular
  30. % calculation), if this switch is set off.
  31. % option'groebprot'Write a protocol to the variable "groebprotfile".
  32. symbolic procedure buchvevdivides!?(vev1,vev2);
  33. % Test : vev1 divides vev2 ? for exponent vectors vev1,vev2.
  34. vevmtest!?(vev2,vev1)and
  35. (null gmodule!* or gevcompatible1(vev1,vev2,gmodule!*));
  36. symbolic procedure gevcompatible1(v1,v2,g);
  37. % Test whether'v1'and'v2'belong to the same vector column.
  38. if null g then t
  39. else if null v1 then(null v2 or gevcompatible1('(0), v2,g))
  40. else if null v2 then gevcompatible1(v1,'(0), g)else
  41. (car g=0 or car v1=car v2)
  42. and gevcompatible1(cdr v1,cdr v2,cdr g);
  43. symbolic procedure gcompatible(f,h);
  44. null gmodule!* or gevcompatible1(vdpevlmon f,vdpevlmon h,gmodule!*);
  45. symbolic procedure groebmakepair(f,h);
  46. % Construct a pair from polynomials'f'and'h'.
  47. begin scalar ttt,sf,sh;
  48. ttt:=tt(f,h);
  49. return if !*gsugar then
  50. << sf:=gsugar(f)#+ vevtdeg vevdif(ttt,vdpevlmon f);
  51. sh:=gsugar(h)#+ vevtdeg vevdif(ttt,vdpevlmon h);
  52. {ttt,f,h,max(sf,sh)}>>
  53. else{ttt,f,h}end;
  54. % The 1-polynomial will be constructed at run time
  55. % because the length of the vev is not known in advance.
  56. fluid'(vdpone!*);
  57. symbolic procedure vdponepol;
  58. % Construct the polynomial=1.
  59. vdpone!*:=vdpfmon(a2vbc 1,vevzero());
  60. symbolic procedure groebner2(p,r);
  61. % Setup all global variables for the Buchberger algorithm,
  62. % printing of statistics.
  63. begin scalar groetime!*,tim1,spac,spac1,p1,factortime!*,
  64. pairsdone!*,factorlevel!*,groesfactors!*,!*gcd;
  65. factortime!*:=0;groetime!*:=time();
  66. vdponepol();% we construct dynamically
  67. hcount!*:=0;mcount!*:=0;fcount!*:=0;
  68. bcount!*:=0;b4count!*:=0;hzerocount!*:=0;
  69. basecount!*:=0;!*gcd:=t;glterms:={'list};
  70. groecontcount!*:=10;
  71. if !*trgroeb then
  72. <<prin2"Groebner Calculation starting ";terprit 2;
  73. prin2" groebopt: ";print !*groebopt>>;
  74. spac:=gctime();
  75. p1:= if !*groebfac or null !*gsugar
  76. then groebbasein(p,!*groebfac,r)where !*gsugar=nil
  77. else gtraverso(p,nil,nil);
  78. if !*trgroeb or !*trgroebr or !*groebstat then
  79. <<spac1:=gctime()-spac;terpri();
  80. prin2t"statistics for GROEBNER calculation";
  81. prin2t"===================================";
  82. prin2" total computing time(including gc): ";
  83. prin2(( tim1:=time())- groetime!*);
  84. prin2t" milliseconds ";
  85. if factortime!* neq 0 then
  86. <<prin2"(time spent in FACTOR(excl. gc): ";
  87. prin2 factortime!*;prin2t " milliseconds)">>;
  88. prin2"(time spent for garbage collection: ";
  89. prin2 spac1;prin2t " milliseconds)";terprit 1;
  90. prin2"H-polynomials total: ";prin2t hcount!*;
  91. prin2"H-polynomials zero : ";prin2t hzerocount!*;
  92. prin2"Crit M hits: ";prin2t mcount!*;
  93. prin2"Crit F hits: ";prin2t fcount!*;
  94. prin2"Crit B hits: ";prin2t bcount!*;
  95. prin2"Crit B4 hits: ";prin2t b4count!*>>;return p1 end;
  96. smacro procedure testabort h;
  97. vdpmember(h,abort1)or
  98. 'cancel=( abort2:=groebtestabort(h,abort2));
  99. symbolic procedure groebenumerate f;
  100. %'f'is a temporary result. Prepare it for medium range storage
  101. % and ssign a number.
  102. if vdpzero!? f then f else
  103. <<vdpcondense f;
  104. if not vdpgetprop(f,'number)then
  105. <<f:=vdpputprop(f,'number,(pcount!*:=pcount!* #+ 1));
  106. if !*groebprot then
  107. <<groebprotsetq(mkid('poly,pcount!*),'candidate);
  108. vdpputprop(f,'groebprot,mkid('poly,pcount!*))
  109. >> >>;f>>;
  110. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  111. % Buchberger's Algorithm
  112. %
  113. % INPUT : G0={f1,...,fr} set of nonzero polynomials.
  114. % OUTPUT: groebner basis(list of nonzero polynomials).
  115. %
  116. % internal variables:
  117. %
  118. % problems list of problems to be processed. Problems is non nil,
  119. % if the inital problem was split by a successful factoring.
  120. % results Collection of results from problems.
  121. % g Basis under construction.
  122. % g1 Local pointer to g.
  123. % d List of critical pairs during algorithm.
  124. % d1,d2 Local lists of pairs during update of d.
  125. % f,fj Polynomials.
  126. % p,p1,p2 Pairs.
  127. % s,h Polynomials in the central part of the algorithm
  128. % (the "s-poly" and the "h-poly" selon Buchberger).
  129. % g99 Set of polynomials used for reduction.
  130. % abort1 List of polynomials in factorization context.
  131. % S calculation branch can be cancelled if one of
  132. % these polys is detected.
  133. % abort2 List of sets of polynomials. If a new h polynomial
  134. % is calculated,it should be removed from the sets.
  135. % If one set becomes null,the set restriction is
  136. % fulfilled and the branch can be cancelled.
  137. symbolic procedure groebbasein(g0,fact,abort1);
  138. begin scalar abort2,d,d1,d2,g,g1,g99,h,hlist,lasth,lv,p,problems,
  139. p1,results,s,x;integer gvbc,probcount!*;
  140. groebabort!*:=abort1;lv:=length vdpvars!*;
  141. for each p in g0 do if vdpzero!? p then g0:=delete(p,g0);
  142. if !*groebprereduce then g0:=groebprereduce g0;
  143. x:=for each fj in g0 collect
  144. <<groebsavelterm fj;gsetsugar(vdpenumerate vdpsimpcont fj,nil)>>;
  145. if !*groebprot then
  146. for each f in x do
  147. <<groebprotsetq(mkid('poly,h:=vdpnumber f),vdp2a f);
  148. vdpputprop(f,'groebprot,mkid('poly,h))>>;
  149. g0:=x;
  150. % Establish the initial problem
  151. problems:={{nil,nil,nil,g0,abort1,nil,nil,vbccurrentmode!*,nil,nil}};
  152. !*trgroeb and groebmess1(g,d);
  153. go to macroloop;
  154. macroloop:
  155. while problems and gvbc < groebresmax do
  156. begin
  157. % Pick up next problem
  158. x:=car problems;d:=car x;g:=cadr x;
  159. % g99:=groeblistreconstruct caddr x;
  160. g99:=vdplsort caddr x;g0:=cadddr x;abort1:=nth(x,5);
  161. abort2:=nth(x,6);pairsdone!*:=nth(x,7);h:=nth(x,8);
  162. % vbccurrentmode!*
  163. factorlevel!*:=nth(x,9);groesfactors!*:=nth(x,10);
  164. problems:=cdr problems;
  165. g0:=% Sort'g0',but keep factor in first position
  166. if factorlevel!* and g0 and cdr g0 then car g0.vdplsort cdr g0
  167. else vdplsort g0;x:=nil;lasth:=nil;
  168. !*trgroeb and groebmess23(g0,abort1,abort2);
  169. while d or g0 do
  170. begin
  171. if groebfasttest(g0,g,d,g99)then go to stop;
  172. !*trgroeb and groebmess50 g;
  173. if g0 then<<h:=car g0;g0:=cdr g0;gsetsugar(h,nil);
  174. groebsavelterm h;p:={nil,h,h}>>else
  175. <<p:=car d;d:=delete(p,d);
  176. s:=groebspolynom(cadr p,caddr p);
  177. if fact then
  178. pairsdone!*:=(vdpnumber cadr p.vdpnumber caddr p).pairsdone!*;
  179. !*trgroeb and groebmess3(p,s);
  180. h:=groebnormalform0(s,g99,'tree,fact);groebsavelterm h;
  181. h:=groebsimpcontnormalform h;
  182. if vdpzero!? h then !*trgroeb and groebmess4(p,d);
  183. % Test for possible chains
  184. if not vdpzero!? h then % only for real h's
  185. <<s:=groebchain(h,cadr p,g99);
  186. if s=h then h:=groebchain(h,caddr p,g99);
  187. if secondvalue!* then g:=delete(secondvalue!*,g)>> >>;
  188. if vdpzero!? h then go to bott;
  189. if vevzero!? vdpevlmon h then % base 1 found
  190. <<!*trgroeb and groebmess5(p,h);go to stop>>;
  191. if testabort(h)then
  192. <<!*trgroeb and groebmess19(h,abort1,abort2);go to stop>>;
  193. s:= nil;
  194. % Look for implicit or explicit factorization
  195. hlist:=nil;
  196. if groebrestriction!* then hlist:=groebtestrestriction(h,abort1);
  197. if not hlist and fact then hlist:=groebfactorize(h,abort1,g,g99);
  198. if hlist='zero then go to bott;
  199. if groefeedback!* then g0:=append(groefeedback!*,g0);
  200. groefeedback!*:=nil;
  201. % Factorisation found but only one factor survived
  202. if hlist and length hlist=2 then<<h:=car cadr hlist;hlist:=nil>>;
  203. if hlist then
  204. <<if hlist neq'cancel then
  205. problems:= groebencapsulate(hlist,d,g0,g,g99,abort1,abort2,problems,fact);
  206. go to stop>>;
  207. %'h'polynomial is accepted now
  208. h:=groebenumerate h;!*trgroeb and groebmess5(p,h);
  209. % Construct new critical pairs
  210. d1:=nil;
  211. !*trgroeb and groebmess50(g);
  212. for each f in g do
  213. if(car p or % That means "not an input polynomial"
  214. not member(vdpnumber h.vdpnumber f,pairsdone!*)
  215. )and gcompatible(f,h)then
  216. <<d1:=groebcplistsortin(groebmakepair(f,h),d1);
  217. if tt(f,h)=vdpevlmon(f)then
  218. <<g:=delete(f,g);
  219. !*trgroeb and groebmess2 f>> >>;
  220. !*trgroeb and groebmess51 d1;
  221. d2:=nil;
  222. while d1 do
  223. <<d1:=groebinvokecritf d1;p1:=car d1;d1:=cdr d1;
  224. d2:=groebinvokecritbuch4(p1,d2);
  225. d1:=groebinvokecritm(p1,d1)>>;
  226. d:=groebinvokecritb(h,d);
  227. d:=groebcplistmerge(d,d2);
  228. % Monomials and binomials
  229. if vdplength h < 3 and car p then
  230. <<g:=groebsecondaryreduction(h,g,g99,d,nil,t);
  231. if g='abort then go to stop;g99:=secondvalue!*;
  232. d:=thirdvalue!*>>;
  233. g:=h.g;lasth:=h;
  234. g99:=groeblistadd(h,g99);
  235. !*trgroeb and groebmess8(g,d);
  236. go to bott;
  237. stop: d:=g:=g0:=nil;
  238. bott:;
  239. end;
  240. g:=vdplsort g;% Such that g descending
  241. x:=groebbasein2(g,g99,problems,abort1,abort2,fact);
  242. g1:=car x;problems:=cdr x;
  243. if g1 then<<results:=g1.results;gvbc:=gvbc+1>>;
  244. !*trgroeb and groebmess13(g1,problems)end;
  245. if gvbc >= groebresmax then
  246. lpriw("########","warning: GROEBRESMAX limit reached");
  247. return groebbasein3 results end;
  248. symbolic procedure groebfasttest(g0,g,d,g99);
  249. <<g:=g0:=d:=g99:=nil;nil>>;% A hook for special techniques
  250. symbolic procedure groebbasein2(g,g99,problems,abort1,abort2,fact);
  251. % Final reduction for a base'g': reduce each polynomial with the
  252. % other members;here again support of factorization.
  253. begin scalar f,g1,!*groebfullreduction,!*groebheufact,!*gsugar,% Saving value
  254. h,hlist,x;integer cnt;
  255. !*groebfullreduction:=t;g1:=nil;
  256. while g do
  257. <<h:=car g;g:=cdr g;
  258. if !*groebprot then
  259. groebprotsetq('candidate,mkid('poly,vdpnumber h));
  260. h:=groebnormalform0(h,g,'sort,nil);
  261. f:=groebsimpcontnormalform h;
  262. !*trgroeb and groebmess26(h,f);
  263. if !*groebprot then groebprotsetq({'gb,cnt:=cnt+1},'candidate);
  264. if vdpone!? f then<<g1:=g:=nil>>;% Base{1} found
  265. % very late now
  266. if fact and not vdpzero!? f then
  267. <<hlist:=groebfactorize(f,abort1,nil,nil);
  268. if not null hlist then
  269. << % lift structure
  270. hlist:=for each x in cdr hlist collect car x;
  271. % discard superfluous factors
  272. for each h in hlist do
  273. if vdpmember(h,abort1)then
  274. <<hlist:=delete(h,hlist);!*trgroeb and groebmess19(h,abort1,abort2)>>;
  275. % Generate new subproblems
  276. x:=0;
  277. for each h in hlist do
  278. <<hlist:=delete(h,hlist);
  279. h:=groebenumerate h;
  280. problems:=
  281. {nil, % null D
  282. append(g1,g), % base
  283. g99, % g99
  284. {h}, % g0
  285. append(hlist,abort1),
  286. abort2,
  287. pairsdone!*,
  288. vbccurrentmode!*,
  289. (x:=x+1).factorlevel!*,
  290. groesfactors!*}. problems>>;
  291. g:=g1:=nil;% Cancel actual final reduction
  292. f:=nil >> >>;
  293. if f and vdpevlmon h neq vdpevlmon f then
  294. <<g:=vdplsort append(g,f.g1);g1:=nil>>else
  295. if f and not vdpzero!? f then g1:=append(g1,{f})>>;
  296. return g1.problems end;
  297. symbolic procedure groebbasein3 results;
  298. % Final postprocessing: remove multiple bases from the result.
  299. begin scalar x,g,f,p1,p2;
  300. x:=nil;g:=results;p1:=p2:=0;
  301. while results do
  302. <<if vdpone!? car car results % Exclude multiple{1}
  303. then p1:=p1+1 % count ones
  304. else
  305. <<f:=for each p in car results % Delete props for member
  306. collect vdpremallprops p;
  307. if member(f,x) % each base only once
  308. then p2:=p2+1 % count multiples
  309. else if not groebabortid( f,groebabort!*)
  310. then x:=f.x;
  311. results:=cdr results>> >>;
  312. results:=if null x then{{vdpone!*}}else x;
  313. return results end;
  314. fluid'(!*vbccompress);
  315. symbolic procedure groebchain(h,f,g99);
  316. % Test if a chain from h-plynomials can be computed from the'h'.
  317. begin scalar count,found,h1,h2,h3;
  318. secondvalue!*:=nil;
  319. return h;% Erst einmal.
  320. if not buchvevdivides!?(vdpevlmon h,vdpevlmon f)
  321. then return h;
  322. h2:=h;h1:=f;found:=t;count:=0;
  323. while found do
  324. <<h3:=groebspolynom(h1,h2);
  325. h3:=groebnormalform0(h3,g99,'tree,t);
  326. h3:=vdpsimpcont h3;
  327. if vdpzero!? h3 then
  328. <<found:=nil;
  329. prin2t "chain---------------------------";
  330. vdpprint h1;vdpprint h2;vdpprint h3;
  331. secondvalue!*:=f;count:=9999>>
  332. else if vdpone!? h3 then
  333. <<found:=nil;
  334. prin2t "chain---------------------------";
  335. vdpprint h1;vdpprint h2;vdpprint h3;
  336. h2:=h3;count:=9999>>
  337. else if buchvevdivides!?(vdpevlmon h3,vdpevlmon h2)then
  338. <<found:=t;
  339. prin2t "chain---------------------------";
  340. vdpprint h1;vdpprint h2;vdpprint h3;
  341. h1:=h2;h2:=h3;count:=count+1>>
  342. else found:=nil>>;
  343. return if count > 0 then
  344. <<prin2 "CHAIN :";prin2t count;h2>>else h end;
  345. symbolic procedure groebencapsulate(hlist,d,g0,g,g99,
  346. abort1,abort2,problems,fact);
  347. %'hlist'is a factorized h-poly. This procedure has the job to
  348. % form new problems from hlist and to add them to problems.
  349. % Result is problems.
  350. % Standard procedure: only creation of subproblems.
  351. begin scalar factl, % List of factorizations under way.
  352. u,y,z;integer fc;
  353. if length vdpvars!* > 10 or car hlist neq'factor then
  354. return groebencapsulatehardcase(hlist,d,g0,g,g99,
  355. abort1,abort2,problems,fact);
  356. % Encapsulate for each factor.
  357. factl:=groebrecfactl{hlist};
  358. !*trgroeb and groebmess22(factl,abort1,abort2);
  359. for each x in reverse factl do
  360. <<y:=append(car x,g0);
  361. z:=vdpunion(cadr x,abort1);
  362. u:=append(caddr x,abort2);
  363. problems:={d,g,
  364. g, % future g99
  365. y, % as new problem
  366. z, % abort1
  367. u, % abort2
  368. pairsdone!*, % pairsdone!*
  369. vbccurrentmode!*,
  370. (fc:=fc+1).factorlevel!*,
  371. groesfactors!*
  372. }. problems>>;
  373. return problems end;
  374. symbolic procedure groebencapsulatehardcase(hlist,d,g0,g,g99,
  375. abort1,abort2,problems,fact);
  376. %'hlist'is a factorized h-poly. This procedure has the job to
  377. % form new problems from hlist and to add them to problems.
  378. % Result is problems.
  379. % First the procedure tries to compute new h-polynomials from the
  380. % remaining pairs which are not affected by the factors in hlist.
  381. % Purpose is to find further factorizations and to do calculations
  382. % in common for all factors in order to shorten the separate later
  383. % branches.
  384. begin scalar factl, % List of factorizations under way.
  385. factr, % Variables under factorization.
  386. break,d1,d2,f,fl1,gc,h,p,pd,p1,s,u,y,z;
  387. integer fc;
  388. factl:={hlist};factr:=vdpspace car cadr hlist;
  389. for each x in cdr hlist do
  390. for each p in x do factr:=vevunion(factr,vdpspace p);
  391. % ITER:
  392. % Now process additional pairs.
  393. while d or g0 do
  394. begin
  395. break:=nil;
  396. if g0 then
  397. << % Next poly from input.
  398. s:=car g0;g0:=cdr g0;p:={nil,s,s}>>
  399. else
  400. << % Next poly fropm pairs.
  401. p:=car d;d:=delete(p,d);
  402. if not vdporthspacep(car p,factr)then
  403. s:=nil else
  404. <<s:=groebspolynom(cadr p,caddr p);
  405. !*trgroeb and groebmess3(p,s)>> >>;
  406. if null s or not vdporthspacep(vdpevlmon s,factr)then
  407. << % Throw away s polynomial .
  408. f:=cadr p;
  409. if not vdpmember3(f,g0,g,gc)then gc:=f.gc;
  410. f:=caddr p;
  411. if car p and not vdpmember3(f,g0,g,gc)
  412. then gc:=f.gc;go to bott>>;
  413. h:=groebnormalform(s,g99,'tree);
  414. if vdpzero!? h and car p then !*trgroeb and groebmess4(p,d);
  415. if not vdporthspacep(vdpevlmon h,factr)then
  416. << % Throw away h-polynomial.
  417. f:=cadr p;
  418. if not vdpmember3(f,g0,g,gc)then gc:=f.gc;
  419. f:=caddr p;
  420. if car p and not vdpmember3(f,g0,g,gc)then gc:=f.gc;
  421. go to bott>>;
  422. %%% if car p then
  423. %%% pairsdone!*:=(vdpnumber cadr p.vdpnumber caddr p).pairsdone!*;
  424. if vdpzero!? h then go to bott;
  425. if vevzero!? vdpevlmon h then % Base 1 found.
  426. go to stop;
  427. h:=groebsimpcontnormalform h;% Coefficients normalized.
  428. if testabort h then
  429. <<!*trgroeb and groebmess19(h,abort1,abort2);
  430. go to stop>>;
  431. s:=nil;hlist:=nil;
  432. if groebrestriction!* then hlist:=groebtestrestriction(h,abort1);
  433. if hlist='cancel then go to stop;
  434. if not hlist and fact then
  435. hlist:=groebfactorize(h,abort1,g,g99);
  436. if groefeedback!* then g0:=append(groefeedback!*,g0);
  437. groefeedback!*:=nil;
  438. if hlist and length hlist=2 then
  439. <<h:=car cadr hlist;hlist:=nil>>;
  440. if hlist then
  441. <<for each x in cdr hlist do
  442. for each h in x do factr:=vevunion(factr,vdpspace h);
  443. factl:=hlist.factl;% Add to factors.
  444. go to bott>>;
  445. h:=groebenumerate h; % Ready now.
  446. !*trgroeb and groebmess5(p,h);
  447. % Construct new critical pairs.
  448. d1:=nil;
  449. for each f in g do
  450. if tt(f,h)=vdpevlmon(f)and gcompatible(f,h)then
  451. <<g:=delete(f,g);
  452. d1:=groebcplistsortin(groebmakepair(f,h),d1);
  453. !*trgroeb and groebmess2 f>>;
  454. !*trgroeb and groebmess51 d1;
  455. d2:=nil;
  456. while d1 do
  457. <<d1:=groebinvokecritf d1;p1:=car d1;d1:=cdr d1;
  458. d2:=groebinvokecritbuch4(p1,d2);
  459. d1:=groebinvokecritm(p1,d1)>>;
  460. d:=groebinvokecritb(h,d);d:=groebcplistmerge(d,d2);
  461. if vdplength h < 3 then
  462. <<g:=groebsecondaryreduction(h,g,g99,d,gc,t);
  463. if g='abort then go to stop;g99:=secondvalue!*;
  464. d:=thirdvalue!*;gc:=fourthvalue!*>>;
  465. g:=h.g;
  466. g99:=groeblistadd(h,g99);
  467. !*trgroeb and groebmess8(g,d);
  468. go to bott;
  469. stop: d:=g:=g0:=gc:=factl:=nil;
  470. bott: end;%ITER
  471. % Now collect all relvevant polys.
  472. g0:=vdpunion(g0,vdpunion(g,gc));
  473. % Encapsulate for each factor.
  474. if factl then
  475. <<factl:=groebrecfactl factl;
  476. !*trgroeb and groebmess22(factl,abort1,abort2)>>;
  477. for each x in reverse factl do
  478. <<fl1:=(fc:=fc+1).factorlevel!*;
  479. break:= nil;y:=append(car x,g0);
  480. z:=vdpunion(cadr x,abort1);
  481. u:=append(caddr x,abort2);
  482. if vdpmember(vdpone!*,y)then break:=vdpone!*;
  483. % Inspect the unreduced list first .
  484. if not break then for each p in z do
  485. if vdpmember(p,y)then break:=p;
  486. % Now prepare the reduced list.
  487. if not break then
  488. <<y:=append(car x,groebreducefromfactors(g0,car x));
  489. pd:=secondvalue!*;
  490. if vdpmember(vdpone!*,y)then break:=vdpone!* else
  491. for each p in z do if vdpmember(p,y)then break:=p;
  492. pd:=subla(pd,pairsdone!*)>>;
  493. if not break then
  494. problems:={
  495. nil, % new d
  496. nil, % new g
  497. nil, % future g99
  498. y, % as new problem
  499. z, % abort1
  500. u, % abort2
  501. nil, % pairsdone!*
  502. vbccurrentmode!*,
  503. fl1, % factorlevel!*,
  504. groesfactors!* % factor db
  505. }.problems else !*trgroeb and groebmess19a(break,fl1)>>;
  506. return problems end;
  507. symbolic procedure groebrecfactl(factl);
  508. % Factl is a list of factorizations:a list of lists of vdps
  509. % generate calculation pathes from them.
  510. begin scalar rf,res,type;
  511. if null factl then return{{nil,nil,nil}};
  512. rf:=groebrecfactl(cdr factl);
  513. factl:=car factl;
  514. type:=car factl;% FACTOR or RESTRICT
  515. factl:=cdr factl;
  516. while factl do
  517. <<for each y in rf do
  518. if vdpdisjoint!?(car factl,cadr y)then
  519. res:={vdpunion(car factl,car y),
  520. (if type='factor then
  521. append(for each x in cdr factl collect car x, cadr y)
  522. else cadr y),
  523. (if type neq'factor then append(cdr factl,caddr y)
  524. else caddr y)}.res;
  525. factl:=cdr factl>>;
  526. return res end;
  527. symbolic procedure groebtestabort(h,abort2);
  528. % Tests if h is member of one of the sets in abort2.
  529. % if yes, it is deleted. If one wet becomes null,the message
  530. % "CANCEL is returned, otherwise the updated abort2.
  531. begin scalar x,break,res;
  532. % First test the occurence.
  533. x:=abort2;
  534. while x and not break do
  535. <<if vdpmember(h,car x)then break:=t;x:=cdr x>>;
  536. if not break then return abort2;% not relvevant
  537. break:=nil;
  538. while abort2 and not break do
  539. <<x:=vdpdeletemember(h,car abort2);
  540. if null x then break:=t;res:=x.res;
  541. abort2:=cdr abort2>>;
  542. !*trgroeb and groebmess25(h,res);
  543. if break then return'cancel;
  544. return res end;
  545. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  546. %
  547. % Reduction of polynomials.
  548. %
  549. symbolic procedure groebnormalform(f,g,type);
  550. groebnormalform0(f,g,type,nil);
  551. symbolic procedure groebnormalform0(f,g,type,m);
  552. % General procedure for reduction of one polynomial from a set
  553. %'f'is a polynomial,'g'is a set of polynomials either in
  554. % a search tree or in a sorted list.
  555. %'f'has to be reduced modulo'g'.
  556. %'m'is indicator,whether a selection('m'is true)is wanted.
  557. begin scalar a,break,c,divisor,done,f0,f1,f2,fold,gl,vev;
  558. integer n,s1,s2;
  559. scalar zzz;
  560. if !*groebweak and !*vdpinteger
  561. and groebweakzerotest( f,g,type)then return f2vdp nil;
  562. fold:=f;f1:=vdpzero();a:= vbcfi 1;
  563. gsetsugar(f1,gsugar f);
  564. while not vdpzero!? f do
  565. begin
  566. vev:=vdpevlmon f;c:=vdplbc f;
  567. if not !*groebfullreduction and not vdpzero!? f1 then g:=nil;
  568. if null g then
  569. <<f1:=vdpsum(f1,f);f:=vdpzero();break:=t;divisor:=nil;go to ready>>;
  570. divisor:=groebsearchinlist(vev,g);
  571. if divisor then<<done:=t;% true action indicator
  572. if m and vdpsortmode!*='revgradlex
  573. and vdpzero!? f1 then gl:=f.gl;
  574. if !*trgroebs then
  575. <<prin2"//-";prin2 vdpnumber divisor>> >>;
  576. if divisor then
  577. if vdplength divisor=1 then
  578. f:=vdpcancelmvev(f,vdpevlmon divisor)else
  579. if !*vdpinteger or not !*groebdivide then
  580. <<f:=groebreduceonestepint(f,f1,c,vev,divisor);
  581. f1:=secondvalue!*;n:=n+1;
  582. if not vdpzero!? f and n #> groecontcount!* then
  583. <<f0:=f;
  584. f:=groebsimpcont2(f,f1);
  585. groecontentcontrol(f neq f0);
  586. f1:=secondvalue!*;n:=0>> >>
  587. else
  588. f:=groebreduceonesteprat(f,nil,c,vev,divisor)
  589. else
  590. <<!*gsugar and<<s1:=gsugar(f);s2:=gsugar(f1)>>;
  591. f1:=vdpappendmon(f1,vdplbc f,vdpevlmon f);
  592. f:=vdpred f;
  593. !*gsugar and<<gsetsugar(f,s1);
  594. gsetsugar(f1,max(s2,s1))>> >>;
  595. ready:
  596. end;
  597. if !*groebprot then groebreductionprotocolborder();
  598. if vdpzero!? f1 then go to ret;
  599. zzz:=f1;
  600. if not done then f1:=fold else
  601. if m and vdpsortmode!*='revgradlex then
  602. <<if not vdpzero!? f1 then gl:=f1.gl;
  603. while gl do
  604. <<f2:=groebnormalformselect car gl;
  605. if f2 then<<f1:=f2;gl:=nil>>else gl:=cdr gl>> >>;
  606. ret: return f1 end;
  607. symbolic procedure groecontentcontrol u;
  608. %'u'indicates,that a substantial content reduction was done;
  609. % update content reduction limit from'u'.
  610. groecontcount!*:=if not numberp groecontcount!* then 10 else
  611. if u then max(0,groecontcount!*-1)
  612. else min(10,groecontcount!*+1);
  613. symbolic procedure groebvbcbig!? a;
  614. % Test if'a'is a "big" coefficient.
  615. (if numberp x then(x > 1000000000000 or x <-1000000000000)
  616. else t)where x=vbcnumber a;
  617. symbolic procedure groebnormalformselect v;
  618. % Select the vdp'v',if the'vdplastvar*'- variable occurs in all
  619. % terms(then return it)or don't select it(then return'nil').
  620. if countlastvar(v,t)#> 0 then v;
  621. symbolic procedure groebsimpcontnormalform h;
  622. % SimpCont version preserving the property SUGAR.
  623. if vdpzero!? h then h else
  624. begin scalar sugar,c;
  625. sugar:=gsugar h;c:=vdplbc h;
  626. h:=vdpsimpcont h;gsetsugar(h,sugar);
  627. if !*groebprot and not(c=vdplbc h)then groebreductionprotocol2
  628. reval{'quotient,vbc2a vdplbc h,vbc2a c};
  629. return h end;
  630. symbolic procedure groebsimpcont2(f,f1);
  631. % Simplify two polynomials with the gcd of their contents.
  632. begin scalar c,s1,s2;
  633. s1:=gsugar f;s2:=gsugar f1;
  634. c:=vdpcontent f;
  635. if vbcone!? vbcabs c then go to ready;
  636. if not vdpzero!? f1 then
  637. <<c:=vdpcontent1(f1,c);
  638. if vbcone!? vbcabs c then go to ready;
  639. f1:= vdpdivmon(f1,c,nil)>>;
  640. f:=vdpdivmon(f,c,nil);
  641. !*trgroeb and groebmess28 c;
  642. groebsaveltermbc c;
  643. gsetsugar(f,s1);gsetsugar(f1,s2);
  644. ready:secondvalue!*:=f1;return f end;
  645. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  646. %
  647. % Special case reductions.
  648. %
  649. symbolic procedure groebprereduce g;
  650. % Reduce the polynomials in g with themselves.
  651. % The reduction is continued until headterms are stable is possible.
  652. begin scalar res,work,oldvev,f,oldf,!*groebweak,
  653. !*groebfullreduction;integer count;
  654. if !*trgroebs then
  655. <<g:=for each p in g collect vdpenumerate p;
  656. for each p in g do vdpprint p>>;
  657. res:=nil;% Delete zero polynomials from'g'.
  658. for each f in g do if not vdpzero!? f then res:=f.res;
  659. work:=g:=res:=reversip res;
  660. while work do
  661. <<g:=vdplsort res;% Sort prvevious result.
  662. if !*trgroebs then prin2t "Starting cycle in prereduction.";
  663. res:=nil;count:=count+1;work:=nil;
  664. while g do
  665. <<oldf:=f:= car g;g:=cdr g;
  666. oldvev:=vdpevlmon f;
  667. f:=vdpsimpcont groebnormalform(f,g,'sort);
  668. if(!*trgroebs or !*groebprot)and not vdpequal(f,oldf)then
  669. <<f:=vdpenumerate f;
  670. if !*groebprot then
  671. if not vdpzero!? f then
  672. groebprotsetq(mkid('poly,vdpnumber f),vdp2a f)
  673. else groebprotval 0;
  674. if !*trgroebs then
  675. <<prin2t "reducing";vdpprint oldf;prin2t "to";vdpprint f>> >>;
  676. if not vdpzero!? f then
  677. <<if oldvev neq vdpevlmon f then work:=t;
  678. res:=f.res>> >> >>;
  679. return for each f in res collect vdpsimpcont f end;
  680. symbolic procedure groebreducefromfactors(g,facts);
  681. % Reduce the polynomials in G from those in facts.
  682. begin scalar new,gnew,f,nold,nnew,numbers;
  683. if !*trgroebs then
  684. <<prin2t "replacing from factors:";
  685. for each x in facts do vdpprin2t x>>;
  686. while g do
  687. <<f:=car g;g:=cdr g;nold:=vdpnumber(f);
  688. new:= groebnormalform(f,facts,'list);
  689. if vdpzero!? new then
  690. <<if !*trgroebs then<<prin2 "vanishes ";
  691. prin2 vdpnumber f>> >>
  692. else if vevzero!? vdpevlmon new then
  693. <<if !*trgroebs then<<prin2 "ONEPOL ";prin2 vdpnumber f>>;
  694. g:=nil;
  695. gnew:={vdpone!*}>>
  696. else<<if new neq f then
  697. <<new:=vdpenumerate vdpsimpcont new;
  698. nnew:=vdpnumber new;
  699. numbers:=(nold.nnew).numbers;
  700. if !*trgroebs then<<prin2 "replacing ";
  701. prin2 vdpnumber f;
  702. prin2 " by ";
  703. prin2t vdpnumber new>> >>;
  704. gnew:=new.gnew>> >>;
  705. secondvalue!*:=numbers;
  706. return gnew end;
  707. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  708. %
  709. % Support for reduction by "simple" polynomials.
  710. symbolic procedure groebnormalform1(f,p);
  711. % Short version;reduce f by p;
  712. % special case: p is a monomial.
  713. if vdplength p=1 then vdpcancelmvev(f,vdpevlmon p)
  714. else groebnormalform(f,{p},nil);
  715. symbolic procedure groebprofitsfromvev(p,vev);
  716. % Tests,if at least one monomial from p would be reduced by vev.
  717. if vdpzero!? p then nil
  718. else if buchvevdivides!?(vev,vdpevlmon p)then t
  719. else groebprofitsfromvev(vdpred p,vev);
  720. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  721. %
  722. % Special reduction procedures.
  723. symbolic procedure groebreduceonestepint(f,f1,c,vev,g1);
  724. % Reduction step for integer case:
  725. % calculate f= a*f-b*g a,b such that leading term vanishes
  726. %(vev of lvbc g divides vev of lvbc f)
  727. % and calculate f1=a * f1;
  728. % return value=f,secondvalue=f1.
  729. begin scalar vevlcm,a,b,cg,x,rg1;
  730. % Trivial case: g1 single monomial.
  731. if vdpzero!?(rg1:=vdpred g1)
  732. then return<<f:=vdpred f;secondvalue!*:=f1;f>>;
  733. vevlcm:=vevdif(vev,vdpevlmon g1);
  734. cg:=vdplbc g1;
  735. % Calculate coefficient factors .
  736. x:=if not !*groebdivide then vbcfi 1 else vbcgcd(c,cg);
  737. a:=vbcquot(cg,x);
  738. b:=vbcquot(c,x);
  739. % Multiply relvevant parts from f and f1 by a(vbc).
  740. if f1 and not vdpzero!? f1 then f1:=vdpvbcprod(f1,a);
  741. if !*groebprot then groebreductionprotocol(a,vbcneg b,vevlcm,g1);
  742. f:= vdpilcomb1(vdpred f,a,vevzero(),
  743. rg1,vbcneg b,vevlcm);
  744. % Return with f and f1.
  745. secondvalue!*:= f1;thirdvalue!*:=a;return f end;
  746. symbolic procedure groebreduceonesteprat(f,dummy,c,vev,g1);
  747. % Reduction step for rational case:
  748. % calculate f= f-g/vdpLbc(f).
  749. begin scalar x,rg1,vevlcm;
  750. % Trivial case: g1 single monomial.
  751. dummy:=nil;
  752. if vdpzero!?(rg1:=vdpred g1)then return vdpred f;
  753. % Calculate coefficient factors.
  754. x:=vbcneg vbcquot(c,vdplbc g1);
  755. vevlcm:=vevdif(vev,vdpevlmon g1);
  756. if !*groebprot then
  757. groebreductionprotocol( a2vbc 1,x,vevlcm,g1);
  758. return vdpilcomb1(vdpred f,a2vbc 1,vevzero(),
  759. rg1,x,vevlcm)end;
  760. symbolic procedure groebreductionprotocol(a,b,vevlcm,g1);
  761. if !*groebprot then
  762. groebprotfile:=
  763. if not vbcone!? a then
  764. append(groebprotfile,
  765. {{'equal,'candidate,
  766. {'times,'candidate,vbc2a a}},
  767. {'equal,'candidate,
  768. {'plus,'candidate,
  769. {'times,vdp2a vdpfmon(b,vevlcm),
  770. mkid('poly,vdpnumber g1)}}}
  771. })
  772. else
  773. append(groebprotfile,
  774. {{'equal,'candidate,
  775. {'plus,'candidate,
  776. {'times,vdp2a vdpfmon(b,vevlcm),
  777. mkid('poly,vdpnumber g1)}}}
  778. });
  779. symbolic procedure groebreductionprotocol2 a;
  780. if !*groebprot then
  781. groebprotfile:=
  782. if not(a=1)then
  783. append(groebprotfile,
  784. {{'equal,'candidate,{'times,'candidate,a}}});
  785. symbolic procedure groebreductionprotocolborder();
  786. append(groebprotfile,'!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+.nil);
  787. symbolic procedure groebprotsetq(a,b);
  788. groebprotfile:=append(groebprotfile,{{'equal,a,b}});
  789. symbolic procedure groebprotval a;
  790. groebprotfile:=
  791. append(groebprotfile,{{'equal,'intermediateresult,a}});
  792. symbolic procedure subset!?(s1,s2);
  793. % Tests,if s1 is a subset of s2.
  794. if null s1 then t else
  795. if member(car s1,s2)then subset!?(cdr s1,s2)
  796. else nil;
  797. symbolic procedure vevsplit vev;
  798. % Split vev such that each exponent vector has only one 1.
  799. begin scalar e,vp;integer n;
  800. for each x in vev do
  801. <<n:=n+1;
  802. if x neq 0 then
  803. <<e:=append(vdpevlmon vdpone!*,nil);
  804. rplaca(pnth(e,n),1);
  805. vp:=e.vp>> >>;return vp end;
  806. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  807. %
  808. % Calculation of an S-polynomial.
  809. %
  810. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  811. % General strategy:
  812. %
  813. % groebspolynom4 calculates the traditional s-polynomial from p1,p2
  814. %(linear combination such that the highest term vanishes).
  815. % groebspolynom2 subtracts multiples of p2 from the s-polynomial such
  816. % that head terms are eliminated early.
  817. symbolic procedure groebspolynom(p1,p2);
  818. groebspolynom2(p1,p2);
  819. symbolic procedure groebspolynom2(p1,p2);
  820. if vdpzero!? p1 then p2 else if vdpzero!? p2 then p1 else
  821. begin scalar cand,s,tp1,tp2,ts;
  822. s:=groebspolynom3(p1,p2);
  823. if vdpzero!? s or vdpone!? s or !*groebprot then return s;
  824. tp1:=vdpevlmon p1;tp2:=vdpevlmon p2;
  825. while not vdpzero!? s
  826. and(( buchvevdivides!?(tp2,(ts:=vdpevlmon s)) and(cand:=p2))
  827. or(buchvevdivides!?(tp1,(ts:=vdpevlmon s))
  828. and(cand:=p1)))
  829. do<<if !*vdpinteger then
  830. s:=% vdpsimpcont
  831. groebreduceonestepint(s,nil,vdplbc s,ts,cand)
  832. else
  833. % Rational, float and modular case .
  834. s:=groebreduceonesteprat(s,nil,vdplbc s,ts,cand)>>;
  835. return s end;
  836. symbolic procedure groebspolynom3(p,q);
  837. begin scalar r;r:=groebspolynom4(p,q);
  838. groebsavelterm r;return r end;
  839. symbolic procedure groebspolynom4(p1,p2);
  840. begin scalar db1,db2,ep1,ep2,ep,r,rp1,rp2,x;
  841. ep1:=vdpevlmon p1;ep2:=vdpevlmon p2;
  842. ep:=vevlcm(ep1,ep2);
  843. rp1:=vdpred p1;rp2:=vdpred p2;
  844. gsetsugar(rp1,gsugar p1);gsetsugar(rp2,gsugar p2);
  845. r:=(if vdpzero!? rp1 and vdpzero!? rp2 then rp1
  846. else(if vdpzero!? rp1 then
  847. <<db2:=a2vbc 0;
  848. vdpprod( rp2,vdpfmon(db1:=a2vbc 1,vevdif(ep,ep2)))>>
  849. else if vdpzero!? rp2 then
  850. <<db1:=a2vbc 0;
  851. vdpprod(rp1,vdpfmon(db2:=a2vbc 1,
  852. vevdif(ep,ep1)))>>
  853. else
  854. <<db1:=vdplbc p1;
  855. db2:=vdplbc p2;
  856. if !*vdpinteger then
  857. <<x:= vbcgcd(db1,db2);
  858. if not vbcone!? x then
  859. <<db1:=vbcquot(db1,x);db2:=vbcquot(db2,x)>> >>;
  860. vdpilcomb1(rp2,db1,vevdif(ep,ep2),
  861. rp1,vbcneg db2,vevdif(ep,ep1)) >>
  862. ));
  863. if !*groebprot then
  864. groebprotsetq('candidate,
  865. {'difference,
  866. {'times,vdp2a vdpfmon(db2,vevdif(ep,ep2)),
  867. mkid('poly,vdpnumber p1)},
  868. {'times,vdp2a vdpfmon(db1,vevdif(ep,ep1)),
  869. mkid('poly,vdpnumber p2)}});
  870. return r end;
  871. symbolic procedure groebsavelterm r;
  872. if !*groelterms and not vdpzero!? r then groebsaveltermbc vdplbc r;
  873. symbolic procedure groebsaveltermbc r;
  874. <<r:=vbc2a r;
  875. if not numberp r and not constant_exprp r then
  876. for each p in cdr fctrf numr simp r do
  877. <<p:=prepf car p;
  878. if not member(p,glterms)then nconc(glterms,{p})>> >>;
  879. symbolic procedure sfcont f;
  880. % Calculate the integer content of standard form f.
  881. if domainp f then f else gcdf(sfcont lc f,sfcont red f);
  882. symbolic procedure vdplmon u;vdpfmon(vdplbc u,vdplbc u);
  883. symbolic procedure vdpmember3(p,g1,g2,g3);
  884. % Test membership of p in one of then lists g1,g2,g3.
  885. vdpmember(p,g1)or vdpmember(p,g2)or vdpmember(p,g3);
  886. symbolic procedure groebabortid(base,abort1);
  887. % Test whether one of the elements in abort1 is
  888. % member of the ideal described by base. Definite
  889. % test here.
  890. if null abort1 then nil else
  891. vdpzero!?(groebnormalform(car abort1,base,'list))
  892. or groebabortid(base,cdr abort1);
  893. endmodule;;end;