groebtra.red 16 KB

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