groebtra.red 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. module groebtra;
  2. % calculation of a Groebner base with the Buchberger algorithm
  3. % including the backtracking information which denotes the
  4. % dependency between base and input polynomials
  5. % Authors: H. Melenk, H.M. Moeller, W. Neun
  6. % November 1988
  7. fluid '( % switches from the user interface
  8. !*groebopt !*groebfac !*groebres !*trgroeb !*trgroebs !*groebrm
  9. !*trgroeb1 !*trgroebr !*groebprereduce groebrestriction!*
  10. !*groebstat !*groebdivide !*groebprot
  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. factortime!* % computing time spent in factoring
  17. factorlvevel!* % bookkeeping of factor tree
  18. pairsdone!* % list of pairs already calculated
  19. probcount!* % counting subproblems
  20. vbcCurrentMode!* % current domain for base coeffs.
  21. groetags!* % starting point of tag variables
  22. groetime!*
  23. );
  24. global '(gvarslast);
  25. switch groebopt,groebfac,groebres,trgroeb,trgroebs,trgroeb1,
  26. trgroebr,groebstat,groebprot;
  27. % variables for counting and numbering
  28. fluid '(hcount!* pcount!* mcount!* fcount!* bcount!* b4count!*
  29. basecount!* hzerocount!*);
  30. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  31. % Interface
  32. symbolic procedure groebnertraeval u;
  33. % backtracking Groebner calculation
  34. begin integer n; scalar !*groebfac,!*groebrm,!*groebprot,!*gsugar;
  35. n := length u;
  36. if n=1 then return groebnertra1(reval car u,nil,nil)
  37. else if n neq 2
  38. then rerror(groebnr2,10,
  39. "GROEBNERT called with wrong number of arguments")
  40. else return groebnertra1(reval car u,reval cadr u,nil)
  41. end;
  42. put('groebnert,'psopfn,'groebnertraeval);
  43. smacro procedure vdpnumber f;
  44. vdpgetprop(f,'number) ;
  45. symbolic procedure groebnertra1(u,v,mod1);
  46. % Buchberger algorithm system driver. u is a list of expressions
  47. % and v a list of variables or NIL in which case the variables in u
  48. % are used.
  49. begin scalar vars,w,y,z,x,np,oldorder,groetags!*,tagvars;
  50. integer pcount!*,nmod;
  51. u := for each j in getrlist u collect
  52. <<if not eqcar(j,'equal)
  53. or not (idp (w:=cadr j) or (pairp w and
  54. w = reval w and
  55. get(car w,'simpfn)='simpiden))
  56. then rerror(groebnr2,11,
  57. "groebnert parameter not {...,name = polynomial,...}")
  58. else cadr j . caddr j
  59. >>;
  60. if null u then rerror(groebnr2,12,"Empty list in Groebner")
  61. else if null cdr u then
  62. return 'list . list('equal,cdar u,caar u);;
  63. w := for each x in u collect cdr x;
  64. if mod1 then
  65. <<z := nil;
  66. for each vect in w do
  67. <<if not eqcar(vect,'list) then
  68. rerror(groebnr2,13,"Non list given to groebner");
  69. if nmod=0 then nmod:= length cdr vect else
  70. if nmod<(x:=length cdr vect) then nmod=x;
  71. z := append(cdr vect,z);
  72. >>;
  73. if not eqcar(mod1,'list) then
  74. rerror(groebnr2,14,"Illegal column weights specified");
  75. vars := groebnervars(z,v);
  76. tagvars := for i:=1:nmod collect mkid('! col,i);
  77. w := for each vect in w collect
  78. <<z:=tagvars; y := cdr mod1;
  79. 'plus . for each p in cdr vect collect
  80. 'times . list('expt,car z,car y) .
  81. <<z := cdr z; y := cdr y;
  82. if null y then y := '(1); list p>>
  83. >>;
  84. groetags!* := length vars + 1;
  85. vars := append(vars,tagvars);
  86. >>
  87. else vars := groebnervars(w,v);
  88. groedomainmode();
  89. if null vars then vdperr 'groebner;
  90. oldorder := vdpinit vars;
  91. % cancel common denominators
  92. u := pair(for each x in u collect car x,w);
  93. u := for each x in u collect
  94. <<z := simp cdr x;
  95. multsq(simp car x,denr z ./ 1) . reorder numr z>>;
  96. w := for each j in u collect cdr j;
  97. % optimize varable sequence if desired
  98. if !*groebopt then<< w:=vdpvordopt (w,vars); vars := cdr w;
  99. w := car w; vdpinit vars>>;
  100. w := pair (for each x in u collect car x,w);
  101. w := for each j in w collect
  102. <<z := f2vdp cdr j; vdpPutProp(z,'cofact,car j)>>;
  103. if not !*vdpInteger then
  104. <<np := t;
  105. for each p in w do
  106. np := if np then vdpcoeffcientsfromdomain!? p else nil;
  107. if not np then <<!*vdpModular:= nil; !*vdpinteger := T>>;
  108. >>;
  109. w := groebtra2 w;
  110. w := if mod1 then groebnermodres(w,nmod,tagvars) else
  111. groebnertrares w;
  112. setkorder oldorder;
  113. gvarslast := 'list . vars; return w;
  114. end;
  115. symbolic procedure groebnertrares w;
  116. begin scalar c,u;
  117. return 'list . for each j in w collect
  118. <<c := prepsq vdpgetprop(j,'cofact);
  119. u := vdp2a j;
  120. if c=0 then u else list('equal,u,c) >>;
  121. end;
  122. symbolic procedure groebnermodres(w,n,tagvars);
  123. begin scalar x,c,oldorder;
  124. c := for each u in w collect prepsq vdpgetprop(u,'cofact);
  125. oldorder := setkorder tagvars;
  126. w := for each u in w collect
  127. 'list . <<u := numr simp vdp2a u;
  128. for i := 1:n collect
  129. prepf if not domainp u and mvar u = nth(tagvars,i)
  130. then <<x := lc u; u := red u; x>> else nil >>;
  131. setkorder oldorder;
  132. % reestablish term order for output
  133. w := for each u in w collect vdp2a a2vdp u;
  134. w := pair(w,c);
  135. return 'list . for each p in w collect
  136. if cdr p=0 then car p else
  137. list('equal,car p,cdr p);
  138. end;
  139. symbolic procedure preduceteval pars;
  140. % trace version of PREDUCE
  141. % parameters:
  142. % 1 expression to be reduced
  143. % formula or equation
  144. % 2 polynomials or equations; base for reduction
  145. % must be equations with atomic lhs
  146. % 3 optional: list of variables
  147. begin scalar vars,x,y,u,v,w,z,oldorder,!*factor,!*exp,!*gsugar;
  148. integer pcount!*; !*exp := t;
  149. pars := groeparams(pars,2,3);
  150. y := car pars; u := cadr pars; v:= caddr pars;
  151. u := for each j in getrlist u
  152. collect
  153. <<if not eqcar(j,'equal) then
  154. j . j else cadr j . caddr j>>;
  155. if null u then rerror(groebnr2,15,"Empty list in preducet");
  156. w := for each p in u collect cdr p; % the polynomials
  157. groedomainmode();
  158. vars := if null v then
  159. for each j in gvarlis w collect !*a2k j
  160. else getrlist v;
  161. if not vars then vdperr 'preducet;
  162. oldorder := vdpinit vars;
  163. u := for each x in u collect
  164. <<z := simp cdr x;
  165. multsq(simp car x,denr z ./ 1) . reorder numr z>>;
  166. w := for each j in u collect
  167. <<z := f2vdp cdr j; vdpputprop(z,'cofact,car j)>>;
  168. if not eqcar(y,'equal) then y := list('equal,y,y);
  169. x := a2vdp caddr y; % the expression
  170. vdpputprop(x,'cofact,simp cadr y); % the lhs (name etc.)
  171. w := tranormalform(x,w, 'sort,'f);
  172. u := list('equal,vdp2a w,prepsq vdpgetprop(w,'cofact));
  173. setkorder oldorder;
  174. return u;
  175. end;
  176. put('preducet,'psopfn,'preduceteval);
  177. symbolic procedure groebnermodeval u;
  178. % Groebner for moduli calculation
  179. (if n=0 or n>3 then
  180. rerror(groebnr2,16,
  181. "groebnerm called with wrong number of arguments")
  182. else
  183. groebnertra1(reval car u,
  184. if n>=2 then reval cadr u else nil,
  185. if n>=3 then reval caddr u else '(list 1))
  186. ) where n = length u;
  187. put('groebnerm,'psopfn,'groebnermodeval);
  188. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  189. % some macros for local usage only
  190. smacro procedure tt(s1,s2);
  191. % lcm of leading terms of s1 and s2
  192. vevlcm(vdpevlmon s1,vdpevlmon s2);
  193. symbolic procedure groebtra2 (p);
  194. % setup all global variables for the Buchberger algorithm
  195. % printing of statistics
  196. begin scalar groetime!*,tim1,spac,spac1,p1,factortime!*,
  197. pairsdone!*,factorlvevel!*;
  198. factortime!* := 0;
  199. groetime!* := time();
  200. vdponepol(); % we construct dynamically
  201. hcount!* := pcount!* := mcount!* := fcount!* :=
  202. bcount!* := b4count!* := hzerocount!* := basecount!* := 0;
  203. if !*trgroeb then
  204. << prin2 "Groebner Calculation with Backtracking starts ";
  205. terprit 2 >>;
  206. spac := gctime();
  207. p1:= groebTra3 (p);
  208. if !*trgroeb or !*trgroebr or !*groebstat then
  209. << spac1 := gctime() - spac; terpri();
  210. prin2t "statistics for Groebner calculation";
  211. prin2t "===================================";
  212. prin2 " total computing time (including gc): ";
  213. prin2((tim1 := time()) - groetime!*);
  214. prin2t " milliseconds ";
  215. prin2 " (time spent for garbage collection: ";
  216. prin2 spac1;
  217. prin2t " milliseconds)";
  218. terprit 1;
  219. prin2 "H-polynomials total: "; prin2t hcount!*;
  220. prin2 "H-polynomials zero : "; prin2t hzerocount!*;
  221. prin2 "Crit M hits: "; prin2t Mcount!*;
  222. prin2 "Crit F hits: "; prin2t Fcount!*;
  223. prin2 "Crit B hits: "; prin2t bcount!*;
  224. prin2 "Crit B4 hits: "; prin2t B4count!* >>;
  225. return p1;
  226. end;
  227. symbolic procedure groebTra3 (g0);
  228. begin scalar x,g,d,d1,d2,p,p1,s,h,g99,one;
  229. x := for each fj in g0 collect vdpenumerate trasimpcont fj;
  230. for each fj in x do g := vdplsortin(fj,g0);
  231. g0 := g; g := nil;
  232. % iteration :
  233. while (d or g0) and not one do
  234. begin if g0 then
  235. << % take next poly from input
  236. h := car g0; g0 := cdr g0;
  237. p := list(nil,h,h) >>
  238. else
  239. << % take next poly from pairs
  240. p := car d; d := cdr d;
  241. s := traspolynom (cadr p, caddr p); tramess3(p,s);
  242. h := groebnormalform(s,g99,'tree); %piloting wo cofact
  243. if vdpzero!? h then groebmess4(p,d)
  244. else h := trasimpcont tranormalform(s,g99,'tree,'h) >>;
  245. if vdpzero!? h then goto bott;
  246. if vevzero!? vdpevlmon h then % base 1 found
  247. << tramess5(p,h);
  248. g0 := d := nil; g:= list h;
  249. goto bott>>;
  250. s:= nil;
  251. % h polynomial is accepted now
  252. h := vdpenumerate h;
  253. tramess5(p,h);
  254. % construct new critical pairs
  255. d1 := nil;
  256. for each f in g do
  257. if groebmoducrit(f,h) then
  258. <<d1 := groebcplistsortin( list(tt(f,h),f,h) , d1);
  259. if tt(f,h) = vdpevlmon(f) then
  260. <<g := delete (f,G); groebmess2 f>> >>;
  261. groebmess51(d1);
  262. d2 := nil;
  263. while d1 do
  264. <<d1 := groebinvokecritf d1;
  265. p1 := car d1;
  266. d1 := cdr d1;
  267. if groebbuchcrit4(cadr p1,caddr p1,car p1)
  268. then d2 := append (d2, list p1);
  269. d1 := groebinvokecritm (p1,d1) >>;
  270. d := groebinvokecritb (h,d);
  271. d := groebcplistmerge(d,d2);
  272. g := h . g;
  273. g99 := groebstreeadd(h, g99);
  274. groebmess8(g,d);
  275. bott:
  276. end;
  277. return groebtra3post g;
  278. end;
  279. symbolic procedure groebtra3post (g);
  280. % final reduction
  281. begin scalar r,p;
  282. g := vdplsort g;
  283. while g do
  284. <<p := tranormalform(car G,cdr G,'sort,'f);
  285. if not vdpzero!? p then r := trasimpcont p . r;
  286. g := cdr g>>;
  287. return reversip r;
  288. end;
  289. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  290. %
  291. % Reduction of polynomials
  292. %
  293. symbolic procedure tranormalform(f,g,type,mode);
  294. % general procedure for reduction of one polynomial from a set
  295. % f is a polynomial, G is a Set of polynomials either in
  296. % a search tree or in a sorted list
  297. % type describes the ordering of the set G:
  298. % 'TREE G is a search tree
  299. % 'SORT G is a sorted list
  300. % 'LIST G is a list, but not sorted
  301. % f has to be reduced modulo G
  302. % version for idealQuotient: doing side effect calculations for
  303. % the cofactors; only headterm reduction
  304. begin scalar c,vev,divisor,break;
  305. while not vdpzero!? f and not break do
  306. begin
  307. vev:=vdpevlmon f; c:=vdpLbc f;
  308. divisor :=
  309. if type = 'tree then groebsearchinstree (vev,g)
  310. else groebsearchinlist (vev,g);
  311. if divisor and !*trgroebs then
  312. << prin2 "//-";
  313. prin2 vdpnumber divisor >>;
  314. if divisor then
  315. if !*vdpInteger then
  316. f := trareduceonestepint(f,nil,c,vev,divisor)
  317. else
  318. f := trareduceonesteprat(f,nil,c,vev,divisor)
  319. else
  320. break := t;
  321. end;
  322. if mode = 'f then f := tranormalform1(f,g,type,mode);
  323. return f
  324. end;
  325. symbolic procedure tranormalform1(f,g,type,mode);
  326. % reduction of subsequent terms
  327. begin scalar c,vev,divisor,break,f1;
  328. mode := nil;
  329. f1 := f;
  330. while not vdpzero!? f and not vdpzero!? f1 do
  331. <<f1 := f; break := nil;
  332. while not vdpzero!? f1 and not break do
  333. <<vev:=vdpevlmon f1; c:=vdpLbc f1;
  334. f1 := vdpred f1;
  335. divisor :=
  336. if type = 'tree then groebsearchinstree (vev,g)
  337. else groebsearchinlist (vev,g);
  338. if divisor and !*trgroebs then
  339. << prin2 "//-";
  340. prin2 vdpnumber divisor >>;
  341. if divisor then
  342. << if !*vdpInteger then
  343. f := trareduceonestepint(f,nil,c,vev,divisor)
  344. else
  345. f := trareduceonesteprat(f,nil,c,vev,divisor);
  346. break := t>> >> >>;
  347. return f;
  348. end;
  349. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  350. %
  351. % special reduction procedures
  352. symbolic procedure trareduceonestepint(f,dummy,c,vev,g1);
  353. % reduction step for integer case:
  354. % calculate f= a*f - b*g a,b such that leading term vanishes
  355. % (vev of lvbc g divides vev of lvbc f)
  356. %
  357. % and calculate f1 = a*f1
  358. % return value=f, secondvalue=f1
  359. begin scalar vevlcm,a,b,cg,x,fcofa,gcofa;
  360. dummy := nil;
  361. fcofa := vdpgetprop(f,'cofact);
  362. if null fcofa then fcofa := nil ./ 1;
  363. gcofa := vdpgetprop(g1,'cofact);
  364. if null gcofa then gcofa := nil ./ 1;
  365. vevlcm := vevdif(vev,vdpevlmon g1);
  366. cg := vdpLbc g1;
  367. % calculate coefficient factors
  368. x := vbcgcd(c,cg);
  369. a := vbcquot(cg,x);
  370. b := vbcquot(c,x);
  371. f:= vdpilcomb1 (f, a, vevzero(), g1,vbcneg b, vevlcm);
  372. x := vdpilcomb1tra (fcofa, a, vevzero(),
  373. gcofa ,vbcneg b, vevlcm);
  374. vdpputprop(f,'cofact,x);
  375. return f;
  376. end;
  377. symbolic procedure trareduceonesteprat(f,dummy,c,vev,g1);
  378. % reduction step for rational case:
  379. % calculate f= f - g/vdpLbc(f)
  380. %
  381. begin scalar x,fcofa,gcofa,vev;
  382. dummy := nil;
  383. fcofa := vdpgetprop(f,'cofact);
  384. gcofa := vdpgetprop(g1,'cofact);
  385. vev := vevdif(vev,vdpevlmon g1);
  386. x := vbcneg vbcquot(c,vdplbc g1);
  387. f := vdpilcomb1(f,a2vbc 1,vevzero(), g1,x,vev);
  388. x := vdpilcomb1tra (fcofa,a2vbc 1 , vevzero(),
  389. gcofa,x,vev);
  390. vdpputprop(f,'cofact,x);
  391. return f;
  392. end;
  393. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  394. %
  395. % calculation of an S-polynomial
  396. %
  397. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  398. symbolic procedure traspolynom (p1,p2);
  399. begin scalar s,ep1,ep2,ep,rp1,rp2,db1,db2,x,cofac1,cofac2;
  400. if vdpzero!? p1 then return p1; if vdpzero!? p1 then return p2;
  401. cofac1 := vdpgetprop(p1,'cofact); cofac2 := vdpGetProp(p2,'cofact);
  402. ep1 := vdpevlmon p1; ep2 := vdpevlmon p2;
  403. ep := vevlcm(ep1, ep2);
  404. rp1 := vdpred p1; rp2 := vdpred p2;
  405. db1 := vdpLbc p1; db2 := vdpLbc p2;
  406. if !*vdpinteger then
  407. <<x:=vbcgcd(db1,db2); db1:=vbcquot(db1,x); db2:=vbcquot(db2,x)>>;
  408. ep1 := vevdif(ep,ep1); ep2 := vevdif(ep,ep2); db2 := vbcneg db2;
  409. s := vdpilcomb1 (rp2,db1,ep2,rp1,db2,ep1);
  410. x := vdpilcomb1tra (cofac2,db1,ep2,cofac1,db2,ep1);
  411. vdpputprop(s,'cofact,x);
  412. return s;
  413. end;
  414. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  415. %
  416. % Normalisation with cofactors taken into account
  417. %
  418. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  419. symbolic procedure trasimpcont(p);
  420. if !*vdpInteger then trasimpconti p else trasimpcontr p;
  421. % routines for integer coefficient case:
  422. % calculation of contents and dividing all coefficients by it
  423. symbolic procedure trasimpconti (p);
  424. % calculate the contents of p and divide all coefficients by it
  425. begin scalar res,num,cofac;
  426. if vdpzero!? p then return p;
  427. cofac := vdpgetprop(p,'cofact);
  428. num := car vdpcontenti p;
  429. if not vbcplus!? num then num := vbcneg num;
  430. if not vbcplus!? vdpLbc p then num:=vbcneg num;
  431. if vbcone!? num then return p;
  432. res := vdpreduceconti (p,num,nil);
  433. cofac:=vdpreducecontitra(cofac,num,nil);
  434. res := vdpputprop(res,'cofact,cofac);
  435. return res;
  436. end;
  437. % routines for rational coefficient case:
  438. % calculation of contents and dividing all coefficients by it
  439. symbolic procedure trasimpcontr (p);
  440. % calculate the contents of p and divide all coefficients by it
  441. begin scalar res,cofac;
  442. cofac := vdpgetprop(p,'cofact);
  443. if vdpzero!? p then return p;
  444. if vbcone!? vdpLbc p then return p;
  445. res := vdpreduceconti (p,vdplbc p,nil);
  446. cofac:=vdpreducecontitra(cofac,vdplbc p,nil);
  447. res := vdpputprop(res,'cofact,cofac);
  448. return res;
  449. end;
  450. symbolic procedure vdpilcomb1tra (cofac1,db1,ep1,cofac2,db2,ep2);
  451. % the linear combination, here done for the cofactors
  452. % (standard quotients)
  453. addsq(multsq(cofac1,vdp2f vdpfmon(db1,ep1) ./ 1),
  454. multsq(cofac2,vdp2f vdpfmon(db2,ep2) ./ 1));
  455. symbolic procedure vdpreducecontitra(cofac,num,dummy);
  456. % divide the cofactor by a number
  457. <<dummy := nil; quotsq(cofac,simp vbc2a num)>>;
  458. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  459. %
  460. % special handling of moduli
  461. %
  462. symbolic procedure groebmoducrit(p1,p2);
  463. null groetags!*
  464. or pnth(vdpevlmon p1,groetags!*) = pnth(vdpevlmon p2,groetags!*);
  465. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  466. %
  467. % trace messages
  468. %
  469. symbolic procedure tramess0 x;
  470. if !*trgroeb then
  471. <<prin2t "adding member to intermediate quotient base:";
  472. vdpprint x;
  473. terpri()>>;
  474. symbolic procedure tramess1 (x,p1,p2);
  475. if !*trgroeb then
  476. <<prin2 "pair ("; prin2 vdpnumber p1; prin2 ",";
  477. prin2 vdpnumber p2;
  478. prin2t ") adding member to intermediate quotient base:";
  479. vdpprint x;
  480. terpri()>>;
  481. symbolic procedure tramess5(p,h);
  482. if car p then % print for true h-Polys
  483. << hcount!* := hcount!* + 1;
  484. if !*trgroeb then << terpri();
  485. prin2 "H-polynomial ";
  486. prin2 pcount!*;
  487. groebmessff(" from pair (",cadr p,nil);
  488. groebmessff(",", caddr p,")");
  489. vdpprint h;
  490. prin2t "with cofactor";
  491. writepri(mkquote prepsq vdpgetprop(h,'cofact),'only);
  492. groetimeprint() >> >>
  493. else
  494. if !*trgroeb then << % print for input polys
  495. prin2t "candidate from input:";
  496. vdpprint h;
  497. groetimeprint() >>;
  498. symbolic procedure tramess3(p,s);
  499. if !*trgroebs then <<
  500. prin2 "S-polynomial ";
  501. prin2 " from ";
  502. groebpairprint p;
  503. vdpprint s;
  504. prin2t "with cofactor";
  505. writepri(mkquote prepsq vdpGetProp(s,'cofact),'only);
  506. groetimeprint();
  507. terprit 3 >>;
  508. endmodule;
  509. end;