groebidq.red 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. module groebidq;
  2. % calculation of ideal quotient using a modified Buchberger algorithm.
  3. % Authors: H. Melenk, H.M. Moeller, W. Neun
  4. % July 1988
  5. fluid '( % switches from the user interface
  6. !*groebopt !*groebfac !*groebres !*trgroeb !*trgroebs !*groebrm
  7. !*trgroeb1 !*trgroebr !*groebprereduce groebrestriction!*
  8. !*groebstat !*groebdivide !*groebprot
  9. !*groebidqbasis
  10. vdpvars!* % external names of the variables
  11. !*vdpinteger !*vdpmodular % indicating type of algorithm
  12. vdpsortmode!* % term ordering mode
  13. secondvalue!* thirdvalue!* % auxiliary: multiple return values
  14. fourthvalue!*
  15. factortime!* % computing time spent in factoring
  16. factorlvevel!* % bookkeeping of factor tree
  17. pairsdone!* % list of pairs already calculated
  18. probcount!* % counting subproblems
  19. vbccurrentmode!* % current domain for base coeffs.
  20. groetime!*
  21. !*gsugar
  22. );
  23. switch groebopt,groebfac,groebrm,groebres,trgroeb,trgroebs,trgroeb1,
  24. trgroebr,groebstat,groebprot;
  25. !*groebidqbasis := t; %default: basis from idq
  26. % variables for counting and numbering
  27. fluid '(hcount!* pcount!* mcount!* fcount!* bcount!* b4count!*
  28. basecount!* hzerocount!*);
  29. symbolic procedure groebidq2 (p,f);
  30. % setup all global variables for the Buchberger algorithm
  31. % printing of statistics
  32. begin scalar groetime!*,tim1,spac,spac1,p1,factortime!*,
  33. pairsdone!*, factorlvevel!*,!*gsugar;
  34. factortime!* := 0;
  35. groetime!* := time();
  36. vdponepol(); % we construct dynamically
  37. hcount!* := 0;
  38. pcount!* := 0;
  39. mcount!* := 0;
  40. fcount!* := 0;
  41. bcount!* := 0;
  42. b4count!* := 0;
  43. hzerocount!* := 0;
  44. basecount!* := 0;
  45. if !*trgroeb then
  46. <<
  47. prin2 "IDQ Calculation starting ";
  48. terprit 2;
  49. >>;
  50. spac := gctime();
  51. p1:= groebidq3 (p, f);
  52. if !*trgroeb or !*trgroebr or !*groebstat then
  53. <<
  54. spac1 := gctime() - spac;
  55. terpri();
  56. prin2t "statistics for IDQ calculation";
  57. prin2t "==============================";
  58. prin2 " total computing time (including gc): ";
  59. prin2((tim1 := time()) - groetime!*);
  60. prin2t " milliseconds ";
  61. prin2 " (time spent for garbage collection: ";
  62. prin2 spac1;
  63. prin2t " milliseconds)";
  64. terprit 1;
  65. prin2 "H-polynomials total: "; prin2t hcount!*;
  66. prin2 "H-polynomials zero : "; prin2t hzerocount!*;
  67. prin2 "Crit M hits: "; prin2t mcount!*;
  68. prin2 "Crit F hits: "; prin2t fcount!*;
  69. prin2 "Crit B hits: "; prin2t bcount!*;
  70. prin2 "Crit B4 hits: "; prin2t b4count!*;
  71. >>;
  72. return if !*groebidqbasis then car groebner2(p1,nil) else p1;
  73. end;
  74. symbolic procedure groebidq3 (g0,fff);
  75. begin scalar result,x,g,d,d1,d2,p,p1,s,h,g99,one,gi;
  76. gi := g0;
  77. fff := vdpsimpcont fff;
  78. vdpputprop(fff,'number,0); % assign number 0
  79. vdpputprop(fff,'cofact,a2vdp 1); % assign cofactor 1
  80. x := for each fj in g0 collect
  81. << fj:=vdpenumerate vdpsimpcont fj;
  82. vdpputprop(fj,'cofact,a2vdp 0); % assign cofactor 0
  83. fj>>;
  84. g0 := list fff;
  85. for each fj in x do g0 := vdplsortin(fj,g0);
  86. % ITERATION :
  87. while (d or g0) and not one do
  88. begin
  89. if g0 then
  90. << % take next poly from input
  91. h := car g0;
  92. g0 := cdr g0;
  93. p := list(nil,h,h);
  94. >>
  95. else
  96. << % take next poly from pairs
  97. p := car d;
  98. d := delete (p,d);
  99. s := idqspolynom (cadr p, caddr p);
  100. idqmess3(p,s);
  101. h := idqsimpcont idqnormalform(s,g99,'tree);
  102. if vdpzero!? h then
  103. << !*trgroeb and groebmess4(p,d);
  104. x := vdpgetprop(h,'cofact);
  105. if not vdpzero!? x then
  106. if vevzero!? vdpevlmon x then one:= t else
  107. << result := idqtoresult(x , result);
  108. idqmess0 x>>;
  109. >>
  110. >>;
  111. if vdpzero!? h then goto bott;
  112. if vevzero!? vdpevlmon h then % base 1 found
  113. << idqmess5(p,h);
  114. result:=gi; d:=g0:=nil;
  115. goto bott;>>;
  116. s:= nil;
  117. % h polynomial is accepted now
  118. h := vdpenumerate h;
  119. idqmess5(p,h);
  120. % construct new critical pairs
  121. d1 := nil;
  122. for each f in g do
  123. <<d1 := groebcplistsortin( list(tt(f,h),f,h) , d1);
  124. if tt(f,h) = vdpevlmon(f) then
  125. <<g := delete (f,g);
  126. !*trgroeb and groebmess2 f>>;
  127. >>;
  128. !*trgroeb and groebmess51(d1);
  129. d2 := nil;
  130. while d1 do
  131. <<d1 := groebinvokecritf d1;
  132. p1 := car d1;
  133. d1 := cdr d1;
  134. if groebbuchcrit4t(cadr p1,caddr p1)
  135. then d2 := append (d2, list p1)
  136. else
  137. <<x := idqdirectelement(cadr p1,caddr p1);
  138. if not vdpzero!? x then
  139. if vevzero!? vdpevlmon x then one:= t else
  140. <<idqmess1 (x,cadr p1,caddr p1);
  141. result := idqtoresult(x,result);
  142. >> >>;
  143. d1 := groebinvokecritm (p1,d1);
  144. >>;
  145. % D := groebInvokeCritB (h,D);
  146. d := groebcplistmerge(d,d2);
  147. g := h . g;
  148. g99 := groebstreeadd(h, g99);
  149. !*trgroeb and groebmess8(g,d);
  150. bott:
  151. end; % ITERATION
  152. % now calculate groebner base from quotient base
  153. if one then result := list vdpfmon(a2vbc 1,vevzero());
  154. idqmess2 result;
  155. return result;
  156. end; % MACROLOOP
  157. symbolic procedure idqtoresult(x,r);
  158. % x is a new element for the quotient r;
  159. % is is reduced by r and then added.
  160. <<x := groebsimpcontnormalform groebnormalform(x,r,'sort);
  161. if vdpzero!? x then r else vdplsortin(x,r)>>;
  162. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  163. %
  164. % Reduction of polynomials
  165. %
  166. symbolic procedure idqnormalform(f,g,type);
  167. % general procedure for reduction of one polynomial from a set
  168. % f is a polynomial, G is a Set of polynomials either in
  169. % a search tree or in a sorted list
  170. % type describes the ordering of the set G:
  171. % 'TREE G is a search tree
  172. % 'SORT G is a sorted list
  173. % 'LIST G is a list, but not sorted
  174. % f has to be reduced modulo G
  175. % version for idealQuotient: doing side effect calculations for
  176. % the cofactors; only headterm reduction
  177. begin scalar c,vev,divisor,done,fold;
  178. fold := f;
  179. while not vdpzero!? f and g do
  180. begin
  181. vev:=vdpevlmon f; c:=vdplbc f;
  182. if type = 'sort then
  183. while g
  184. and vevcompless!? (vev,vdpevlmon (car g))
  185. do g := cdr g;
  186. divisor :=
  187. if type = 'tree then groebsearchinstree (vev,g)
  188. else groebsearchinlist (vev,g);
  189. if divisor then done := t; % true action indicator
  190. if divisor and !*trgroebs then
  191. << prin2 "//-";
  192. prin2 vdpnumber divisor;
  193. >>;
  194. if divisor then
  195. if !*vdpinteger then
  196. f := idqreduceonestepint(f,nil,c,vev,divisor)
  197. else
  198. f := idqreduceonesteprat(f,nil,c,vev,divisor)
  199. else
  200. g := nil;
  201. end;
  202. return if done then f else fold; %in order to preserve history
  203. end;
  204. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  205. %
  206. % special reduction procedures
  207. symbolic procedure idqreduceonestepint(f,dummy,c,vev,g1);
  208. % reduction step for integer case:
  209. % calculate f= a*f - b*g a,b such that leading term vanishes
  210. % (vev of lvbc g divides vev of lvbc f)
  211. %
  212. % and calculate f1 = a*f1
  213. % return value=f, secondvalue=f1
  214. begin scalar vevlcm,a,b,cg,x,fcofa,gcofa;
  215. dummy := nil;
  216. fcofa := vdpgetprop(f,'cofact);
  217. gcofa := vdpgetprop(g1,'cofact);
  218. vevlcm := vevdif(vev,vdpevlmon g1);
  219. cg := vdplbc g1;
  220. % calculate coefficient factors
  221. x := vbcgcd(c,cg);
  222. a := vbcquot(cg,x);
  223. b := vbcquot(c,x);
  224. f:= vdpilcomb1 (vdpred f, a, vevzero(),
  225. vdpred g1,vbcneg b, vevlcm);
  226. x := vdpilcomb1 (fcofa, a, vevzero(),
  227. gcofa ,vbcneg b, vevlcm);
  228. vdpputprop(f,'cofact,x);
  229. return f;
  230. end;
  231. symbolic procedure idqreduceonesteprat(f,dummy,c,vev,g1);
  232. % reduction step for rational case:
  233. % calculate f= f - g/vdpLbc(f)
  234. %
  235. begin scalar x,fcofa,gcofa,vev;
  236. dummy := nil;
  237. fcofa := vdpgetprop(f,'cofact);
  238. gcofa := vdpgetprop(g1,'cofact);
  239. vev := vevdif(vev,vdpevlmon g1);
  240. x := vbcneg vbcquot(c,vdplbc g1);
  241. f := vdpilcomb1(vdpred f,a2vbc 1,vevzero(),
  242. vdpred g1,x,vev);
  243. x := vdpilcomb1 (fcofa,a2vbc 1 , vevzero(),
  244. gcofa,x,vev);
  245. vdpputprop(f,'cofact,x);
  246. return f;
  247. end;
  248. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  249. %
  250. % calculation of an S-polynomial and related things
  251. %
  252. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  253. symbolic procedure idqspolynom (p1,p2);
  254. begin scalar s,ep1,ep2,ep,rp1,rp2,db1,db2,x,cofac1,cofac2;
  255. if vdpzero!? p1 then return p1; if vdpzero!? p2 then return p2;
  256. cofac1 := vdpgetprop(p1,'cofact); cofac2 := vdpgetprop(p2,'cofact);
  257. ep1 := vdpevlmon p1; ep2 := vdpevlmon p2;
  258. ep := vevlcm(ep1, ep2);
  259. rp1 := vdpred p1; rp2 := vdpred p2;
  260. db1 := vdplbc p1; db2 := vdplbc p2;
  261. if !*vdpinteger then
  262. <<x:=vbcgcd(db1,db2); db1:=vbcquot(db1,x); db2:=vbcquot(db2,x)>>;
  263. ep1 := vevdif(ep,ep1); ep2 := vevdif(ep,ep2); db2 := vbcneg db2;
  264. s := vdpilcomb1 (rp2,db1,ep2,rp1,db2,ep1);
  265. x := vdpilcomb1 (cofac2,db1,ep2,cofac1,db2,ep1);
  266. vdpputprop(s,'cofact,x);
  267. return s;
  268. end;
  269. symbolic procedure idqdirectelement(p1,p2);
  270. % the s-Polynomial is reducable to zero because of
  271. % buchcrit 4. So we can calculate the corresponing cofactor
  272. % directly
  273. (if vdpzero!? c1 and vdpzero!? c2 then c1
  274. else vdpdif(vdpprod(p1,c2),vdpprod(p2,c1))
  275. ) where c1 = vdpgetprop(p1,'cofact),
  276. c2 = vdpgetprop(p2,'cofact);
  277. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  278. %
  279. % Normailsation with cofactors taken into account
  280. %
  281. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  282. symbolic procedure idqsimpcont(p);
  283. if !*vdpinteger then idqsimpconti p else idqsimpcontr p;
  284. % routines for integer coefficient case:
  285. % calculation of contents and dividing all coefficients by it
  286. symbolic procedure idqsimpconti (p);
  287. % calculate the contents of p and divide all coefficients by it
  288. begin scalar res,num,cofac;
  289. if vdpzero!? p then return p;
  290. cofac := vdpgetprop(p,'cofact);
  291. num := car vdpcontenti p;
  292. if not vdpzero!? cofac then num:=vbcgcd(num,car vdpcontenti cofac);
  293. if not vbcplus!? num then num := vbcneg num;
  294. if not vbcplus!? vdplbc p then num:=vbcneg num;
  295. if vbcone!? num then return p;
  296. res := vdpreduceconti (p,num,nil);
  297. if not vdpzero!? cofac then cofac:=vdpreduceconti(cofac,num,nil);
  298. res := vdpputprop(res,'cofact,cofac);
  299. return res;
  300. end;
  301. % routines for rational coefficient case:
  302. % calculation of contents and dividing all coefficients by it
  303. symbolic procedure idqsimpcontr (p);
  304. % calculate the contents of p and divide all coefficients by it
  305. begin scalar res,cofac;
  306. cofac := vdpgetprop(p,'cofact);
  307. if vdpzero!? p then return p;
  308. if vbcone!? vdplbc p then return p;
  309. res := vdpreduceconti (p,vdplbc p,nil);
  310. if not vdpzero!? cofac then
  311. cofac:=vdpreduceconti(cofac,vdplbc p,nil);
  312. res := vdpputprop(res,'cofact,cofac);
  313. return res;
  314. end;
  315. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  316. %
  317. % trace messages
  318. %
  319. symbolic procedure idqmess0 x;
  320. if !*trgroeb then
  321. <<prin2t "adding member to intermediate quotient basis:";
  322. vdpprint x;
  323. terpri()>>;
  324. symbolic procedure idqmess1 (x,p1,p2);
  325. if !*trgroeb then
  326. <<prin2 "pair ("; prin2 vdpnumber p1; prin2 ",";
  327. prin2 vdpnumber p2;
  328. prin2t ") adding member to intermediate quotient basis:";
  329. vdpprint x;
  330. terpri()>>;
  331. symbolic procedure idqmess2 b;
  332. if !*trgroeb then
  333. <<prin2t "---------------------------------------------------";
  334. prin2 "the full intermediate base of the ideal quotient is:";
  335. for each x in b do vdpprin3t x;
  336. prin2t "---------------------------------------------------";
  337. terpri()>>;
  338. symbolic procedure idqmess5(p,h);
  339. if car p then % print for true h-Polys
  340. << hcount!* := hcount!* + 1;
  341. if !*trgroeb then <<
  342. terpri();
  343. prin2 "H-polynomial ";
  344. prin2 pcount!*;
  345. groebmessff(" from pair (",cadr p,nil);
  346. groebmessff(",", caddr p,")");
  347. vdpprint h;
  348. prin2t "with cofactor";
  349. vdpprint vdpgetprop(h,'cofact);
  350. groetimeprint() >> >>
  351. else
  352. if !*trgroeb then << % print for input polys
  353. prin2t "candidate from input:";
  354. vdpprint h;
  355. groetimeprint() >>;
  356. symbolic procedure idqmess3(p,s);
  357. if !*trgroebs then <<
  358. prin2 "S-polynomial ";
  359. prin2 " from ";
  360. groebpairprint p;
  361. vdpprint s;
  362. prin2t "with cofactor";
  363. vdpprint vdpgetprop(s,'cofact);
  364. groetimeprint();
  365. terprit 3 >>;
  366. endmodule;
  367. end;