(* ---------------------------------------------------------------------------- * $Id: DIPDCGB.mi,v 1.3 1994/11/28 20:52:53 dolzmann Exp $ * ---------------------------------------------------------------------------- * This file is part of MAS. * ---------------------------------------------------------------------------- * Copyright (c) 1989 - 1994 Universitaet Passau * ---------------------------------------------------------------------------- * $Log: DIPDCGB.mi,v $ * Revision 1.3 1994/11/28 20:52:53 dolzmann * Syntactical errors corrected. * Usage of predefined procedure types. * * Revision 1.2 1994/11/03 14:40:56 pfeil * added procedures SetTraceLevel, SetDecompProc, SetUpdateProc, SetVarOrdOpt, * SetFacSugar, SetReduceExp, SetBranchProc, WriteDCGBopt. * modified procedure GroebnerBases1 for sugar. * added procedure EQIEQ (Graebe/Lassner) for procedure GrobnerBases2 * * Revision 1.1 1994/08/31 13:27:50 pfeil * Initial revision * * ---------------------------------------------------------------------------- *) IMPLEMENTATION MODULE DIPDCGB; (* DIP Decompositional Groebner Bases Implementation Module. *) (* Import lists and declarations. *) FROM MASBIOS IMPORT SWRITE, BLINES; FROM MASSTOR IMPORT LIST, SIL, COMP, ADV, FIRST, RED, SFIRST, LIST1, INV, TIME, LENGTH; FROM MASERR IMPORT severe, ERROR; FROM MASLISPU IMPORT PROCF1, PROCF2, PROCP1V2, PROCP0V2; FROM SACLIST IMPORT EQUAL, SECOND, FIRST2, AWRITE, LIST2, LIST5, LWRITE, OWRITE, CONC, CCONC; FROM SACRN IMPORT RNINT; FROM DIPC IMPORT DIPTDG, DIPEVL, VALIS, DILPERM, DIPLPM; FROM DIPADOM IMPORT DIWRIT, DIPFAC, DIPSFF, DIPNF, DIPS, DIPEXP, DIPIRL; FROM DIPTOO IMPORT DIPVOPP, INVPERM; FROM DIPAGB IMPORT ECPPOLY1, ECPPOLY2, ECPSELECT, EDIPEVL, EDIPNOR, EDIPSP, EDIPSUGAR, EDIPSUGCON, EDIPUNEXTEND, EDIPWRITE, LDIPEXTEND, LECPWRITE, LEDIPUNEXTEND, LEDIPWRITE, SetDIPAGBStrategy, UpdateVariableWeight, UPDATE; CONST rcsidi = "$Id: DIPDCGB.mi,v 1.3 1994/11/28 20:52:53 dolzmann Exp $"; CONST copyrighti = "Copyright (c) 1989 - 1994 Universitaet Passau"; VAR DCGBopt: RECORD TraceLevel: INTEGER; DecompProc: PROCF2; DPNo: INTEGER; UpdateProc: PROCP1V2; UPNo: INTEGER; VarOrdOpt: INTEGER; FacSugar: INTEGER; ReduceExp: INTEGER; BranchProc: PROCF1; BPNo: INTEGER; END; (* ------------------------------------------------------------------------ * * 0. option procedures * * ------------------------------------------------------------------------ *) PROCEDURE SetTraceLevel(TL: INTEGER); (* Set Trace-Level for decompositional groebner bases: 0 = no output, except with VOOB, >0 = output of time and result after computation, >1 = output of messages about tree of computation: number of canceled branches/factors, "cancel factor", "cancel branch", "groebner base", "branch w.o. zeros", >2 = output of s-polynomials and normalforms, >3 = output of parameters of local procedures and of time and groebner bases during computation. *) BEGIN DCGBopt.TraceLevel:=TL; END SetTraceLevel; PROCEDURE SetDecompProc(DCP: INTEGER); (* Set Decomposition-Procedure for decompositional groebner bases: 1 = DIPFAC, 2 = DIPSFF. *) BEGIN CASE DCP OF 1: DCGBopt.DecompProc:=DIPFAC; | 2: DCGBopt.DecompProc:=DIPSFF; ELSE ERROR(severe,"SetDecompProc: unknown DecompProc option"); END; (* CASE DCP... *) DCGBopt.DPNo:=DCP; END SetDecompProc; PROCEDURE SetUpdateProc(UP: INTEGER); (* Set Update-Procedure for decompositional groebner bases: 1 = UPDATE from module DIPAGB. *) BEGIN CASE UP OF 1: DCGBopt.UpdateProc:=UPDATE; ELSE ERROR(severe,"SetUpdateProc: unknown UpdateProc option"); END; (* CASE UP... *) DCGBopt.UPNo:=UP; END SetUpdateProc; PROCEDURE SetVarOrdOpt(VOO: INTEGER); (* Set Variable-Order-Optimization for decompositional groebner bases: 0 = don`t optimize, 1 = optimize at begin only, 2 = optimize factorization only, 3 = optimize at begin and factorization *) BEGIN IF (VOO<0) OR (VOO>3) THEN ERROR(severe,"SetVarOrdOpt: unknown VarOrdOpt option"); END; DCGBopt.VarOrdOpt:=VOO; END SetVarOrdOpt; PROCEDURE SetFacSugar(FS: INTEGER); (* Set Factor-Sugar for procedure GroebnerBases1: 0 = normal strategy (no sugar) 1 = sugar of factor is total degree of factor, 2 = sugar of factor is old sugar *) BEGIN IF (FS<0) OR (FS>2) THEN ERROR(severe,"SetFacSugar: unknown FacSugar option"); END; DCGBopt.FacSugar:=FS; END SetFacSugar; PROCEDURE SetReduceExp(RE: INTEGER); (* Set Reduce-Exponent for procedure GroebnerBases2: 1 = reduce (no power of) polynomial >1 = reduce corresponding power of polynomial *) BEGIN IF RE<1 THEN ERROR(severe,"SetReduceExp: unknown ReduceExp option"); END; DCGBopt.ReduceExp:=RE; END SetReduceExp; PROCEDURE SetBranchProc(BP: INTEGER); (* Set Branch-Procedure for procedure GroebnerBases2: 1 = SSCO - new branch for each subset of factors, 2 = EQIEQ - new branch for each factor *) BEGIN CASE BP OF 1: DCGBopt.BranchProc:=SSCO; | 2: DCGBopt.BranchProc:=EQIEQ; ELSE ERROR(severe,"SetBranchProc: unknown BranchProc option"); END; (* CASE BP... *) DCGBopt.BPNo:=BP; END SetBranchProc; PROCEDURE SetDCGBopt(options: LIST); (* Set options for decompositional groebner bases. options is a list of 7 or less elements in following order: 1. Trace-Level (0-4), 2. No. of Decomposition-Procedure (1,2), 3. No. of Update-Procedure (1), 4. Optimization of variable order (0,1,2,3), 5. Sugar of factors for Procedure GroebnerBases1 (0,1,2), 6. Reduce-Exponent for procedure GroebnerBases2 (>0), 7. No. of Branch-Procedure in GroebnerBases2 (1,2). *) VAR TL,DCP,UP,VOO,RE,FS,BP: INTEGER; BEGIN IF options<>SIL THEN ADV(options,TL,options); SetTraceLevel(TL); IF options<>SIL THEN ADV(options,DCP,options); SetDecompProc(DCP); IF options<>SIL THEN ADV(options,UP,options); SetUpdateProc(UP); IF options<>SIL THEN ADV(options,VOO,options); SetVarOrdOpt(VOO); IF options<>SIL THEN ADV(options,FS,options); SetFacSugar(FS); IF options<>SIL THEN ADV(options,RE,options); SetReduceExp(RE); IF options<>SIL THEN ADV(options,BP,options); SetBranchProc(BP); END; END; END; END; END; END; END; END SetDCGBopt; PROCEDURE WriteDCGBopt; (* write decompositional groebner bases options *) BEGIN SWRITE("TraceLevel : "); AWRITE(DCGBopt.TraceLevel); BLINES(0); SWRITE("DecompProc : "); CASE DCGBopt.DPNo OF 1: SWRITE("DIPFAC"); | 2: SWRITE("DIPSFF"); END; (* CASE ... *) BLINES(0); SWRITE("UpdateProc : "); CASE DCGBopt.UPNo OF 1: SWRITE("UPDATE"); END; (* CASE ... *) BLINES(0); SWRITE("VarOrdOpt : "); AWRITE(DCGBopt.VarOrdOpt); BLINES(0); SWRITE("FacSugar : "); AWRITE(DCGBopt.FacSugar); BLINES(0); SWRITE("ReduceExp : "); AWRITE(DCGBopt.ReduceExp); BLINES(0); SWRITE("BranchProc : "); CASE DCGBopt.BPNo OF 1: SWRITE("SSCO"); | 2: SWRITE("EQIEQ"); END; (* CASE ... *) BLINES(0); END WriteDCGBopt; (* ------------------------------------------------------------------------ * * 1. The main function GroebnerBases1 * * ------------------------------------------------------------------------ *) PROCEDURE GroebnerBases1(G: LIST): LIST; (* Distributive polynomials decompositional groebner bases. G is a list of polynomials in distributive representation over an arbitrary domain, returns a list (GB1,...,GBk) of groebner bases, where Z(G) = Z(GB1) v ... v Z(GBk). *) VAR GBList,T,t,OldVarL,PermV,invPV,VOOF,VOOB: LIST; nocb: INTEGER; CS: BOOLEAN; PROCEDURE RECGB1(G,Fcmp: LIST): LIST; VAR H,g,HTg,HTf,G1,F,GBList,f,B: LIST; CS: BOOLEAN; BEGIN IF DCGBopt.TraceLevel>3 THEN SWRITE("R1"); BLINES(0); PWrite(1,G); PWrite(4,Fcmp); BLINES(1); END; H:=SIL; WHILE G<>SIL DO ADV(G,g,G); IF DIPTDG(g)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= branch w.o. zeros ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; G1:=CCONC(G,H); F:=newFactors(G1,g,Fcmp); IF DCGBopt.TraceLevel>3 THEN PWrite(2,F); END; IF F=SIL THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= cancel branch ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; ADV(F,f,F); IF F=SIL THEN HTg:=DIPEVL(g); HTf:=DIPEVL(f); IF EQUAL(HTg,HTf)=1 THEN H:=COMP(f,H); ELSE G:=COMP(f,G1); DIPIRL(G,CS); H:=SIL; END; (* IF EQUAL... *) ELSE GBList:=SIL; LOOP (* 1 *) G:=COMP(f,G1); DIPIRL(G,CS); GBList:=CONC(GBList,RECGB1(G,Fcmp)); IF F=SIL THEN EXIT; END; Fcmp:=COMP(f,Fcmp); ADV(F,f,F); END; (* LOOP 1 *) RETURN(GBList); END; (* IF F... *) END; (* WHILE G... *) Init(H,B); RETURN(RECGB2(H,B,Fcmp)); END RECGB1; PROCEDURE RECGB2(G,B,Fcmp: LIST): LIST; VAR CP,g1,g2,S,h,F,oldG,oldB,f,GBList: LIST; CS: BOOLEAN; BEGIN IF DCGBopt.TraceLevel>3 THEN SWRITE("R2"); BLINES(0); PWrite(1,G); PPWrite(B); PWrite(4,Fcmp); BLINES(1); END; WHILE B<>SIL DO ADV(B,CP,B); FIRST2(CP,g1,g2); S:=DIPS(g1,g2); IF DCGBopt.TraceLevel>2 THEN DIWRIT(S,VALIS); END; IF S<>0 THEN h:=DIPNF(G,S); IF DCGBopt.TraceLevel>2 THEN DIWRIT(h,VALIS); BLINES(0); END; IF h<>0 THEN IF DIPTDG(h)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= branch w.o. zeros ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; F:=newFactors(G,h,Fcmp); IF DCGBopt.TraceLevel>3 THEN PWrite(2,F); END; IF F=SIL THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= cancel branch ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; ADV(F,f,F); IF F=SIL THEN DCGBopt.UpdateProc(f,G,B); ELSE GBList:=SIL; oldG:=G; oldB:=B; LOOP (* 1 *) G:=oldG; B:=oldB; DCGBopt.UpdateProc(f,G,B); GBList:=CONC(GBList,RECGB2(G,B,Fcmp)); IF F=SIL THEN EXIT; END; Fcmp:=COMP(f,Fcmp); ADV(F,f,F); END; (* LOOP 1 *) RETURN(GBList); END; (* IF F... *) END; (* IF h... *) ELSE IF DCGBopt.TraceLevel>2 THEN BLINES(0); END; END; (* IF S... *) END; (* WHILE B... *) DIPIRL(G,CS); IF CS THEN RETURN(RECGB1(G,Fcmp)); ELSE IF DCGBopt.TraceLevel>1 THEN SWRITE("= groebner base ="); BLINES(0); IF DCGBopt.TraceLevel>3 THEN t:=TIME()-T; SWRITE("Time :"); AWRITE(t); PWrite(0,G); BLINES(0); END; (* IF DCGBopt... *) END; (* IF DCGBopt... *) RETURN(LIST1(G)); END; (* IF CS... *) END RECGB2; PROCEDURE newFactors(G,h,Fcmp: LIST): LIST; VAR Fnew,F,ExpPol,hi,FL,g,G1: LIST; BEGIN Fnew:=SIL; F:=DCGBopt.DecompProc(h,VOOF); (* factorization *) F:=SortF(F); (* sort factors in non-increasing order *) WHILE F<>SIL DO ADV(F,hi,F); G1:=COMP(hi,G); FL:=Fcmp; LOOP (* 1 *) IF FL=SIL THEN Fnew:=COMP(hi,Fnew); Fcmp:=COMP(hi,Fcmp); EXIT; END; ADV(FL,g,FL); IF DIPNF(G1,g)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= cancel factor ="); nocb:=nocb+1; BLINES(0); END; EXIT; END; END; (* LOOP 1 *) END; (* WHILE F... *) RETURN(INV(Fnew)); END newFactors; PROCEDURE REC1(G,Fcmp1: LIST): LIST; VAR H,g,h,HTg,HTf,G1,F,GBList,f,B: LIST; CS: BOOLEAN; BEGIN IF DCGBopt.TraceLevel>3 THEN SWRITE("R1"); BLINES(0); LEDIPWRITE(G); PWrite(4,Fcmp1); BLINES(1); END; H:=SIL; WHILE G<>SIL DO ADV(G,g,G); IF DIPTDG(EDIPPOLY(g))=0 THEN (* g constant *) IF DCGBopt.TraceLevel>1 THEN SWRITE("= branch w.o. zeros ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; G1:=CCONC(G,H); F:=EnewFactors(G1,g,Fcmp1); IF DCGBopt.TraceLevel>3 THEN SWRITE("F = "); BLINES(0); LEDIPWRITE(F); END; IF F=SIL THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= cancel branch ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; ADV(F,f,F); IF F=SIL THEN HTg:=EDIPEVL(g); HTf:=EDIPEVL(f); IF EQUAL(HTg,HTf)=1 THEN H:=COMP(f,H); ELSE G:=COMP(f,G1); EDIPIRL(G,CS); H:=SIL; END; (* IF EQUAL... *) ELSE GBList:=SIL; LOOP (* 1 *) G:=COMP(f,G1); EDIPIRL(G,CS); GBList:=CONC(GBList,REC1(G,Fcmp1)); IF F=SIL THEN EXIT; END; Fcmp1:=COMP(EDIPPOLY(f),Fcmp1); ADV(F,f,F); END; (* LOOP 1 *) RETURN(GBList); END; (* IF F... *) END; (* WHILE G... *) Init(H,B); RETURN(REC2(H,B,Fcmp1)); END REC1; PROCEDURE REC2(G,B,Fcmp2: LIST): LIST; VAR CP,g1,g2,S,h,h1,F,oldG,oldB,f,GBList: LIST; CS: BOOLEAN; BEGIN IF DCGBopt.TraceLevel>3 THEN SWRITE("R2"); BLINES(0); LEDIPWRITE(G); LECPWRITE(B); PWrite(4,Fcmp2); BLINES(1); END; WHILE B<>SIL DO ECPSELECT(B,CP,B); g1:=ECPPOLY1(CP); g2:=ECPPOLY2(CP); S:=EDIPSP(g1,g2); IF DCGBopt.TraceLevel>2 THEN EDIPWRITE(S); END; IF FIRST(S)<>0 THEN h:=EDIPNOR(G,S); IF DCGBopt.TraceLevel>2 THEN EDIPWRITE(h); BLINES(0); END; h1:=EDIPPOLY(h); IF h1<>0 THEN IF DIPTDG(h1)=0 THEN (* h1 constant *) IF DCGBopt.TraceLevel>1 THEN SWRITE("= branch w.o. zeros ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; F:=EnewFactors(G,h,Fcmp2); IF DCGBopt.TraceLevel>3 THEN SWRITE("F = "); BLINES(0); LEDIPWRITE(F); END; IF F=SIL THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= cancel branch ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; ADV(F,f,F); IF F=SIL THEN DCGBopt.UpdateProc(f,G,B); ELSE GBList:=SIL; oldG:=G; oldB:=B; LOOP (* 1 *) G:=oldG; B:=oldB; DCGBopt.UpdateProc(f,G,B); GBList:=CONC(GBList,REC2(G,B,Fcmp2)); IF F=SIL THEN EXIT; END; Fcmp2:=COMP(EDIPPOLY(f),Fcmp2); ADV(F,f,F); END; (* LOOP 1 *) RETURN(GBList); END; (* IF F... *) END; (* IF h... *) ELSE IF DCGBopt.TraceLevel>2 THEN BLINES(0); END; END; (* IF S... *) END; (* WHILE B... *) EDIPIRL(G,CS); IF CS THEN RETURN(REC1(G,Fcmp2)); ELSE IF DCGBopt.TraceLevel>1 THEN SWRITE("= groebner base ="); BLINES(0); IF DCGBopt.TraceLevel>3 THEN t:=TIME()-T; SWRITE("Time :"); AWRITE(t); BLINES(0); LEDIPWRITE(G); BLINES(0); END; (* IF DCGBopt... *) END; (* IF DCGBopt... *) RETURN(LIST1(G)); END; (* IF CS... *) END REC2; PROCEDURE EnewFactors(G,h,Fcmp: LIST): LIST; (* G is a list of extended polynomials in distributive representation, Fcmp is a list of polynomials in distributive representation, h is an extended polynomial in distributive representation *) VAR Fnew,Sugar,F,ExpPol,hi,FL,g,G1,h1: LIST; BEGIN Fnew:=SIL; FIRST2(h,h1,Sugar); G:=LEDIPUNEXTEND(G); F:=DCGBopt.DecompProc(h1,VOOF); (* factorization *) F:=SortF(F); (* sort factors in non-increasing order *) WHILE F<>SIL DO ADV(F,hi,F); G1:=COMP(hi,G); FL:=Fcmp; LOOP (* 1 *) IF FL=SIL THEN Fcmp:=COMP(hi,Fcmp); CASE DCGBopt.FacSugar OF 1: Fnew:=COMP(LIST2(hi,RNINT(DIPTDG(hi))),Fnew); | 2: Fnew:=COMP(LIST2(hi,Sugar),Fnew); END; (* CASE ... *) EXIT; END; (* if FL... *) ADV(FL,g,FL); IF DIPNF(G1,g)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= cancel factor ="); BLINES(0); nocb:=nocb+1; END; EXIT; END; (* IF DIPNF... *) END; (* LOOP 1 *) END; (* WHILE F... *) RETURN(INV(Fnew)); END EnewFactors; BEGIN CASE DCGBopt.FacSugar OF 0: SetDIPAGBStrategy(0); | (* strategy = normal *) 1,2: SetDIPAGBStrategy(1); (* strategy = normal with sugar *) END; (* CASE ... *) IF G=SIL THEN ERROR(severe,"GB1: undefined ideal"); END; IF ZeroPoly(G) THEN ERROR(severe,"GB1: zero polynomial"); END; T:=TIME(); CASE DCGBopt.VarOrdOpt OF 1: VOOB:=1; VOOF:=0; | 2: VOOB:=0; VOOF:=1; | 3: VOOB:=1; VOOF:=1; ELSE VOOB:=0; VOOF:=0; END; (* DCGBopt... *) IF VOOB=1 THEN OldVarL:=VALIS; DIPVOPP(G,OldVarL,G,VALIS,PermV); invPV:=INVPERM(PermV); END; (* IF VOOB... *) nocb:=0; CASE DCGBopt.FacSugar OF 0: DIPIRL(G,CS); GBList:=RECGB1(G,SIL); | 1,2: UpdateVariableWeight; G:=LDIPEXTEND(G); EDIPIRL(G,CS); GBList:=LLEDIPUNEXTEND(REC1(G,SIL)); END; (* CASE ... *) IF VOOB=1 THEN VALIS:=OldVarL; BLINES(1); SWRITE("= changed variable order ="); GBList:=SGBLwrtVO1(GBList,invPV); END; (* IF VOOB... *) IF DCGBopt.TraceLevel>0 THEN t:=TIME()-T; IF DCGBopt.TraceLevel>1 THEN BLINES(0); SWRITE("Number of canceled branches/factors : "); AWRITE(nocb); END; BLINES(1); SWRITE("Time : "); AWRITE(t); SWRITE(" ms"); SWRITE(" with program GB1 :"); CWrite1(GBList); END; (* IF DCGBopt... *) RETURN(GBList); END GroebnerBases1; (* ------------------------------------------------------------------------ *) PROCEDURE SGBLwrtVO1(GBL,invPV: LIST): LIST; (* sort groebner bases list w.r.t. variable order *) VAR GBLnew,G: LIST; BEGIN GBLnew:=SIL; WHILE GBL<>SIL DO ADV(GBL,G,GBL); G:=DILPERM(G,invPV); GBLnew:=COMP(G,GBLnew); END; RETURN(GBLnew); END SGBLwrtVO1; PROCEDURE CWrite1(gbl: LIST); VAR i: INTEGER; G: LIST; BEGIN BLINES(1); i:=1; WHILE gbl<>SIL DO ADV(gbl,G,gbl); AWRITE(i); SWRITE(". GB with "); AWRITE(LENGTH(G)); SWRITE(" equation(s)"); BLINES(0); PWrite(0,G); BLINES(1); i:=i+1; END; END CWrite1; PROCEDURE LLEDIPUNEXTEND(P: LIST): LIST; (* List of lists of extended distributive polynomials un-extend. P is a list of lists of extended distributive polynomials. LLEDIPUNEXTEND(P) is the list of lists of the appropriate distributive polynomials. *) VAR Pnew,PL: LIST; BEGIN Pnew:=SIL; WHILE P<>SIL DO ADV(P,PL,P); Pnew:=COMP(LEDIPUNEXTEND(PL),Pnew); END; (* while P... *) RETURN(Pnew); END LLEDIPUNEXTEND; PROCEDURE EDIPPOLY(PS: LIST): LIST; (* Extended distributive polynomial *) VAR p: LIST; BEGIN CASE DCGBopt.FacSugar OF 0: p:=PS; | 1,2: p:=FIRST(PS); END; (* CASE ... *) RETURN(p); END EDIPPOLY; PROCEDURE EDIPIRL(VAR P: LIST; VAR CS: BOOLEAN); (* Extended distributive polynomials interreduced list of polynomials. P is a list of extended polynomials in distributive representation over an arbitrary domain, CS is a flag, CS = TRUE iff P is changed, returns a interreduced list of polynomials R=(p1,...,pk), R is the result of reducing each pi modulo R-(pi) until no further reductions are possible. *) VAR H,f,f1,HTf1,HTg1,g,g1: LIST; NewHT: BOOLEAN; BEGIN CS:=FALSE; REPEAT H:=SIL; NewHT:=FALSE; WHILE P<>SIL DO ADV(P,f,P); f1:=EDIPPOLY(f); HTf1:=DIPEVL(f1); g:=EDIPNOR(CCONC(P,H),f); g1:=EDIPPOLY(g); IF g1<>0 THEN HTg1:=DIPEVL(g1); IF EQUAL(HTf1,HTg1)=1 THEN IF EQUAL(f1,g1)<>1 THEN CS:=TRUE; END; ELSE NewHT:=TRUE; CS:=TRUE; END; (* IF EQUAL... *) H:=COMP(g,H); END; (* IF g1<>0... *) END; (* WHILE ... *) P:=H; UNTIL NOT(NewHT); END EDIPIRL; (* ------------------------------------------------------------------------ * * 2. The main function GroebnerBases2 * * ------------------------------------------------------------------------ *) PROCEDURE GroebnerBases2(G,U: LIST): LIST; (* Distributive polynomials decompositional groebner bases 2. G and U are lists of polynomials in distributive representation over an arbitrary domain, returns a list ((GB1,U1),...,(GBk,Uk)) of pairs (Gi,Ui), where Gi is a groebner bases, Ui is a list of polynomials and Z(G) n D(U) = (Z(GB1) n D(U1)) v ... v (Z(GBk) n D(Uk)). *) VAR GBList,T,t,OldVarL,PermV,invPV,VOOF,VOOB: LIST; nocb: INTEGER; CS: BOOLEAN; PROCEDURE RECGB1(G,U: LIST): LIST; VAR H,g,HTg,HTf,G1,F,GBList,f,B,SCL,SC,U1,G2: LIST; CS: BOOLEAN; BEGIN IF DCGBopt.TraceLevel>3 THEN SWRITE("R1"); BLINES(0); PWrite(1,G); PWrite(3,U); END; H:=SIL; WHILE G<>SIL DO ADV(G,g,G); IF DIPTDG(g)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= branch w.o. zeros ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; G1:=CCONC(G,H); F:=DCGBopt.DecompProc(g,VOOF); IF DCGBopt.TraceLevel>3 THEN PWrite(5,F); END; IF RED(F)=SIL THEN HTg:=DIPEVL(g); f:=SECOND(FIRST(F)); HTf:=DIPEVL(f); IF EQUAL(HTg,HTf)=1 THEN H:=COMP(f,H); ELSE G:=COMP(f,G1); DIPIRL(G,CS); IF NOT(TEII(U,G)) THEN RETURN(SIL); END; H:=SIL; END; (* IF EQUAL... *) ELSE SCL:=DCGBopt.BranchProc(F); GBList:=SIL; WHILE SCL<>SIL DO ADV(SCL,SC,SCL); FIRST2(SC,G2,U1); G2:=CCONC(G2,G1); U1:=CCONC(U1,U); DIPIRL(G2,CS); IF TEII(U1,G2) THEN GBList:=CONC(GBList,RECGB1(G2,U1)); END; END; (* WHILE SCL... *) RETURN(GBList); END; (* IF RED(F)... *) END; (* WHILE G... *) Init(H,B); RETURN(RECGB2(H,U,B)); END RECGB1; PROCEDURE RECGB2(G,U,B: LIST): LIST; VAR CP,g1,g2,S,h,F,oldG,oldB,SCL,SC,G1,U1,f,GBList: LIST; CS: BOOLEAN; BEGIN IF DCGBopt.TraceLevel>3 THEN SWRITE("R2"); BLINES(0); PWrite(1,G); PWrite(3,U); PPWrite(B); END; WHILE B<>SIL DO ADV(B,CP,B); FIRST2(CP,g1,g2); S:=DIPS(g1,g2); IF DCGBopt.TraceLevel>2 THEN DIWRIT(S,VALIS); END; IF S<>0 THEN h:=DIPNF(G,S); IF DCGBopt.TraceLevel>2 THEN DIWRIT(h,VALIS); BLINES(0); END; IF h<>0 THEN IF DIPTDG(h)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= branch w.o. zeros ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; F:=DCGBopt.DecompProc(h,VOOF); IF DCGBopt.TraceLevel>3 THEN PWrite(5,F); END; IF RED(F)=SIL THEN f:=SECOND(FIRST(F)); DCGBopt.UpdateProc(f,G,B); IF NOT(TEII(U,G)) THEN RETURN(SIL); END; ELSE SCL:=DCGBopt.BranchProc(F); oldG:=G; oldB:=B; GBList:=SIL; REPEAT ADV(SCL,SC,SCL); FIRST2(SC,G1,U1); G:=oldG; B:=oldB; WHILE G1<>SIL DO ADV(G1,f,G1); DCGBopt.UpdateProc(f,G,B); END; (* WHILE G1... *) U1:=CCONC(U1,U); IF TEII(U1,G) THEN GBList:=CONC(GBList,RECGB2(G,U1,B)); END; UNTIL SCL=SIL; RETURN(GBList); END; (* IF RED... *) END; (* IF h... *) END; (* IF S... *) END; (* WHILE B... *) DIPIRL(G,CS); IF CS THEN IF TEII(U,G) THEN RETURN(RECGB1(G,U)); END; RETURN(SIL); ELSE IF DCGBopt.TraceLevel>1 THEN SWRITE("= groebner base ="); BLINES(0); IF DCGBopt.TraceLevel>3 THEN t:=TIME()-T; SWRITE("Time :"); AWRITE(t); PWrite(0,G); PWrite(0,U); BLINES(0); END; (* IF DCGBopt... *) END; (* IF DCGBopt... *) RETURN(LIST1(LIST2(G,U))); END; (* IF CS... *) END RECGB2; PROCEDURE REC1(G,U: LIST): LIST; VAR H,g,HTg,HTf,G1,F,GBList,f,B,SCL,SC,U1,G2: LIST; CS: BOOLEAN; BEGIN IF DCGBopt.TraceLevel>3 THEN SWRITE("R1"); BLINES(0); PWrite(1,G); PWrite(3,U); END; H:=SIL; WHILE G<>SIL DO ADV(G,g,G); IF DIPTDG(g)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= branch w.o. zeros ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; G1:=CCONC(G,H); F:=DCGBopt.DecompProc(g,VOOF); IF DCGBopt.TraceLevel>3 THEN PWrite(5,F); END; IF RED(F)=SIL THEN HTg:=DIPEVL(g); f:=SECOND(FIRST(F)); HTf:=DIPEVL(f); IF EQUAL(HTg,HTf)=1 THEN H:=COMP(f,H); ELSE G:=COMP(f,G1); DIPIRL(G,CS); IF NOT(TEII(U,G)) THEN RETURN(SIL); END; H:=SIL; END; (* IF EQUAL... *) ELSE SCL:=DCGBopt.BranchProc(F); GBList:=SIL; WHILE SCL<>SIL DO ADV(SCL,SC,SCL); FIRST2(SC,g,U1); G2:=COMP(g,G1); U1:=CCONC(U1,U); DIPIRL(G2,CS); IF TEII(U1,G2) THEN GBList:=CONC(GBList,REC1(G2,U1)); END; END; (* WHILE SCL... *) RETURN(GBList); END; (* IF RED(F)... *) END; (* WHILE G... *) Init(H,B); RETURN(REC2(H,U,B)); END REC1; PROCEDURE REC2(G,U,B: LIST): LIST; VAR CP,g1,g2,S,h,F,oldG,oldB,SCL,SC,U1,f,GBList: LIST; CS: BOOLEAN; BEGIN IF DCGBopt.TraceLevel>3 THEN SWRITE("R2"); BLINES(0); PWrite(1,G); PWrite(3,U); PPWrite(B); END; WHILE B<>SIL DO ADV(B,CP,B); FIRST2(CP,g1,g2); S:=DIPS(g1,g2); IF DCGBopt.TraceLevel>2 THEN DIWRIT(S,VALIS); END; IF S<>0 THEN h:=DIPNF(G,S); IF DCGBopt.TraceLevel>2 THEN DIWRIT(h,VALIS); BLINES(0); END; IF h<>0 THEN IF DIPTDG(h)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= branch w.o. zeros ="); nocb:=nocb+1; BLINES(0); END; RETURN(SIL); END; F:=DCGBopt.DecompProc(h,VOOF); IF DCGBopt.TraceLevel>3 THEN PWrite(5,F); END; IF RED(F)=SIL THEN f:=SECOND(FIRST(F)); DCGBopt.UpdateProc(f,G,B); IF NOT(TEII(U,G)) THEN RETURN(SIL); END; ELSE SCL:=DCGBopt.BranchProc(F); oldG:=G; oldB:=B; GBList:=SIL; REPEAT ADV(SCL,SC,SCL); FIRST2(SC,f,U1); G:=oldG; B:=oldB; DCGBopt.UpdateProc(f,G,B); U1:=CCONC(U1,U); IF TEII(U1,G) THEN GBList:=CONC(GBList,REC2(G,U1,B)); END; UNTIL SCL=SIL; RETURN(GBList); END; (* IF RED... *) END; (* IF h... *) END; (* IF S... *) END; (* WHILE B... *) DIPIRL(G,CS); IF CS THEN IF TEII(U,G) THEN RETURN(REC1(G,U)); END; RETURN(SIL); ELSE IF DCGBopt.TraceLevel>1 THEN SWRITE("= groebner base ="); BLINES(0); IF DCGBopt.TraceLevel>3 THEN t:=TIME()-T; SWRITE("Time :"); AWRITE(t); PWrite(0,G); PWrite(0,U); BLINES(0); END; (* IF DCGBopt... *) END; (* IF DCGBopt... *) RETURN(LIST1(LIST2(G,U))); END; (* IF CS... *) END REC2; PROCEDURE TEII(U,G: LIST): BOOLEAN; (* Test equations and inequations for inconsistence *) VAR u: LIST; BEGIN IF DCGBopt.ReduceExp=1 THEN WHILE U<>SIL DO ADV(U,u,U); IF DIPNF(G,u)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= cancel branch ="); nocb:=nocb+1; BLINES(0); END; RETURN(FALSE); END; (* IF DIPNF... *) END; (* WHILE U... *) ELSE WHILE U<>SIL DO ADV(U,u,U); u:=DIPEXP(u,DCGBopt.ReduceExp); IF DIPNF(G,u)=0 THEN IF DCGBopt.TraceLevel>1 THEN SWRITE("= cancel branch ="); nocb:=nocb+1; BLINES(0); END; RETURN(FALSE); END; (* IF DIPNF... *) END; (* WHILE U... *) END; (* IF DCGBopt... *) RETURN(TRUE); END TEII; BEGIN SetDIPAGBStrategy(0); (* strategy = normal *) IF G=SIL THEN ERROR(severe,"GB2: undefined ideal"); END; IF ZeroPoly(G) THEN ERROR(severe,"GB2: zero polynomial"); END; T:=TIME(); CASE DCGBopt.VarOrdOpt OF 1: VOOB:=1; VOOF:=0; | 2: VOOB:=0; VOOF:=1; | 3: VOOB:=1; VOOF:=1; ELSE VOOB:=0; VOOF:=0; END; (* DCGBopt... *) IF VOOB=1 THEN OldVarL:=VALIS; DIPVOPP(G,OldVarL,G,VALIS,PermV); invPV:=INVPERM(PermV); END; (* IF VOOB... *) GBList:=SIL; nocb:=0; DIPIRL(G,CS); IF TEII(U,G) THEN CASE DCGBopt.BPNo OF 1: GBList:=RECGB1(G,U); | 2: GBList:=REC1(G,U); END; (* CASE ... *) END; (* IF TEII... *) IF VOOB=1 THEN VALIS:=OldVarL; BLINES(1); SWRITE("= changed variable order ="); GBList:=SGBLwrtVO2(GBList,invPV); END; (* IF VOOB... *) IF DCGBopt.TraceLevel>0 THEN t:=TIME()-T; IF DCGBopt.TraceLevel>1 THEN BLINES(0); SWRITE("Number of canceled branches : "); AWRITE(nocb); END; BLINES(1); SWRITE("Time : "); AWRITE(t); SWRITE(" ms"); SWRITE(" with program GB2 :"); CWrite2(GBList); END; (* IF DCGBopt... *) RETURN(GBList); END GroebnerBases2; (* ------------------------------------------------------------------------ *) PROCEDURE SSCO(M: LIST): LIST; (* compute subsets and their complements *) VAR ML,CS,f,SSL,A,SS,CO,S1,S2,ExpPol: LIST; BEGIN ML:=SIL; CS:=SIL; WHILE M<>SIL DO ADV(M,ExpPol,M); f:=SECOND(ExpPol); SSL:=LIST1(LIST2(LIST1(f),CS)); WHILE ML<>SIL DO ADV(ML,A,ML); FIRST2(A,SS,CO); S1:=LIST2(COMP(f,SS),CO); SSL:=COMP(S1,SSL); S2:=LIST2(SS,COMP(f,CO)); SSL:=COMP(S2,SSL); END; (* WHILE ML... *) CS:=COMP(f,CS); ML:=SSL; END; (* WHILE M... *) RETURN(SSL); END SSCO; PROCEDURE EQIEQ(M: LIST): LIST; (* compute equalities and inequalities *) VAR ML,CS,f: LIST; BEGIN M:=SortF(M); (* sort factors into non-increasing order *) ML:=SIL; CS:=SIL; WHILE M<>SIL DO ADV(M,f,M); ML:=COMP(LIST2(f,CS),ML); CS:=COMP(f,CS); END; (* while M... *) RETURN(ML); END EQIEQ; PROCEDURE SGBLwrtVO2(GBL,invPV: LIST): LIST; (* sort groebner bases list w.r.t. variable order *) VAR GBLnew,GU,G,U: LIST; BEGIN GBLnew:=SIL; WHILE GBL<>SIL DO ADV(GBL,GU,GBL); FIRST2(GU,G,U); G:=DILPERM(G,invPV); U:=DILPERM(U,invPV); GU:=LIST2(G,U); GBLnew:=COMP(GU,GBLnew); END; RETURN(GBLnew); END SGBLwrtVO2; PROCEDURE CWrite2(gbl: LIST); VAR i: INTEGER; gb,G,U: LIST; BEGIN BLINES(1); i:=1; WHILE gbl<>SIL DO ADV(gbl,gb,gbl); FIRST2(gb,G,U); AWRITE(i); SWRITE(". GB with "); AWRITE(LENGTH(G)); SWRITE(" equation(s)"); BLINES(0); PWrite(0,G); SWRITE(" and "); AWRITE(LENGTH(U)); SWRITE(" inequation(s)."); BLINES(0); PWrite(0,U); BLINES(1); i:=i+1; END; END CWrite2; (* ------------------------------------------------------------------------ * * 3. utilities * * ------------------------------------------------------------------------ *) PROCEDURE SortF(F: LIST): LIST; VAR Fnew, ExpPol: LIST; BEGIN Fnew:=SIL; WHILE F<>SIL DO (* remove exponents *) ADV(F,ExpPol,F); Fnew:=COMP(SECOND(ExpPol),Fnew); END; (* WHILE F... *) RETURN(INV(DIPLPM(Fnew))); (* sorting F into non-increasing order *) END SortF; PROCEDURE ZeroPoly(G: LIST): BOOLEAN; (* test polynomial list G for zero-polynomial *) VAR g: LIST; BEGIN WHILE G<>SIL DO ADV(G,g,G); IF g=0 THEN RETURN(TRUE); END; END; (* while G... *) RETURN(FALSE); END ZeroPoly; PROCEDURE Init(VAR G,B: LIST); (* initialize critical pair list B and list of generating polynomials G. *) VAR f,D: LIST; BEGIN D:=SIL; B:=SIL; WHILE G<>SIL DO ADV(G,f,G); DCGBopt.UpdateProc(f,D,B); END; G:=D; END Init; PROCEDURE PWrite(S,P: LIST); (* write list of polynomials *) VAR p: LIST; BEGIN IF S=1 THEN SWRITE(" List of polynomials:"); END; IF (S=2) OR (S=5) THEN SWRITE(" List of factors:"); END; IF S=3 THEN SWRITE(" List of inequations:"); END; IF S=4 THEN SWRITE(" List of branches to compare:"); END; BLINES(0); WHILE P<>SIL DO ADV(P,p,P); IF S=5 THEN p:=SECOND(p); END; SWRITE(" "); DIWRIT(p,VALIS); BLINES(0); END; BLINES(0); END PWrite; PROCEDURE PPWrite(PP: LIST); (* write list of polynomial pairs *) VAR CP,g1,g2: LIST; BEGIN SWRITE(" List of critical pairs:"); BLINES(0); WHILE PP<>SIL DO ADV(PP,CP,PP); FIRST2(CP,g1,g2); SWRITE(" < "); DIWRIT(g1,VALIS); SWRITE(" , "); DIWRIT(g2,VALIS); SWRITE(" >"); BLINES(0); END; BLINES(0); END PPWrite; (* ------------------------------------------------------------------------ *) BEGIN DCGBopt.TraceLevel:=0; DCGBopt.DecompProc:=DIPFAC; DCGBopt.DPNo:=1; DCGBopt.UpdateProc:=UPDATE; DCGBopt.UPNo:=1; DCGBopt.VarOrdOpt :=0; DCGBopt.FacSugar :=0; DCGBopt.ReduceExp :=1; DCGBopt.BranchProc:=SSCO; DCGBopt.BPNo:=1; END DIPDCGB. (* -EOF- *)