traverso.red 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. module traverso;
  2. % Buchberger algorithm base on "sugar" strategy
  3. % see Giovini-Mora-Niesi-Robbiano-Traverso:
  4. % One sugar gube, please. ISSAC 91 proceddings, pp 49-54
  5. fluid '(!*gtraverso!-sloppy !*gsugar);
  6. !*gtraverso!-sloppy := t;
  7. symbolic procedure gtraverso (g0,fact,groebres,abort1);
  8. begin scalar g,d,s,h,p,!*gsugar;
  9. fact := nil; groebres := nil; abort1 := nil;
  10. !*gsugar := t;
  11. g0:=for each fj in g0 join
  12. if not vdpzero!? fj then
  13. <<groebsavelterm fj;
  14. {gsetsugar(vdpenumerate vdpsimpcont fj,nil)}>>;
  15. main_loop:
  16. if null g0 and null d then return gtraverso!-final g;
  17. if g0 then
  18. <<h:=car g0;g0:=cdr g0;
  19. p := list(nil,h,h)
  20. >>
  21. else
  22. <<p := car d;
  23. d := cdr d;
  24. s := groebspolynom (cadr p, caddr p);
  25. !*trgroeb and groebmess3 (p,s);
  26. h:=groebsimpcontnormalform groebnormalform(s,g,'list);
  27. if vdpzero!? h then
  28. <<!*trgroeb and groebmess4(p,d); goto main_loop>>;
  29. if vevzero!? vdpevlmon h then % base 1 found
  30. << !*trgroeb and groebmess5(p,h);
  31. d:=g:=g0:=nil;
  32. >>;
  33. >>;
  34. h := groebenumerate h; !*trgroeb and groebmess5(p,h);
  35. groebsavelterm h;
  36. % new pair list
  37. d := gtraverso!-pairlist(h,g,d);
  38. % new basis
  39. g := nconc(g,{h});
  40. goto main_loop;
  41. end;
  42. symbolic procedure gtraverso!-pairlist(gk,g,d);
  43. % gk: new polynomial,
  44. % g: current basis,
  45. % d: old pair list.
  46. begin scalar ev,r,n,nn,q;
  47. % delete triange relations from old pair list.
  48. d := gtraverso!-pairs!-discard1(gk,d);
  49. % build new pair list.
  50. ev := vdpevlmon gk;
  51. for each p in g do
  52. if not groebbuchcrit4t(ev,vdpevlmon p)
  53. then r := vevlcm(ev,vdpevlmon p).r
  54. else n := groebmakepair(p,gk) . n;
  55. % delete from new pairs equivalents to coprime lcm.
  56. for each q in r do
  57. for each p in n do
  58. if car p=q then n:=delete(p,n);
  59. % discard multiples: collect survivers in n
  60. if !*gtraverso!-sloppy then !*gsugar:=nil;
  61. n := groebcplistsort(n);
  62. !*gsugar := t;
  63. nn := n; n:=nil;
  64. for each p in nn do
  65. <<q:=nil;
  66. for each r in n do
  67. q:=q or vevdivides!?(car r,car p);
  68. if not q then n:=groebcplistsortin(p,n);
  69. >>;
  70. return groebcplistmerge(d,reversip n);
  71. end;
  72. symbolic procedure gtraverso!-pairs!-discard1(gk,d);
  73. % crit B
  74. begin scalar gi,gj,tij,evk;
  75. evk:=vdpevlmon gk;
  76. for each pij in d do
  77. <<tij := car pij; gi:=cadr pij; gj:=caddr pij;
  78. if vevstrictlydivides!?(tt(gi,gk),tij)
  79. and vevstrictlydivides!?(tt(gj,gk),tij)
  80. then d:=delete(pij,d);
  81. >>;
  82. return d;
  83. end;
  84. symbolic procedure vevstrictlydivides!?(ev1,ev2);
  85. not(ev1=ev2) and vevdivides!?(ev1,ev2);
  86. symbolic procedure gtraverso!-final g;
  87. % final reduction and sorting;
  88. begin scalar r,p,!*gsugar;
  89. g:=vdplsort g; % descending
  90. while g do
  91. <<p:=car g; g:=cdr g;
  92. if not groebsearchinlist(vdpevlmon p,g) then
  93. r := groebsimpcontnormalform groebnormalform(p,g,'list) . r;
  94. >>;
  95. return list reversip r;
  96. end;
  97. endmodule;
  98. end;