module groext; % author: Herbert Melenk, ZIB Berlin.
% version 3: removal of the return value 'superfluous' and
% switching to 'groebnerf'.
% version 4: extending ALL bases, which do not reduce the
% polynomial to zero; 'groext11' has now a list for any
% new polynmial with a '1', if the polynomial is not reduced
% to zero by the basis; otherwise it has a '0'.
% version 5: determine the subcases by Groebner base
% computaions.
create!-package('(groext),'(contrib groebner));
load!-package 'groebner;put('groext,'psopfn,'groexteval);
fluid'(groext11);groext11:='(list);share groext11;
symbolic procedure groexteval u;
begin scalar gg,ll,v;
!*groebopt:=nil;
if not(2=length u) then
rerror(groext,1,"groext: illegal number of parameters.");
gg:=reval car u;
if not eqcar(gg,'list) then
rerror(groext,2,"groext: first parameter must be a list of lists.");
gg:=cdr gg;ll:=reval cadr u;
if not eqcar(ll,'list) then
rerror(groext,3,"groext: second parameter must be a list.");
ll:=for each lll in cdr ll collect reval{'num,lll};
v:=groext1(gg,ll);
return if null u then 'empty else if v=t then car u else 'list.v end;
symbolic procedure groext1(gg,ll);
begin scalar a,aa,b,bb,c,ii,l;
l:=length ll;
gg:=for each ggg in gg collect ggg.for each gggg in ggg collect gggg;
groext11:=nil;
for each lll in ll do
<<c:='list.for each ggg in gg collect
<<a:=preduceeval{lll,car ggg};
if a=0 then 0 else<<cdr ggg:=nconc(cdr ggg,{a});1>> >>;
groext11:=c.groext11>>;
groext11:='list.reversip groext11;
for each ggg in gg do ii:=nconc(groext3 cdr ggg,ii);
if null ii then return nil;
% for each iii in ii do if null groext2(iii,ii) then jj:=iii.jj
% else ii:=deletip(iii,ii);
a:=ii;
aa:if null a then go to cc;aa:=car a;a:=cdr a;b:=ii;
bb:if null b then go to aa;bb:=car b;b:=cdr b;
if groext2(aa,bb)then<<ii:=delete(bb,ii);a:=delete(bb,a)>>;go to bb;
cc:return reversip ii end;
symbolic procedure groext2(a,b);
% Test, if the Groebner basis 'a' describes a subproblem of one of
% the Groebner basis 'b'; return 't' then. Otherwise return 'nil'.
if a eq b then nil else
begin scalar !*groebfac;
!*groebfac:=t;return if b=cadr groebner1(append(b,cdr a),nil,nil)then t
else nil end;
fluid'(!*groebfac);
symbolic procedure groext3 a;
% Simulate "Groebner a;".
begin scalar b,!*groebfac;!*groebfac:=t;b:=groebner1(a,nil,nil);
return if b='(list(list 1))then nil else cdr b end;
endmodule;;end;