buchbg.red 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  1. module buchbg; % Central Groebner base code: Buchberger algorithm.
  2. % Authors: H. Melenk, H.M. Moeller, W. Neun
  3. % ZIB Berlin
  4. % July 1988
  5. fluid '(!*gcd);
  6. fluid '( % switches from the user interface
  7. !*groebopt !*groebfac !*groebres !*trgroeb !*trgroebs !*groebrm
  8. !*trgroeb1 !*trgroebr !*groebprereduce groebrestriction!*
  9. !*groebfullreduction !*groebstat !*groebdivide !*groebprot
  10. !*groebheufact !*groebweak !*groelterms
  11. vdpvars!* % external names of the variables
  12. !*vdpinteger !*vdpmodular % indicating type of algorithm
  13. vdpsortmode!* % term ordering mode
  14. secondvalue!* thirdvalue!* % auxiliary: multiple return values
  15. fourthvalue!*
  16. groebdomain!* % domain mode if selected explicitly
  17. factortime!* % computing time spent in factoring
  18. factorlevel!* % bookkeeping of factor tree
  19. groefeedback!* % sideeffect factorization
  20. groesfactors!* % data structure for act. fact.
  21. pairsdone!* % list of pairs already calculated
  22. probcount!* % counting subproblems
  23. vbccurrentmode!* % current domain for base coeffs.
  24. vbcmodule!* % for modular calculation:
  25. % current prime
  26. groetime!*
  27. !*gsugar % enable Traverso's sugar technique
  28. groecontcount!* % control of content reduction
  29. gmodule!* % internal module basis
  30. groebabort!* % input abort conditions
  31. );
  32. global '(groebrestriction % interface:
  33. % name of restriction function
  34. groebresmax % maximum number of internal results
  35. gvarslast % output: variable list
  36. groebmonfac % minimum exponent for reduction of
  37. % monomial factors
  38. groebprotfile % reduction protocol
  39. glterms % list for lterms collection
  40. );
  41. flag ('(groebrestriction groebresmax gvarslast groebmonfac
  42. groebprotfile glterms), 'share);
  43. groebrestriction := nil;
  44. groebresmax := 300;
  45. groebmonfac := 1;
  46. groecontcount!* := 10;
  47. !*groebfullreduction := t;
  48. !*gsugar := t;
  49. !*groelterms := t;
  50. switch groebopt,groebres,trgroeb,trgroebs,trgroeb1,
  51. trgroebr,groebfullreduction,groebstat,groebprot;
  52. % variables for counting and numbering
  53. fluid '(hcount!* pcount!* mcount!* fcount!* bcount!* b4count!*
  54. basecount!* hzerocount!*);
  55. % option ' groebopt' "optimizes" the given input
  56. % polynomial set ( variable
  57. % ordering )
  58. % option ' trgroeb' prints intermediate
  59. % results on the output file
  60. % option ' trgroeb1' prints internal representation
  61. % of critical pair list d
  62. % option ' trgroebs ' prints S - polynomials
  63. % on the output file
  64. % option trgroebr prints (intermediate) results and
  65. % computation statistics
  66. % groebstat the statistics are printed
  67. % groebres the H- polynomials are optimised using resultant
  68. % and factorisation method
  69. %
  70. % groebrm multiplicities of factors in h-polynomials are reduced
  71. % to simple factors.
  72. %
  73. % groebdivide
  74. % the algorithm avoids all divisions (only for modular
  75. % calculation) , if this switch is set off;
  76. %
  77. % groebprot Write a protocol to the variable "groebprotfile";
  78. !*groebfullreduction := t;
  79. %!*groebPreReduce := T;
  80. !*groebdivide := t;
  81. % the code for checkpointing is factored out
  82. % This version: NO CHECKPOINT FACILITY
  83. smacro procedure groebcheckpoint1(); list nil;
  84. smacro procedure groebcheckpoint2(); list nil;
  85. smacro procedure groebcheckpoint2a(); list nil;
  86. smacro procedure groebcheckpoint3(); list nil;
  87. smacro procedure groebcheckpoint4(); list nil;
  88. smacro procedure groebcheckpoint5(); list nil;
  89. symbolic procedure buch!-vevdivides!? (vev1,vev2);
  90. % test: vev1 divides vev2 ? for exponent vectors vev1,vev2
  91. vevmtest!? (vev2,vev1) and
  92. (null gmodule!* or gevcompatible1(vev1,vev2,gmodule!*));
  93. symbolic procedure gevcompatible1(v1,v2,g);
  94. % test whether v1 and v2 belong to the same vector column.
  95. if null g then t
  96. else if null v1 then (null v2 or gevcompatible1('(0),v2,g))
  97. else if null v2 then gevcompatible1(v1,'(0),g) else
  98. (car g = 0 or car v1 = car v2) and
  99. gevcompatible1(cdr v1,cdr v2,cdr g);
  100. symbolic procedure gcompatible(f,h);
  101. null gmodule!* or
  102. gevcompatible1(vdpevlmon f,vdpevlmon h,gmodule!*);
  103. symbolic procedure groebmakepair(f,h);
  104. % construct a pair from polynomials f and h
  105. begin scalar ttt,sf,sh;
  106. ttt:=tt(f,h);
  107. return if !*gsugar then
  108. <<sf:=gsugar(f) #+ vevtdeg vevdif(ttt,vdpevlmon f);
  109. sh:=gsugar(h) #+ vevtdeg vevdif(ttt,vdpevlmon h);
  110. list(ttt,f,h,max(sf,sh))>>
  111. else list(ttt,f,h);
  112. end;
  113. % the 1-polynomial will be constructed at run time
  114. % because the length of the vev is not known in advance
  115. fluid '(vdpone!*);
  116. symbolic procedure vdponepol;
  117. % construct the polynomial=1
  118. vdpone!* := vdpfmon(a2vbc 1,vevzero());
  119. symbolic procedure groebner2(p,r);
  120. % setup all global variables for the Buchberger algorithm
  121. % printing of statistics
  122. begin scalar groetime!*,tim1,spac,spac1,p1,factortime!*,
  123. pairsdone!*,factorlevel!*,groesfactors!*,!*gcd;
  124. factortime!* := 0;
  125. groetime!* := time();
  126. vdponepol(); % we construct dynamically
  127. hcount!* := 0; mcount!* := 0; fcount!* := 0;
  128. bcount!* := 0; b4count!* := 0; hzerocount!* := 0;
  129. basecount!* := 0; !*gcd := t; glterms := list('list);
  130. groecontcount!* := 10;
  131. if !*trgroeb then
  132. << prin2 "Groebner Calculation starting ";
  133. terprit 2;
  134. prin2 " groebopt: "; print !*groebopt;
  135. >>;
  136. spac := gctime();
  137. p1:= if !*groebfac or null !*gsugar
  138. then groebbasein (p,!*groebfac,!*groebres,r)
  139. where !*gsugar=nil
  140. else gtraverso(p,nil,nil,nil);
  141. if !*trgroeb or !*trgroebr or !*groebstat then
  142. <<
  143. spac1 := gctime() - spac;
  144. terpri();
  145. prin2t "statistics for GROEBNER calculation";
  146. prin2t "===================================";
  147. prin2 " total computing time (including gc): ";
  148. prin2((tim1 := time()) - groetime!*);
  149. prin2t " milliseconds ";
  150. if factortime!* neq 0 then
  151. <<prin2 " (time spent in FACTOR (excl. gc): ";
  152. prin2 factortime!*;
  153. prin2t " milliseconds)";
  154. >>;
  155. prin2 " (time spent for garbage collection: ";
  156. prin2 spac1;
  157. prin2t " milliseconds)";
  158. terprit 1;
  159. prin2 "H-polynomials total: "; prin2t hcount!*;
  160. prin2 "H-polynomials zero : "; prin2t hzerocount!*;
  161. prin2 "Crit M hits: "; prin2t mcount!*;
  162. prin2 "Crit F hits: "; prin2t fcount!*;
  163. prin2 "Crit B hits: "; prin2t bcount!*;
  164. prin2 "Crit B4 hits: "; prin2t b4count!*;
  165. >>;
  166. return p1;
  167. end;
  168. smacro procedure testabort h;
  169. vdpmember (h,abort1) or
  170. 'cancel = (abort2 := groebtestabort(h,abort2));
  171. symbolic procedure groebenumerate f;
  172. % f is a temporary result. Prepare it for medium range storage
  173. % and ssign a number
  174. if vdpzero!? f then f else
  175. << vdpcondense f;
  176. if not vdpgetprop(f,'number) then
  177. <<f := vdpputprop(f,'number,(pcount!* := pcount!* #+ 1));
  178. if !*groebprot then
  179. << groebprotsetq(mkid('poly,pcount!*),'candidate);
  180. vdpputprop(f,'groebprot,mkid('poly,pcount!*));
  181. >>;
  182. >>;
  183. f>>;
  184. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  185. % Buchberger's Algorithm
  186. %
  187. % INPUT : G0 = { f1, ... , fr} set of nonzero polynomials
  188. % OUTPUT: groebner basis (list of nonzero polynomials)
  189. %
  190. % internal variables:
  191. %
  192. % problems list of problems to be processed. problems is non nil,
  193. % if the inital problem was split by a successful factoring
  194. % results collection of results from problems
  195. % G basis under construction
  196. % G1 local pointer to G
  197. % D list of critical pairs during algorithm
  198. % D1,D2 local lists of pairs during update of D
  199. % f,fj polynomials
  200. % p,p1,p2 pairs
  201. % s,h polynomials in the central part of the algorithm
  202. % (the "s-poly" and the "h-poly" selon Buchberger
  203. % G99 set of polynomials used for reduction. Held as
  204. % a search tree
  205. % abort1 list of polynomials in factorization context.
  206. % a calculation branch can be cancelled if one of
  207. % these polys is detected
  208. % abort2 list of sets of polynomials. If a new h polynomial
  209. % is calculated, it should be removed from the sets.
  210. % if one set becomes null, the set restriction is
  211. % fulfilled and the branch can be cancelled
  212. symbolic procedure groebbasein (g0,fact,groebres,abort1);
  213. begin scalar problems, results, abort2,x,
  214. g,g1,d,d1,d2,p,p1,s,h,g99,hlist,lv,lasth;
  215. integer gvbc, probcount!*;
  216. groebabort!* := abort1;
  217. lv := length vdpvars!*;
  218. groebcheckpoint1();
  219. for each p in g0 do
  220. if vdpzero!? p then g0 := delete(p,g0);
  221. if !*groebprereduce then g0 := groebprereduce g0;
  222. x := for each fj in g0 collect
  223. <<groebsavelterm fj;
  224. gsetsugar(vdpenumerate vdpsimpcont fj,nil)>>;
  225. if !*groebprot then
  226. for each f in x do
  227. << groebprotsetq(mkid('poly,h:= vdpnumber f), vdp2a f);
  228. vdpputprop(f,'groebprot,mkid('poly,h))>>;
  229. g0 := x;
  230. % establish the initial problem
  231. problems := list (list (nil,nil,nil,g0,abort1,nil,nil,
  232. vbccurrentmode!*, nil,nil) );
  233. !*trgroeb and groebmess1(g,d);
  234. goto macroloop;
  235. groebcheckpoint2();
  236. macroloop:
  237. while problems and gvbc < groebresmax do
  238. begin
  239. groebcheckpoint2a();
  240. % pick up next problem
  241. x := car problems;
  242. groebcheckpoint3();
  243. d := car x;
  244. g := cadr x;
  245. g99 := groebstreereconstruct caddr x;
  246. g0 := cadddr x;
  247. abort1 := nth(x,5);
  248. abort2 := nth(x,6);
  249. pairsdone!* := nth(x,7);
  250. h := nth(x,8); % vbcCurrentMode!*
  251. factorlevel!* := nth(x,9);
  252. groesfactors!* := nth(x,10);
  253. groebcheckpoint4();
  254. problems := cdr problems;
  255. g0 := % sort G0, but keep factor in first position
  256. if factorlevel!* and g0 and cdr g0 then car g0 . vdplsort cdr g0
  257. else vdplsort g0;
  258. x := nil;
  259. lasth := nil;
  260. !*trgroeb and groebmess23 (g0,abort1,abort2);
  261. while d or g0 do
  262. begin
  263. if groebfasttest(g0,g,d,g99) then goto stop;
  264. !*trgroeb and groebmess50(g);
  265. if g0 then
  266. << h := car g0;
  267. g0 := cdr g0;
  268. gsetsugar(h,nil);
  269. groebsavelterm h;
  270. p := list(nil,h,h); >>
  271. else
  272. << p := car d;
  273. d := delete (p,d);
  274. s := groebspolynom (cadr p, caddr p);
  275. if fact then
  276. pairsdone!* := (vdpnumber cadr p
  277. . vdpnumber caddr p)
  278. . pairsdone!*;
  279. !*trgroeb and groebmess3 (p,s);
  280. h:=groebnormalform(s,g99,'tree);
  281. groebsavelterm h;
  282. h:=groebsimpcontnormalform h;
  283. if vdpzero!? h then !*trgroeb and groebmess4(p,d);
  284. % test for possible chains
  285. if not vdpzero!? h then % only for real h's
  286. << s := groebchain (h,cadr p,g99);
  287. if s = h then
  288. h := groebchain (h,caddr p,g99);
  289. if secondvalue!* then
  290. g := delete(secondvalue!*,g)>>; >>;
  291. if vdpzero!? h then goto bott;
  292. if vevzero!? vdpevlmon h then % base 1 found
  293. << !*trgroeb and groebmess5(p,h); goto stop>>;
  294. if testabort(h) then
  295. << !*trgroeb and groebmess19(h,abort1,abort2);
  296. goto stop>>;
  297. s:= nil;
  298. % look for implicit or explicit factorization
  299. hlist := nil;
  300. if groebrestriction!* then
  301. hlist := groebtestrestriction(h,abort1);
  302. if not hlist and fact then
  303. hlist := groebfactorize(h,abort1,g,g99);
  304. if hlist = 'zero then goto bott;
  305. if groefeedback!* then g0 := append(groefeedback!*,g0);
  306. groefeedback!* := nil;
  307. % factorisation found but only one factor survived
  308. if hlist and length hlist = 2 then
  309. <<h := car cadr hlist; hlist := nil>>;
  310. if not hlist and groebres then
  311. <<hlist := groebtestresultant(lasth,h,lv);
  312. if hlist then groebres := nil>>;
  313. if hlist then
  314. <<if hlist neq 'cancel then
  315. problems:=
  316. groebencapsulate(hlist,d,g0,g,g99,
  317. abort1,abort2,problems,fact);
  318. go stop>>;
  319. % h polynomial is accepted now
  320. h := groebenumerate h; !*trgroeb and groebmess5(p,h);
  321. % construct new critical pairs
  322. d1 := nil;
  323. !*trgroeb and groebmess50(g);
  324. for each f in g do
  325. if(car p or % that means "not an input polynomial"
  326. not member (vdpnumber h . vdpnumber f, pairsdone!*)
  327. ) and gcompatible(f,h) then
  328. <<d1 := groebcplistsortin(groebmakepair(f,h),d1);
  329. if tt(f,h) = vdpevlmon(f) then
  330. <<g := delete (f,g);
  331. !*trgroeb and groebmess2 f>> >>;
  332. !*trgroeb and groebmess51(d1);
  333. d2 := nil;
  334. while d1 do
  335. <<d1 := groebinvokecritf d1;
  336. p1 := car d1; d1 := cdr d1;
  337. d2 := groebinvokecritbuch4 (p1,d2);
  338. d1 := groebinvokecritm (p1,d1) >>;
  339. d := groebinvokecritb (h,d);
  340. d := groebcplistmerge(d,d2);
  341. % monomials and binomials
  342. if vdplength h < 3 and car p then
  343. <<g := groebsecondaryreduction (h,g,g99,d,nil,t);
  344. if g = 'abort then goto stop;
  345. g99 := secondvalue!*;
  346. d := thirdvalue!*>>;
  347. g := h . g;
  348. lasth := h;
  349. g99 := groebstreeadd(h, g99);
  350. !*trgroeb and groebmess8(g,d);
  351. goto bott;
  352. stop: d := g := g0 := nil;
  353. bott: groebcheckpoint5();
  354. end;
  355. g := vdplsort g; % such that T descending
  356. x := groebbasein2(g,g99,problems,abort1,abort2,fact);
  357. g1 := car x; problems := cdr x;
  358. if g1 then <<results := g1 . results; gvbc := gvbc+1>>;
  359. !*trgroeb and groebmess13(g1,problems);
  360. end;
  361. if gvbc >= groebresmax then
  362. lpriw("########","warning: GROEBRESMAX limit reached");
  363. return groebbasein3 results;
  364. end;
  365. symbolic procedure groebfasttest(g0,g,d,g99);
  366. <<g := g0 := d := g99 := nil; nil>>;
  367. % a hook for special techniques
  368. symbolic procedure groebbasein2(g,g99,problems,abort1,abort2,fact);
  369. % final reduction for a base G: reduce each polynomial with the
  370. % other members; here again support of factorization
  371. begin scalar !*groebfullreduction,!*groebheufact; % saving value
  372. scalar g1,f,h,hlist,x,!*gsugar; integer cnt;
  373. !*groebfullreduction := t;
  374. g1 := nil;
  375. while g do
  376. <<h := car g;
  377. g := cdr g;
  378. if !*groebprot then
  379. groebprotsetq('candidate,mkid('poly,vdpnumber h));
  380. h := groebnormalform (h,g,'sort);
  381. f := groebsimpcontnormalform h;
  382. !*trgroeb and groebmess26(h,f);
  383. if !*groebprot then
  384. groebprotsetq({'gb,cnt:=cnt+1},'candidate);
  385. if vdpone!? f then <<g1 := g := nil>>; % base {1} found
  386. % very late now
  387. if fact and not vdpzero!? f then
  388. << hlist := groebfactorize (f,abort1,nil,nil);
  389. if not null hlist then
  390. << % lift structure
  391. hlist := for each x in cdr hlist collect car x;
  392. % discard superfluous factors
  393. for each h in hlist do
  394. if vdpmember(h,abort1) then
  395. <<hlist := delete(h,hlist);
  396. !*trgroeb and
  397. groebmess19(h,abort1,abort2)>>;
  398. % generate new subproblems
  399. x := 0;
  400. for each h in hlist do
  401. <<hlist := delete(h,hlist);
  402. h := groebenumerate h;
  403. problems:=
  404. list(nil, % null D
  405. append(g1,g), % base
  406. g99, % G99
  407. list h, % G0
  408. append(hlist,abort1),
  409. abort2,
  410. pairsdone!*,
  411. vbccurrentmode!*,
  412. (x := x+1) . factorlevel!*,
  413. groesfactors!*
  414. ) . problems;
  415. >>;
  416. g := g1 := nil; % cancel actual final reduction
  417. f := nil;
  418. >>
  419. >>;
  420. if f and vdpevlmon h neq vdpevlmon f then
  421. <<g:= vdplsort append(g,f . g1); g1 := nil>> else
  422. if f and not vdpzero!? f then g1 := append (g1 ,list f);
  423. >>;
  424. return g1.problems;
  425. end;
  426. symbolic procedure groebbasein3 results;
  427. % final postprocessing : remove multiple bases from the result
  428. begin scalar x,g,f,p1,p2;
  429. x := nil; g := results; p1 := p2 := 0;
  430. while results do
  431. <<if vdpone!? car car results % exclude multiple {1}
  432. then p1 := p1 + 1 % count ones
  433. else
  434. <<f := for each p in car results % delete props for member
  435. collect vdpremallprops p;
  436. if member (f,x) % each base only once
  437. then p2 := p2 + 1 % count multiples
  438. else if not groeb!-abort!-id(f,groebabort!*)
  439. then x := f . x;
  440. results := cdr results>> >>;
  441. results := if null x then list list vdpone!* else x;
  442. return results;
  443. end;
  444. fluid '( !*vbccompress);
  445. symbolic procedure groebchain(h,f,g99);
  446. % test if a chain from h-plynomials can be computed from the h
  447. begin scalar h1,h2,h3,count,found;
  448. secondvalue!* := nil;
  449. return h; % erst einmal
  450. if not buch!-vevdivides!? (vdpevlmon h, vdpevlmon f)
  451. then return h;
  452. h2 := h;
  453. h1 := f;
  454. found := t;
  455. count := 0;
  456. while found do
  457. <<h3 := groebspolynom(h1,h2);
  458. h3 := groebnormalform(h3,g99,'tree);
  459. h3 := vdpsimpcont h3;
  460. if vdpzero!? h3 then
  461. <<found := nil;
  462. prin2t "chain---------------------------";
  463. vdpprint h1;
  464. vdpprint h2;
  465. vdpprint h3;
  466. secondvalue!* := f;
  467. count := 9999>>
  468. else
  469. if vdpone!? h3 then
  470. <<found := nil;
  471. prin2t "chain---------------------------";
  472. vdpprint h1;
  473. vdpprint h2;
  474. vdpprint h3;
  475. h2 := h3;
  476. count := 9999>>
  477. else
  478. if buch!-vevdivides!?(vdpevlmon h3, vdpevlmon h2)
  479. then <<found := t;
  480. prin2t "chain---------------------------";
  481. vdpprint h1;
  482. vdpprint h2;
  483. vdpprint h3;
  484. h1 := h2;
  485. h2 := h3;
  486. count := count+1>>
  487. else
  488. found := nil;
  489. >>;
  490. return if count > 0 then
  491. << prin2 "CHAIN :"; prin2t count; h2>>
  492. else h;
  493. end;
  494. symbolic procedure groebencapsulate(hlist,d,g0,g,g99,
  495. abort1,abort2,problems,fact);
  496. % hlist is a factorized h poly. This procedure has the job to
  497. % form new problems from hlist and to add them to problems.
  498. % Result is problems.
  499. % Standard procedure: only creation of subproblems
  500. begin scalar factl, % list of factorizations under way
  501. u,y,z;
  502. integer fc;
  503. if length vdpvars!*>10 or car hlist neq 'factor then
  504. return groebencapsulatehardcase(hlist,d,g0,g,g99,
  505. abort1,abort2,problems,fact);
  506. % encapsulate for each factor
  507. factl := groebrecfactl list hlist;;
  508. !*trgroeb and groebmess22 (factl,abort1,abort2);
  509. for each x in reverse factl do
  510. <<y := append (car x, g0);
  511. z := vdpunion (cadr x,abort1);
  512. u := append(caddr x,abort2);
  513. problems := list(
  514. d,
  515. g,
  516. g, % future G99
  517. y, % as new problem
  518. z, % abort1
  519. u, % abort2
  520. pairsdone!*, % pairsdone!*
  521. vbccurrentmode!*,
  522. (fc:= fc+1) . factorlevel!*,
  523. groesfactors!*
  524. ) . problems;
  525. >>;
  526. return problems;
  527. end;
  528. symbolic procedure groebencapsulatehardcase(hlist,d,g0,g,g99,
  529. abort1,abort2,problems,fact);
  530. % hlist is a factorized h poly. This procedure has the job to
  531. % form new problems from hlist and to add them to problems.
  532. % Result is problems.
  533. % First the procedure tries to compute new h-polynomials from the
  534. % remaining pairs which are not affected by the factors in hlist.
  535. % purpose is to find further factorizations and to do calculations
  536. % in common for all factors in order to shorten the separate later
  537. % branches;
  538. begin scalar factl, % list of factorizations under way
  539. factr, % variables under factorization
  540. u,h,d1,d2,p1,y,z,p,s,f,gc,pd,break,fl1;
  541. integer fc;
  542. factl := list hlist;
  543. factr := vdpspace car cadr hlist;
  544. for each x in cdr hlist do
  545. for each p in x do
  546. factr := vevunion(factr,vdpspace p);
  547. % ITER:
  548. % now process additional pairs
  549. while d or g0 do
  550. begin
  551. break := nil;
  552. if g0 then
  553. << % next poly from input
  554. s := car g0; g0 := cdr g0; p := list(nil,s,s);
  555. >>
  556. else
  557. << % next poly fropm pairs
  558. p := car d; d := delete (p,d);
  559. if not vdporthspacep(car p,factr) then
  560. s:= nil else
  561. <<s := groebspolynom (cadr p, caddr p);
  562. !*trgroeb and groebmess3 (p,s);>>;
  563. >>;
  564. if null s or not vdporthspacep(vdpevlmon s,factr) then
  565. << % throw away s polynomial
  566. f := cadr p;
  567. if not vdpmember3(f,g0,g,gc)
  568. then gc := f . gc;
  569. f := caddr p;
  570. if car p and not vdpmember3 (f,g0,g,gc)
  571. then gc := f . gc;
  572. goto bott>>;
  573. h := groebnormalform(s,g99,'tree);
  574. if vdpzero!? h and car p then
  575. !*trgroeb and groebmess4(p,d);
  576. if not vdporthspacep(vdpevlmon h,factr) then
  577. << % throw away h polynomial
  578. f := cadr p;
  579. if not vdpmember3(f,g0,g,gc)
  580. then gc := f . gc;
  581. f := caddr p;
  582. if car p and not vdpmember3 (f,g0,g,gc)
  583. then gc := f . gc;
  584. goto bott>>;
  585. %%% if car p then
  586. %%% pairsdone!* := (vdpnumber cadr p . vdpnumber caddr p)
  587. %%% . pairsdone!*;
  588. if vdpzero!? h then goto bott;
  589. if vevzero!? vdpevlmon h then % base 1 found
  590. goto stop;
  591. h := groebsimpcontnormalform h; % coefficients normalized
  592. if testabort h then
  593. <<!*trgroeb and groebmess19(h,abort1,abort2);
  594. goto stop>>;
  595. s:= nil;
  596. hlist := nil;
  597. if groebrestriction!* then
  598. hlist := groebtestrestriction(h,abort1);
  599. if hlist = 'cancel then goto stop;
  600. if not hlist and fact then
  601. hlist := groebfactorize(h,abort1,g,g99);
  602. if groefeedback!* then g0 := append(groefeedback!*,g0);
  603. groefeedback!* := nil;
  604. if hlist and length hlist = 2 then
  605. <<h := car cadr hlist; hlist := nil>>;
  606. if hlist then
  607. << for each x in cdr hlist do
  608. for each h in x do
  609. factr := vevunion(factr,vdpspace h);
  610. factl := hlist . factl; % add to factors
  611. goto bott>>;
  612. h := groebenumerate h; % ready now
  613. !*trgroeb and groebmess5(p,h);
  614. % construct new critical pairs
  615. d1 := nil;
  616. for each f in g do
  617. if tt(f,h) = vdpevlmon(f) and gcompatible(f,h) then
  618. <<g := delete (f,g);
  619. d1 := groebcplistsortin( groebmakepair(f,h) , d1);
  620. !*trgroeb and groebmess2 f;
  621. >>;
  622. !*trgroeb and groebmess51(d1);
  623. d2 := nil;
  624. while d1 do
  625. <<d1 := groebinvokecritf d1;
  626. p1 := car d1; d1 := cdr d1;
  627. d2 := groebinvokecritbuch4 (p1,d2);
  628. d1 := groebinvokecritm (p1,d1);
  629. >>;
  630. d := groebinvokecritb (h,d);
  631. d := groebcplistmerge(d,d2);
  632. if vdplength h < 3 then
  633. <<g := groebsecondaryreduction (h,g,g99,d,gc,t);
  634. if g = 'abort then goto stop;
  635. g99 := secondvalue!*;
  636. d := thirdvalue!*;
  637. gc := fourthvalue!*>>;
  638. g := h . g;
  639. g99 := groebstreeadd(h, g99);
  640. !*trgroeb and groebmess8(g,d);
  641. goto bott;
  642. stop:
  643. d := g := g0 := gc := factl := nil;
  644. bott:
  645. end; %ITER
  646. % now collect all relvevant polys
  647. g0 := vdpunion(g0,vdpunion(g,gc));
  648. % encapsulate for each factor
  649. if factl then
  650. << factl := groebrecfactl factl;
  651. !*trgroeb and groebmess22 (factl,abort1,abort2);
  652. >>;
  653. for each x in reverse factl do
  654. <<fl1 := (fc := fc+1) . factorlevel!*;
  655. break:= nil;
  656. y := append (car x, g0);
  657. z := vdpunion (cadr x,abort1);
  658. u := append(caddr x,abort2);
  659. if vdpmember(vdpone!*,y) then break:=vdpone!*;
  660. % inspect the unreduced list first
  661. if not break then for each p in z do
  662. if vdpmember(p,y) then break := p;
  663. % now prepare the reduced list
  664. if not break then
  665. <<y := append (car x,groebreducefromfactors(g0,car x));
  666. pd := secondvalue!*;
  667. if vdpmember(vdpone!*,y) then break := vdpone!* else
  668. for each p in z do if vdpmember(p,y) then break := p;
  669. pd := subla(pd,pairsdone!*);
  670. >>;
  671. if not break then
  672. problems := list(
  673. nil, % new D
  674. nil, % new G
  675. nil, % future G99
  676. y, % as new problem
  677. z, % abort1
  678. u, % abort2
  679. nil, % pairsdone!*
  680. vbccurrentmode!*,
  681. fl1, % factorlevel!*,
  682. groesfactors!* % factor db
  683. ) . problems
  684. else !*trgroeb and groebmess19a(break,fl1);
  685. >>;
  686. return problems;
  687. end;
  688. symbolic procedure groebrecfactl (factl);
  689. % factl is a list of factorizations:a list of lists of vdps
  690. % generate calculation pathes from them
  691. begin scalar rf,res,type;
  692. if null factl then return list list(nil,nil,nil);
  693. rf := groebrecfactl (cdr factl);
  694. factl := car factl;
  695. type := car factl; % FACTOR or RESTRICT
  696. factl := cdr factl;
  697. while factl do
  698. <<for each y in rf do
  699. if vdpdisjoint!?(car factl,cadr y) then
  700. res := list( vdpunion(car factl,car y),
  701. (if type = 'factor then
  702. append (for each x in cdr factl collect car x,
  703. cadr y)
  704. else
  705. if type = 'resultant then
  706. append (for each x in cdr factl collect cadr x,
  707. cadr y)
  708. else cadr y),
  709. (if type neq 'factor and type neq 'resultant then
  710. append(cdr factl,caddr y)
  711. else caddr y)
  712. ) . res;
  713. factl := cdr factl>>;
  714. return res;
  715. end;
  716. symbolic procedure groebtestabort (h,abort2);
  717. % tests if h is member of one of the sets in abort2.
  718. % if yes, it is deleted. If one wet becomes null, the message
  719. % "CANCEL is returned, otherwise the updated abort2.
  720. begin scalar x,break,res;
  721. % car test the occurence
  722. x := abort2;
  723. while x and not break do
  724. << if vdpmember(h,car x) then break := t;
  725. x := cdr x>>;
  726. if not break then return abort2; % not relvevant
  727. break := nil;
  728. while abort2 and not break do
  729. <<x := vdpdeletemember(h,car abort2);
  730. if null x then break := t;
  731. res := x . res;
  732. abort2 := cdr abort2;
  733. >>;
  734. !*trgroeb and groebmess25(h,res);
  735. if break then return 'cancel;
  736. return res;
  737. end;
  738. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  739. %
  740. % Reduction of polynomials
  741. %
  742. symbolic procedure groebnormalform(f,g,type);
  743. % general procedure for reduction of one polynomial from a set
  744. % f is a polynomial, G is a Set of polynomials either in
  745. % a search tree or in a sorted list
  746. % type describes the ordering of the set G:
  747. % 'TREE G is a search tree
  748. % 'SORT G is a sorted list
  749. % 'LIST G is a list, but not sorted
  750. % f has to be reduced modulo G
  751. begin scalar f0,f1,c,vev,divisor,break,done,fold,a;
  752. integer n,s1,s2;
  753. if !*groebweak and !*vdpinteger
  754. and groebweakzerotest(f,g,type) then return f2vdp nil;
  755. fold := f; f1 := vdpzero(); a:= vbcfi 1;
  756. gsetsugar(f1,gsugar f);
  757. while not vdpzero!? f do
  758. begin
  759. vev:=vdpevlmon f; c:=vdplbc f;
  760. if not !*groebfullreduction and not vdpzero!? f1 then
  761. g := nil; % cut off
  762. if type = 'sort then
  763. while g and vevcompless!?(vev,vdpevlmon car g)
  764. do g := cdr g;
  765. if null g then
  766. <<f1:=vdpsum (f1,f); f:=vdpzero();
  767. break := t; divisor := nil; goto ready>>;
  768. divisor :=
  769. if type = 'tree then groebsearchinstree(vev,g)
  770. else groebsearchinlist (vev,g);
  771. if divisor then done := t; % true action indicator
  772. if divisor and !*trgroebs then
  773. << prin2 "//-";
  774. prin2 vdpnumber divisor;
  775. >>;
  776. if divisor then
  777. if vdplength divisor = 1 then
  778. f := vdpcancelmvev(f,vdpevlmon divisor)
  779. else
  780. if !*vdpinteger or not !*groebdivide then
  781. << f:=groebreduceonestepint(f,f1,c,vev,divisor);
  782. f1 := secondvalue!*; n := n+1;
  783. if not vdpzero!? f and
  784. n #> groecontcount!* then
  785. <<f0 := f;
  786. f:=groebsimpcont2(f,f1);
  787. groecontentcontrol(f neq f0);
  788. f1 := secondvalue!*; n := 0 >>;
  789. >>
  790. else
  791. f := groebreduceonesteprat(f,nil,c,vev,divisor)
  792. else
  793. <<!*gsugar and <<s1:=gsugar(f);s2:=gsugar(f1)>>;
  794. f1 := vdpappendmon (f1,vdplbc f,vdpevlmon f);
  795. f := vdpred f;
  796. !*gsugar and <<gsetsugar(f,s1);
  797. gsetsugar(f1,max(s2,s1))>>;
  798. >>;
  799. ready:
  800. end;
  801. if !*groebprot then groebreductionprotocolborder();
  802. if not done then f1 := fold;
  803. return f1;
  804. end;
  805. symbolic procedure groecontentcontrol u;
  806. % u indicates, that a substantial content reduction was done;
  807. % update content reduction limit from u.
  808. groecontcount!*:= if not numberp groecontcount!* then 10 else
  809. if u then max(0,groecontcount!*-1)
  810. else min(10,groecontcount!*+1);
  811. symbolic procedure groebvbcbig!? a;
  812. % test if a is a "big" coefficient
  813. (if numberp x then (x > 1000000000000 or x < -1000000000000)
  814. else t)
  815. where x=vbcnumber a;
  816. symbolic procedure groebsimpcontnormalform h;
  817. % simpCont version preserving the property SUGAR
  818. if vdpzero!? h then h else
  819. begin scalar sugar,c;
  820. sugar :=gsugar h; c:=vdplbc h;
  821. h := vdpsimpcont h;
  822. gsetsugar(h,sugar);
  823. if !*groebprot and not(c=vdplbc h)then
  824. groebreductionprotocol2
  825. reval list('quotient,vbc2a vdplbc h,vbc2a c);
  826. return h;
  827. end;
  828. symbolic procedure groebsimpcont2(f,f1);
  829. % simplify two polynomials with the gcd of their contents;
  830. begin scalar c,s1,s2;
  831. s1:=gsugar f; s2:=gsugar f1;
  832. c := vdpcontent f;
  833. if vbcone!? vbcabs c then goto ready;
  834. if not vdpzero!? f1 then
  835. << c := vdpcontent1(f1,c);
  836. if vbcone!? vbcabs c then goto ready;
  837. f1 := vdpdivmon(f1,c,nil)>>;
  838. f := vdpdivmon(f,c,nil);
  839. !*trgroeb and groebmess28 c;
  840. groebsaveltermbc c;
  841. gsetsugar(f,s1); gsetsugar(f1,s2);
  842. ready:
  843. secondvalue!* := f1; return f;
  844. end;
  845. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  846. %
  847. % special case reductions
  848. %
  849. symbolic procedure groebprereduce g;
  850. % reduce the polynomials in g with themselves.
  851. % the reduction is continued until headterms are stable
  852. % is possible;
  853. begin scalar res,work,oldvev,f,oldf,!*groebweak,!*groebfullreduction;
  854. integer count;
  855. if !*trgroebs then
  856. << g := for each p in g collect vdpenumerate p;
  857. for each p in g do vdpprint p>>;
  858. res := nil; % delete zero polynomials from G
  859. for each f in g do if not vdpzero!? f then res := f . res;
  860. work := g := res := reversip res;
  861. while work do
  862. << g := vdplsort res; % sort prvevious result
  863. if !*trgroebs then prin2t "Starting cycle in prereduction.";
  864. res := nil;
  865. count := count + 1;
  866. work := nil;
  867. while g do
  868. << oldf := f:= car g; g := cdr g;
  869. oldvev := vdpevlmon f;
  870. f := vdpsimpcont groebnormalform (f,g,'sort);
  871. if (!*trgroebs or !*groebprot) and not vdpequal(f,oldf) then
  872. <<f := vdpenumerate f;
  873. if !*groebprot then
  874. if not vdpzero!? f then
  875. groebprotsetq(mkid('poly,vdpnumber f), vdp2a f)
  876. else groebprotval 0;
  877. if !*trgroebs then
  878. <<prin2t "reducing"; vdpprint oldf; prin2t "to";
  879. vdpprint f>>;
  880. >>;
  881. if not vdpzero!? f then
  882. <<if oldvev neq vdpevlmon f then work := t;
  883. res := f . res>>;
  884. >>;
  885. >>;
  886. return for each f in res collect vdpsimpcont f;
  887. end;
  888. symbolic procedure groebreducefromfactors (g,facts);
  889. % reduce the polynomials in G from those in facts.
  890. begin scalar new,gnew,f,nold,nnew,numbers;
  891. if !*trgroebs then <<
  892. prin2t "replacing from factors:";
  893. for each x in facts do vdpprin2t x
  894. >>;
  895. while g do
  896. <<f := car g;
  897. g := cdr g;
  898. nold := vdpnumber(f);
  899. new := groebnormalform(f,facts,'list);
  900. if vdpzero!? new then
  901. << if !*trgroebs then <<prin2 "vanishes ";
  902. prin2 vdpnumber f
  903. >>;
  904. >>
  905. else
  906. if vevzero!? vdpevlmon new then
  907. << if !*trgroebs then <<prin2 "ONEPOL ";
  908. prin2 vdpnumber f
  909. >>;
  910. g := nil;
  911. gnew := list vdpone!*;
  912. >>
  913. else
  914. <<
  915. if new neq f then
  916. <<new := vdpenumerate vdpsimpcont new;
  917. nnew := vdpnumber new;
  918. numbers := (nold . nnew) . numbers;
  919. if !*trgroebs then <<prin2 "replacing ";
  920. prin2 vdpnumber f;
  921. prin2 " by ";
  922. prin2t vdpnumber new
  923. >>;
  924. >>;
  925. gnew := new . gnew;
  926. >>;
  927. >>;
  928. secondvalue!* := numbers;
  929. return gnew;
  930. end;
  931. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  932. %
  933. % support for Reduction by "simple" polynomials
  934. symbolic procedure groebnormalform1(f,p);
  935. % short version; reduce f by p
  936. % special case: p is a nomomial
  937. if vdplength p = 1 then vdpcancelmvev(f,vdpevlmon p)
  938. else groebnormalform(f,list p,nil);
  939. symbolic procedure groebprofitsfromvev(p,vev);
  940. % tests, if at least one monomial from p would be reduced by vev
  941. if vdpzero!? p then nil
  942. else
  943. if buch!-vevdivides!?(vev, vdpevlmon p) then t
  944. else
  945. groebprofitsfromvev(vdpred p,vev);
  946. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  947. %
  948. % special reduction procedures
  949. symbolic procedure groebreduceonestepint(f,f1,c,vev,g1);
  950. % reduction step for integer case:
  951. % calculate f= a*f - b*g a,b such that leading term vanishes
  952. % (vev of lvbc g divides vev of lvbc f)
  953. %
  954. % and calculate f1 = a*f1
  955. % return value=f, secondvalue=f1
  956. begin scalar vevlcm,a,b,cg,x,rg1;
  957. % trivial case: g1 single monomial
  958. if vdpzero!? (rg1:= vdpred g1)
  959. then return <<f := vdpred f; secondvalue!* := f1; f>>;
  960. vevlcm := vevdif(vev,vdpevlmon g1);
  961. cg := vdplbc g1;
  962. % calculate coefficient factors
  963. x := if not !*groebdivide then vbcfi 1 else vbcgcd(c,cg);
  964. a := vbcquot(cg,x);
  965. b := vbcquot(c,x);
  966. % multiply relvevant parts from f and f1 by a (vbc)
  967. if f1 and not vdpzero!? f1 then f1 := vdpvbcprod(f1,a);
  968. if !*groebprot then groebreductionprotocol(a,vbcneg b,vevlcm,g1);
  969. f:= vdpilcomb1 (vdpred f, a, vevzero(),
  970. rg1,vbcneg b, vevlcm);
  971. % return with f and f1
  972. secondvalue!*:= f1;
  973. thirdvalue!* := a;
  974. return f;
  975. end;
  976. symbolic procedure groebreduceonesteprat(f,dummy,c,vev,g1);
  977. % reduction step for rational case:
  978. % calculate f= f - g/vdpLbc(f)
  979. %
  980. begin scalar x,rg1,vevlcm;
  981. % trivial case: g1 single monomial
  982. dummy := nil;
  983. if vdpzero!? (rg1 := vdpred g1) then return vdpred f ;
  984. % calculate coefficient factors
  985. x := vbcneg vbcquot(c,vdplbc g1);
  986. vevlcm := vevdif(vev,vdpevlmon g1);
  987. if !*groebprot then
  988. groebreductionprotocol(a2vbc 1,x,vevlcm,g1);
  989. return vdpilcomb1(vdpred f,a2vbc 1,vevzero(),
  990. rg1,x,vevlcm);
  991. end;
  992. symbolic procedure groebreductionprotocol(a,b,vevlcm,g1);
  993. if !*groebprot then
  994. groebprotfile :=
  995. if not vbcone!? a then
  996. append(groebprotfile,
  997. list(
  998. list('equal,
  999. 'candidate,
  1000. list('times,'candidate,vbc2a a)),
  1001. list('equal,
  1002. 'candidate,
  1003. list('plus,
  1004. 'candidate,
  1005. list('times,
  1006. vdp2a vdpfmon(b,vevlcm),
  1007. mkid('poly,vdpnumber g1) )))
  1008. ) )
  1009. else
  1010. append(groebprotfile,
  1011. list(
  1012. list('equal,
  1013. 'candidate,
  1014. list('plus,
  1015. 'candidate,
  1016. list('times,
  1017. vdp2a vdpfmon(b,vevlcm),
  1018. mkid('poly,vdpnumber g1) )))
  1019. ) ) ;
  1020. symbolic procedure groebreductionprotocol2 a;
  1021. if !*groebprot then
  1022. groebprotfile :=
  1023. if not(a=1) then
  1024. append(groebprotfile,
  1025. list(
  1026. list('equal,
  1027. 'candidate,
  1028. list('times,'candidate,a))));
  1029. symbolic procedure groebreductionprotocolborder();
  1030. append(groebprotfile,'!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+ . nil);
  1031. symbolic procedure groebprotsetq(a,b);
  1032. groebprotfile :=
  1033. append (groebprotfile,
  1034. list (list ('equal,a,b)));
  1035. symbolic procedure groebprotval a;
  1036. groebprotfile :=
  1037. append (groebprotfile,
  1038. list (list ('equal,'intermediateresult,a)));
  1039. symbolic procedure subset!?(s1,s2);
  1040. % tests if s1 is a subset of s2
  1041. if null s1 then t
  1042. else
  1043. if member(car s1,s2) then subset!?(cdr s1,s2)
  1044. else
  1045. nil;
  1046. symbolic procedure vevsplit (vev);
  1047. % split vev such that each exponent vector has only one 1
  1048. begin scalar n,vp,e;
  1049. n := 0;
  1050. for each x in vev do
  1051. <<n := n+1;
  1052. if x neq 0 then
  1053. <<e := append (vdpevlmon vdpone!*,nil);
  1054. rplaca(pnth(e,n),1);
  1055. vp := e . vp;
  1056. >>;
  1057. >>;
  1058. return vp;
  1059. end;
  1060. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1061. %
  1062. % calculation of an S-polynomial
  1063. %
  1064. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1065. %general strategy:
  1066. %
  1067. % groebSpolynom4 calculates the traditional s-Polynomial from p1,p2
  1068. % (linear combination such that the highest term vanishes).
  1069. % groebSpolynom2 subtracts multiples of p2 from the s-polynomial such
  1070. % that head terms are eliminated early.
  1071. symbolic procedure groebspolynom (p1,p2);
  1072. groebspolynom2(p1,p2);
  1073. symbolic procedure groebspolynom2 (p1,p2);
  1074. if vdpzero!? p1 then p2 else if vdpzero!? p2 then p1 else
  1075. begin scalar s,tp1,tp2,ts,cand;
  1076. s := groebspolynom3(p1,p2);
  1077. if vdpzero!? s or vdpone!? s or !*groebprot then return s;
  1078. tp1 := vdpevlmon p1; tp2 := vdpevlmon p2;
  1079. while not vdpzero!? s
  1080. and ((buch!-vevdivides!?(tp2,(ts := vdpevlmon s))
  1081. and (cand := p2))
  1082. or
  1083. (buch!-vevdivides!?(tp1,(ts := vdpevlmon s))
  1084. and (cand := p1)))
  1085. do << if !*vdpinteger then
  1086. s := % vdpsimpcont
  1087. groebreduceonestepint(s,nil,vdplbc s,ts,cand)
  1088. else
  1089. % rational, float and modular case
  1090. s := groebreduceonesteprat
  1091. (s,nil,vdplbc s,ts,cand);
  1092. >>;
  1093. return s;
  1094. end;
  1095. symbolic procedure groebspolynom3(p,q);
  1096. begin scalar r;
  1097. r:=groebspolynom4(p,q);
  1098. groebsavelterm r;
  1099. return r;
  1100. end;
  1101. symbolic procedure groebspolynom4 (p1,p2);
  1102. begin scalar ep1,ep2,ep,rp1,rp2,db1,db2,x,r;
  1103. ep1 := vdpevlmon p1; ep2 := vdpevlmon p2;
  1104. ep := vevlcm(ep1, ep2);
  1105. rp1 := vdpred p1; rp2 := vdpred p2;
  1106. gsetsugar(rp1,gsugar p1); gsetsugar(rp2,gsugar p2);
  1107. r:= ( if vdpzero!? rp1 and vdpzero!? rp2 then rp1
  1108. else ( if vdpzero!? rp1 then
  1109. <<db2:=a2vbc 0;
  1110. vdpprod(rp2,
  1111. vdpfmon(db1:=a2vbc 1,
  1112. vevdif(ep, ep2) ) )
  1113. >>
  1114. else if vdpzero!? rp2 then
  1115. <<db1:=a2vbc 0;
  1116. vdpprod(rp1,
  1117. vdpfmon(db2:=a2vbc 1,
  1118. vevdif(ep, ep1) ) )
  1119. >>
  1120. else
  1121. <<db1 := vdplbc p1;
  1122. db2 := vdplbc p2;
  1123. if !*vdpinteger then
  1124. << x:= vbcgcd (db1,db2);
  1125. if not vbcone!? x then
  1126. << db1 := vbcquot (db1,x);
  1127. db2 := vbcquot (db2,x);
  1128. >> >>;
  1129. vdpilcomb1 (rp2,db1,vevdif(ep,ep2),
  1130. rp1,vbcneg db2,vevdif(ep,ep1))
  1131. >>
  1132. )
  1133. );
  1134. if !*groebprot then
  1135. groebprotsetq('candidate,
  1136. {'difference,
  1137. {'times,vdp2a vdpfmon(db2,vevdif(ep,ep2)),
  1138. mkid('poly,vdpnumber p1)},
  1139. {'times,vdp2a vdpfmon(db1,vevdif(ep,ep1)),
  1140. mkid('poly,vdpnumber p2)}} );
  1141. return r;
  1142. end;
  1143. symbolic procedure groebsavelterm r;
  1144. if !*groelterms and not vdpzero!? r then
  1145. groebsaveltermbc vdplbc r;
  1146. symbolic procedure groebsaveltermbc r;
  1147. <<r:=vbc2a r;
  1148. if not numberp r and not constant_exprp r then
  1149. for each p in cdr fctrf numr simp r do
  1150. <<p:=prepf car p;
  1151. if not member(p,glterms) then nconc(glterms,list p);
  1152. >> >>;
  1153. symbolic procedure sfcont f;
  1154. % Calculate the integer content of standard form f.
  1155. if domainp f then f else
  1156. gcdf(sfcont lc f, sfcont red f);
  1157. symbolic procedure vdplmon u; vdpfmon (vdplbc u,vdplbc u);
  1158. symbolic procedure vdpmember3(p,g1,g2,g3);
  1159. % test membership of p in one of then lists g1,g2,g3
  1160. vdpmember(p,g1) or vdpmember(p,g2) or vdpmember(p,g3);
  1161. symbolic procedure groeb!-abort!-id(base,abort1);
  1162. % Test whether one of the elements in abort1 is
  1163. % member of the ideal described by base. Definite
  1164. % test here.
  1165. if null abort1 then nil else
  1166. vdpzero!?(groebnormalform(car abort1,base,'list))
  1167. or groeb!-abort!-id(base,cdr abort1);
  1168. endmodule;
  1169. end;