ncgroeb.red 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. module ncgroeb; % Groebner for noncommutative one sided ideals.
  2. % Author: H. Melenk, ZIB Berlin, J. Apel, University of Leipzig.
  3. % Following Carlo Traverso's model.
  4. switch gsugar;
  5. symbolic procedure nc!-groebeval u;
  6. begin scalar g;
  7. nc!-gsetup();
  8. u:=car u;
  9. g:=for each p in cdr listeval(u,nil) collect a2ncvdp reval p;
  10. g:=nc!-traverso g;
  11. return 'list.for each w in g collect vdp2a w end;
  12. put('nc_groebner,'psopfn,'nc!-groebeval);
  13. symbolic procedure nc!-preduce u;
  14. begin scalar g,p,!*gsugar;
  15. nc!-gsetup();
  16. g:=for each p in cdr listeval(cadr u,nil) collect a2ncvdp reval p;
  17. p:=a2ncvdp reval car u;
  18. p:=nc!-normalform(p,g,nil,nil);
  19. return vdp2a p end;
  20. put('nc_preduce,'psopfn,'nc!-preduce);
  21. symbolic procedure nc!-div u;
  22. begin scalar g,p,!*gsugar;
  23. nc!-gsetup();
  24. g:=a2ncvdp reval cadr u;
  25. p:=a2ncvdp reval car u;
  26. p:=nc!-qremf(p,g);
  27. return{'list,vdp2a car p,vdp2a cdr p}end;
  28. put('nc_divide,'psopfn,'nc!-div);
  29. symbolic procedure nc!-gsetup();
  30. << factortime!*:=0;
  31. groetime!*:=time();
  32. vdpinit2 ncdipvars!*;
  33. vdponepol(); % we construct dynamically
  34. hcount!*:=mcount!*:=fcount!*:=pcount!*:=0;
  35. bcount!*:=b4count!*:=hzerocount!*:=0;
  36. basecount!*:=0;!*gcd:=t;glterms:=list('list);
  37. groecontcount!*:=10;
  38. !*nc!-traverso!-sloppy:=!*vdpinteger:=t;
  39. if null ncdipbase!* then
  40. rederr "non-commutative ideal initialization missing">>;
  41. !*gsugar:=t;
  42. symbolic procedure nc!-traverso g0;
  43. begin scalar g,d,s,h,p;
  44. g0:=for each fj in g0 collect gsetsugar(vdpenumerate vdpsimpcont fj,nil);
  45. main_loop:if null g0 and null d then return nc!-traverso!-final g;
  46. if g0 then<<h:=car g0;g0:=cdr g0;p:={nil,h,h}>>
  47. else
  48. <<p:=car d;
  49. d:=cdr d;
  50. s:=nc!-spoly (cadr p, caddr p);
  51. !*trgroeb and groebmess3 (p,s);
  52. h:=groebsimpcontnormalform nc!-normalform(s,g,'list,t);
  53. if vdpzero!? h then
  54. <<!*trgroeb and groebmess4(p,d);go to main_loop>>;
  55. if vevzero!? vdpevlmon h then % base 1 found
  56. << !*trgroeb and groebmess5(p,h);
  57. d:=g:=g0:=nil>>>>;
  58. h:=groebenumerate h;!*trgroeb and groebmess5(p,h);
  59. % new pair list
  60. d:=nc!-traverso!-pairlist(h,g,d);
  61. % new basis
  62. g:=nconc(g,{h});
  63. go to main_loop end;
  64. symbolic procedure nc!-traverso!-pairlist(gk,g,d);
  65. % gk: new polynomial,
  66. % g: current basis,
  67. % d: old pair list.
  68. begin scalar ev,r,n,nn,q;
  69. % delete triange relations from old pair list.
  70. d:=nc!-traverso!-pairs!-discard1(gk,d);
  71. % build new pair list.
  72. ev:=vdpevlmon gk;
  73. for each p in g do n:=groebmakepair(p,gk).n;
  74. % discard multiples: collect survivers in n
  75. <<if !*nc!-traverso!-sloppy then !*gsugar:=nil;
  76. n:=groebcplistsort n>>where !*gsugar=!*gsugar;
  77. nn:=n;n:=nil;
  78. for each p in nn do
  79. <<q:=nil;
  80. for each r in n do
  81. q:=q or vevdivides!?(car r,car p);
  82. if not q then n:=groebcplistsortin(p,n)>>;
  83. return groebcplistmerge(d,reversip n) end;
  84. symbolic procedure nc!-traverso!-pairs!-discard1(gk,d);
  85. % crit B
  86. begin scalar gi,gj,tij,evk;
  87. evk:=vdpevlmon gk;
  88. for each pij in d do
  89. <<tij:=car pij;gi:=cadr pij;gj:=caddr pij;
  90. if vevstrictlydivides!?(tt(gi,gk),tij)
  91. and vevstrictlydivides!?(tt(gj,gk),tij)
  92. then d:=delete(pij,d)>>;
  93. return d end;
  94. symbolic procedure vevstrictlydivides!?(ev1,ev2);
  95. not(ev1=ev2)and vevdivides!?(ev1,ev2);
  96. symbolic procedure nc!-traverso!-final g;
  97. % final reduction and sorting;
  98. begin scalar r,p,!*gsugar;
  99. g:=vdplsort g; % descending
  100. while g do
  101. <<p:=car g;g:=cdr g;
  102. if not groebsearchinlist(vdpevlmon p,g) then
  103. r:=groebsimpcontnormalform nc!-normalform(p,g,'list,t).r>>;
  104. return reversip r end;
  105. symbolic procedure nc!-fullprint(comm,cu,u,tu,cv,v,tv,r);
  106. <<terpri();prin2 "COMPUTE ";prin2t comm;
  107. vdpprin2 cu;prin2 " * P(";prin2 vdpnumber u; prin2 ")=> ";
  108. vdpprint tu;
  109. vdpprin2 cv;prin2 " * P("; prin2 vdpnumber v; prin2 ")=> ";
  110. vdpprint tv;
  111. prin2t " ====>";
  112. vdpprint r;
  113. prin2t " - - - - - - -">>;
  114. symbolic procedure nc!-spoly(u,v);
  115. % Compute S-polynomial.
  116. begin scalar cu,cv,tu,tv,bl,l,r;
  117. l:=vev!-cofac(vdpevlmon u,vdpevlmon v);
  118. bl:=vbc!-cofac(vdplbc u,vdplbc v);
  119. cu:=vdpfmon(car bl, car l);
  120. cv:=vdpfmon(cdr bl, cdr l);
  121. if !*ncg!-right then <<tu:=vdp!-nc!-prod(u,cu);tv:=vdp!-nc!-prod(v,cv)>>
  122. else <<tu:=vdp!-nc!-prod(cu,u);tv:=vdp!-nc!-prod(cv,v)>>;
  123. nccof!*:=cu.cv;
  124. r:=vdpdif(tu,tv);
  125. if !*trgroebfull then nc!-fullprint("S polynomial:",cu,u,tu,cv,v,tv,r);
  126. return r end;
  127. symbolic procedure nc!-qremf(u,v);
  128. % compute (u/v, remainder(u,v)).
  129. begin scalar ev,cv,q;
  130. q:=a2vdp 0;
  131. if vdpzero!? u then return q.q;
  132. ev:=vdpevlmon v;cv:=vdplbc v;
  133. while not vdpzero!? u and vevdivides!?(ev,vdpevlmon u) do
  134. <<u:=nc!-reduce1(u,vdplbc u,vdpevlmon u, v);
  135. q:=if !*ncg!-right then vdp!-nc!-prod(q,car nccof!*)
  136. else vdp!-nc!-prod(car nccof!*,q);
  137. q:=vdpsum(q,cdr nccof!*)>>;
  138. return q.u end;
  139. symbolic procedure nc!-reduce1(u,bu,eu,v);
  140. % Compute u - w*v such that monomial (bu*x^eu) in u is deleted.
  141. begin scalar cu,cv,tu,tv,bl,l,r;
  142. l:=vev!-cofac(eu,vdpevlmon v);
  143. bl:=vbc!-cofac(bu,vdplbc v);
  144. cu:=vdpfmon(car bl,car l);
  145. cv:=vdpfmon(cdr bl,cdr l);
  146. if !*ncg!-right then
  147. <<tu:=vdp!-nc!-prod(u,cu);tv:=vdp!-nc!-prod(v,cv)>>
  148. else <<tu:=vdp!-nc!-prod(cu,u);tv:=vdp!-nc!-prod(cv,v)>>;
  149. nccof!*:=cu.cv;
  150. r:=vdpdif(tu,tv);
  151. if !*trgroebfull then
  152. nc!-fullprint("Reduction step:",cu,u,tu,cv,v,tv,r);
  153. %%%% if null yesp "cont" then rederr "abort";
  154. return r end;
  155. symbolic procedure nc!-normalform(s,g,mode,cmode);
  156. <<mode:=nil;nc!-normalform2(s,g,cmode)>>;
  157. symbolic procedure nc!-normalform2(s,g,cmode);
  158. % Normal form 2: full reduction.
  159. begin scalar g0,ev,f,s1,b;
  160. loop:s1:=s;
  161. % unwind to last reduction point.
  162. if ev then while vevcomp(vdpevlmon s1,ev)>0 do s1:=vdpred s1;
  163. loop2:if vdpzero!? s1 then return s;
  164. ev:=vdpevlmon s1;b:=vdplbc s1;
  165. g0:=g;f:=nil;
  166. while null f and g0 do
  167. if vevdivides!?(vdpevlmon car g0,ev) then f:=car g0 else g0:=cdr g0;
  168. if null f then<<s1:=vdpred s1;go to loop2>>;
  169. s:=nc!-reduce1(s,b,ev,f);
  170. if !*trgroebs then<<prin2 "//";prin2 vdpnumber f>>;
  171. if cmode then s:=groebsimpcontnormalform s;
  172. go to loop end;
  173. endmodule;;end;