123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- module traverso;
- % Buchberger algorithm base on "sugar" strategy
- % see Giovini-Mora-Niesi-Robbiano-Traverso:
- % One sugar gube, please. ISSAC 91 proceddings, pp 49-54
- fluid '(!*gtraverso!-sloppy !*gsugar);
- !*gtraverso!-sloppy := t;
- symbolic procedure gtraverso (g0,fact,groebres,abort1);
- begin scalar g,d,s,h,p,!*gsugar;
- fact := nil; groebres := nil; abort1 := nil;
- !*gsugar := t;
- g0:=for each fj in g0 join
- if not vdpzero!? fj then
- <<groebsavelterm fj;
- {gsetsugar(vdpenumerate vdpsimpcont fj,nil)}>>;
- main_loop:
- if null g0 and null d then return gtraverso!-final g;
- if g0 then
- <<h:=car g0;g0:=cdr g0;
- p := list(nil,h,h)
- >>
- else
- <<p := car d;
- d := cdr d;
- s := groebspolynom (cadr p, caddr p);
- !*trgroeb and groebmess3 (p,s);
- h:=groebsimpcontnormalform groebnormalform(s,g,'list);
- if vdpzero!? h then
- <<!*trgroeb and groebmess4(p,d); goto main_loop>>;
- if vevzero!? vdpevlmon h then % base 1 found
- << !*trgroeb and groebmess5(p,h);
- d:=g:=g0:=nil;
- >>;
- >>;
- h := groebenumerate h; !*trgroeb and groebmess5(p,h);
- groebsavelterm h;
- % new pair list
- d := gtraverso!-pairlist(h,g,d);
-
- % new basis
- g := nconc(g,{h});
- goto main_loop;
- end;
- symbolic procedure gtraverso!-pairlist(gk,g,d);
- % gk: new polynomial,
- % g: current basis,
- % d: old pair list.
- begin scalar ev,r,n,nn,q;
- % delete triange relations from old pair list.
- d := gtraverso!-pairs!-discard1(gk,d);
- % build new pair list.
- ev := vdpevlmon gk;
- for each p in g do
- if not groebbuchcrit4t(ev,vdpevlmon p)
- then r := vevlcm(ev,vdpevlmon p).r
- else n := groebmakepair(p,gk) . n;
-
- % delete from new pairs equivalents to coprime lcm.
- for each q in r do
- for each p in n do
- if car p=q then n:=delete(p,n);
- % discard multiples: collect survivers in n
- if !*gtraverso!-sloppy then !*gsugar:=nil;
- n := groebcplistsort(n);
- !*gsugar := t;
- nn := n; n:=nil;
- for each p in nn do
- <<q:=nil;
- for each r in n do
- q:=q or vevdivides!?(car r,car p);
- if not q then n:=groebcplistsortin(p,n);
- >>;
- return groebcplistmerge(d,reversip n);
- end;
- symbolic procedure gtraverso!-pairs!-discard1(gk,d);
- % crit B
- begin scalar gi,gj,tij,evk;
- evk:=vdpevlmon gk;
- for each pij in d do
- <<tij := car pij; gi:=cadr pij; gj:=caddr pij;
- if vevstrictlydivides!?(tt(gi,gk),tij)
- and vevstrictlydivides!?(tt(gj,gk),tij)
- then d:=delete(pij,d);
- >>;
- return d;
- end;
- symbolic procedure vevstrictlydivides!?(ev1,ev2);
- not(ev1=ev2) and vevdivides!?(ev1,ev2);
- symbolic procedure gtraverso!-final g;
- % final reduction and sorting;
- begin scalar r,p,!*gsugar;
- g:=vdplsort g; % descending
- while g do
- <<p:=car g; g:=cdr g;
- if not groebsearchinlist(vdpevlmon p,g) then
- r := groebsimpcontnormalform groebnormalform(p,g,'list) . r;
- >>;
- return list reversip r;
- end;
- endmodule;
- end;
|