(* ---------------------------------------------------------------------------- * $Id: MASUGB.mi,v 1.3 1995/11/05 09:12:10 kredel Exp $ * ---------------------------------------------------------------------------- * This file is part of MAS. * ---------------------------------------------------------------------------- * Copyright (c) 1989 - 1993 Universitaet Passau * ---------------------------------------------------------------------------- * $Log: MASUGB.mi,v $ * Revision 1.3 1995/11/05 09:12:10 kredel * Improved error handling and cosmetic. * * Revision 1.2 1994/03/11 15:47:31 pesch * Corrections suggested by A. Dolzmann. * Correct number of arguments in procedure calls, etc. * * Revision 1.1 1993/05/11 10:11:17 kredel * Initial Revision * * ---------------------------------------------------------------------------- *) IMPLEMENTATION MODULE MASUGB; (* Universal Groebner Bases Implementation Module. *) (* Author: T. Belkahia, Uni Passau, 1992. *) FROM MASSTOR IMPORT ADV, FIRST, LIST, LIST1, RED, SIL, LENGTH, INV, COMP, SRED, SFIRST, BETA; FROM MASERR IMPORT severe, ERROR; FROM MASBIOS IMPORT SWRITE, BLINES, CREADB, MASORD, LETTER, SIUNIT, BKSP, LISTS; FROM SACLIST IMPORT ADV2, AWRITE, LWRITE, CCONC, CINV, COMP2, LIST5, EQUAL, MEMBER, LIST4, THIRD, FOURTH, FIRST2, SECOND, LAST, OREAD, OWRITE, LIST3, LIST2; FROM SACRN IMPORT RNINT, RNQ, RNPROD, RNINV, RNDIF, RNSUM, RNSIGN, RNCOMP, RNABS, RNNEG; FROM MASRN IMPORT RNMAX; FROM SACI IMPORT IQR, IPROD, ILCM, IMAX; FROM SACPOL IMPORT VLREAD; FROM SACSET IMPORT USUN; FROM DIPC IMPORT DIPEVL, DIPFMO, DIPMAD, EVDEL, EVDIF, EVLCM, EVMT, EVIGLC, EVILCP, EVORD, EVSUM, DIPTDG, DIPINV, DIPLBC, DIPMPV, DIPLPM, DILBSO, DIPMCP, VALIS, LEX, INVLEX, GRLEX, IGRLEX; FROM DIPRN IMPORT DIRPDF, DIRPNG, DIRPPR, DIRPQ, DIRPRP, DIRPSM, DIRPMC, DIRLWR, DIRLRD; FROM DIPRNGB IMPORT DIRPNF, DIRPGB, EVPLM, EVPLSO; FROM MASSYM2 IMPORT SREAD1; FROM MASELEM IMPORT GAMMAINT; CONST rcsidi = "$Id: MASUGB.mi,v 1.3 1995/11/05 09:12:10 kredel Exp $"; CONST copyrighti = "Copyright (c) 1989 - 1993 Universitaet Passau"; (*Note: a linear form is represented as a vector of rational numbers, instead as a vector of univariate recursive integral polynomials in the DIPC module. *) PROCEDURE UGBBIN(); (*UGB input, execute and output. Diese hauptprozedur liest die eingabedatei ein (die polynome, die variablen und ihre anzahl durch pread, den parameter durch rdpar und die option durch execrd). Die funktion exeugb wird anschliessend aufgerufen. UGBBIN wird vom hauptprogramm main aufgerufen. *) VAR I, L, OPT, PAR, V: LIST; BEGIN (*1*) PREAD(L,I,V); OPREAD(PAR,OPT); EXEUGB(L,I,V,PAR,OPT); (*4*) RETURN; END UGBBIN; PROCEDURE EXEUGB(L,I,V,PAR,OPT: LIST); (*UGB execute. Diese prozedur ruft, abhaengig von der option opt die prozeduren lf, plf, ugb und pugb. Diese prozeduren realisieren die verschiedenen optionen, die im abschnitt benutzerschnittstelle besprochen wurden. Die prozedur wird von der hauptprozedur ugbbin aufgerufen. *) BEGIN (*1*) IF MEMBER(1,OPT) = 1 THEN LF(L,I,V,PAR,OPT); ELSE IF MEMBER(2,OPT) = 1 THEN PLF(L,I,V,PAR,OPT); ELSE IF MEMBER(3,OPT) = 1 THEN UGB(L,I,V,PAR,OPT); ELSE IF MEMBER(4,OPT) = 1 THEN PUGB(L,I,V,PAR,OPT); END; END; END; END; (*4*) RETURN; END EXEUGB; PROCEDURE LF(L,I,V,PAR,OPT: LIST); (*UGB linear form. Die prozedur berechnet die linearformen nach der option LF. Vergleiche benutzerschnittstelle und 5.1.6. Die prozedur wird von exeugb aufgerufen. *) VAR DIFALT, KALT, NEUFLF, NURLF, OLDL, P, PALT, Q, STAKK: LIST; BEGIN (*1*) SWRITE("Option ... LF"); BLINES(1); Q:=EXPTU(L); IF PAR = 8 THEN SWRITE("Die Liste der Terme als ganzzahlige Tupel ist "); BLINES(1); OWRITE(Q); BLINES(1); END; P:=MAKERN(Q); PALT:=SIL; DIFALT:=SIL; OLDL:=LIST3(SIL,SIL,SIL); KALT:=SIL; STAKK:=PROJEC(PALT,P,DIFALT,OLDL,I,PAR); ALLELN(STAKK,L,KALT,I,PAR, NEUFLF,NURLF); IF PAR = 8 THEN SWRITE("Die Linearformen sind"); BLINES(1); OWRITE(NEUFLF); BLINES(2); END; (*4*) RETURN; END LF; PROCEDURE PLF(L,I,V,PAR,OPT: LIST); (*UGB linear form with precomputed linear forms. Die prozedur berechnet die linearformen nach der option plf. Vergleiche benutzerschnittstelle und 5.1.7. Die prozedur wird von exeugb aufgerufen. *) VAR DEG, DIFALT, IP, KALT, LFP, LFQ, NEWLF, NP, OLDL, PALT, Q, Q2: LIST; BEGIN (*1*) SWRITE("Option ... PLF"); BLINES(1); SUNIT1(I); (*2*) IP:=I; Q:=EXPTU(L); IF PAR = 8 THEN SWRITE("Die Liste der Terme als ganzzahlige Tupel ist "); BLINES(1); OWRITE(Q); BLINES(1); END; Q:=MAKERN(Q); PALT:=SIL; DIFALT:=SIL; OLDL:=LIST3(SIL,SIL,SIL); KALT:=SIL; PROJ(PALT,Q,DIFALT,OLDL,I, NP,Q2,DEG); IF PAR = 8 THEN SWRITE("Gradschranke dieser Dimension ist "); OWRITE(2*DEG); BLINES(1); END; SWRITE("Datei einlesen ..."); BLINES(1); LFQ:=OREAD(); IF I <> 3 THEN DEG:=2*DEG; END; LFP:=LFGET(DEG,LFQ); IP:=IP-1; IF PAR = 8 THEN OWRITE(LENGTH(LFP)); SWRITE(" eingelesene Linearformen "); BLINES(1); END; SWRITE("Berechnung der Linearformen ... "); BLINES(1); NEWLF:=MKLF1(LFP,Q2,NP,IP); SWRITE("Die berechneten Linearformen sind "); OWRITE(LENGTH(NEWLF)); BLINES(1); IF PAR = 8 THEN SWRITE("Die Linearformen sind"); BLINES(1); OWRITE(NEWLF); BLINES(2); END; (*5*) RETURN; END PLF; PROCEDURE UGB(L,I,V,PAR,OPT: LIST); (*Universal Groebner base. Die prozedur berechnet eine universelle groebner basis nach der option ugb. Vergleiche benutzerschnittstelle und 5.2.4. Die prozedur wird von exeugb aufgerufen. *) VAR DIFALT, G, GB, KALT, NEUFLF, NURLF, OLDL, P, PALT, Q, STAKK, UL: LIST; BEGIN (*1*) SWRITE("Option ... UGB"); BLINES(1); IF I = 1 THEN G:=DIRPGB(L,0); SWRITE("*************************************."); BLINES(1); SWRITE("es gibt nur eine zulaessige Ordnung ."); BLINES(1); SWRITE(" die Linearform ist (1) ."); BLINES(1); SWRITE("*************************************."); BLINES(1); WRUGB(G,V); RETURN; END; Q:=EXPTU(L); IF PAR = 8 THEN SWRITE("Die Liste der Terme als ganzzahlige Tupel ist "); BLINES(1); OWRITE(Q); BLINES(1); END; P:=MAKERN(Q); PALT:=SIL; DIFALT:=SIL; OLDL:=LIST3(SIL,SIL,SIL); KALT:=SIL; STAKK:=PROJEC(PALT,P,DIFALT,OLDL,I,PAR); LFALL(STAKK,L,KALT,I, NEUFLF,NURLF); GB:=UG(NEUFLF,I,V,STAKK,L,NURLF,PAR); UL:=WRUGF(GB,V,PAR); BLINES(2); WRUGB(UL,V); (*4*) RETURN; END UGB; PROCEDURE PUGB(L,I,V,PAR,OPT: LIST); (*Universal Groebner base with precomputed linear forms. Die prozedur berechnet eine universelle groebner basis nach der option pugb. Vergleiche benutzerschnittstelle und 5.2.5. Die prozedur wird von exeugb aufgerufen. *) VAR DEG, GB, LF, LFLIST, LFQ, NURLF, R, UL: LIST; BEGIN (*1*) SWRITE("Option ... PUGB"); BLINES(1); SUNIT2(I); DEG:=LDEG(L); IF PAR = 8 THEN SWRITE("Grad der Polynome ... "); OWRITE(DEG); BLINES(1); END; SWRITE("Lese Linearfomen ... "); BLINES(1); IF I = 2 THEN IQR(DEG,2, DEG,R); IF R <> 0 THEN DEG:=DEG+1; END; END; LFQ:=OREAD(); LF:=LFGET(DEG,LFQ); LF:=DO1(LF); IF PAR = 8 THEN OWRITE(LENGTH(LF)); SWRITE(" eingelesene Linearformen"); BLINES(1); END; MKLIST(LF,L, LFLIST,NURLF); GB:=PUG(LFLIST,I,V,L,DEG,NURLF,PAR,LFQ); UL:=WRUGF(GB,V,PAR); BLINES(1); WRUGB(UL,V); (*4*) RETURN; END PUGB; PROCEDURE SUNIT1(I: LIST); (*UGB set input unit 1. Diese prozedur stellt bei der option plf die richtige datei zum einlesen von linearformen bereit. I ist die anzahl der variablen. Die vorberechneten lineraformen sind je nach der anzahl der variablen in verschiedenen dateien gespeichert. Diese prozedur wird von der prozedur plf aufgerufen. *) VAR r: GAMMAINT; BEGIN (*1*) (*ISLM:=2; ISIZE:=80;*) r:=0; (*2*) IF (I = 1) OR (I = 2) THEN SWRITE("Diese Option ist ab 3 Variablen sinnvoll."); BLINES(1); RETURN; ELSE IF I = 3 THEN r:=SIUNIT("ugblade/linform.lade1"); ELSE IF I = 4 THEN r:=SIUNIT("ugblade/linform.lade2"); ELSE IF I = 5 THEN r:=SIUNIT("ugblade/linform.lade3"); ELSE IF I >= 6 THEN SWRITE("Anzahl der Variablen zu hoch."); BLINES(1); RETURN; END; END; END; END; END; IF r <> 0 THEN ERROR(severe,"SUNIT1: Cannot open file."); END; (*5*) RETURN; END SUNIT1; PROCEDURE SUNIT2(I: LIST); (*UGB set input unit 2. Diese prozedur stellt bei der option pugb die richtige datei zum einlesen von linearformen bereit. I ist die anzahl der variablen. Die vorberechneten lineraformen sind je nach der anzahl der variablen in verschiedenen dateien gespeichert. Diese prozedur wird von der prozedur pugb aufgerufen. *) VAR r: GAMMAINT; BEGIN (*1*) (* ISLM:=2; ISIZE:=80; *) r:=0; (*2*) IF I = 1 THEN SWRITE("Diese Option ist ab 2 Variablen sinnvoll."); BLINES(1); RETURN; ELSE IF I = 2 THEN r:=SIUNIT("ugblade/linform.lade1"); ELSE IF I = 3 THEN r:=SIUNIT("ugblade/linform.lade2"); ELSE IF I = 4 THEN r:=SIUNIT("ugblade/linform.lade3"); ELSE IF I = 5 THEN r:=SIUNIT("ugblade/linform.lade4"); ELSE IF I >= 6 THEN SWRITE("Anzahl der Variablen zu hoch."); BLINES(1); RETURN; END; END; END; END; END; END; IF r <> 0 THEN ERROR(severe,"SUNIT2: Cannot open file."); END; (*5*) RETURN; END SUNIT2; PROCEDURE PREAD( VAR L,I,V: LIST); (*UGB polynomial read. Die polynome werden von der eingabedatei eingelesen. Diese funktion wird von der hauptprozedur ugbbin aufgerufen. *) BEGIN (*1*) V:=VLREAD(); L:=DIRLRD(V); I:=LENGTH(V); SWRITE("Die eingegebenen Polynome sind "); BLINES(1); DIRLWR(L,V,-1); BLINES(1); (*4*) RETURN; END PREAD; PROCEDURE OPREAD( VAR PAR,OPT: LIST); (*UGB options and parameter read. Diese prozedur liest von der eingabedatei den parameter par (zustaendig fuer zwischenausgaben) durch die prozedur rdpar und die option opt (steht fuer lf, plf, ugb, pugb) durch die prozedur execrd. Diese prozedur wird von der hauptprozedur ugbbin aufgerufen. *) BEGIN (*1*) PAR:=RDPAR(); IF PAR = 8 THEN SWRITE("Zwischenausgaben ... JA"); BLINES(1); ELSE IF PAR = 9 THEN SWRITE("Zwischenausgaben ... NEIN"); BLINES(1); END; END; OPT:=EXECRD(); (*4*) RETURN; END OPREAD; PROCEDURE EXPTU(L: LIST): LIST; (*UGB extract exponent vector list from polynomial list. Aus den polynomen wird die liste der terme berechnet. Da jeder term mit dem tupel seiner exponenten identifizert werden kann, wird die liste der exponententupel ausgegeben. Diese funktion wird von den prozeduren mklist, newdif, isneu, ug, pug, lf, plf, ugb und pugb. *) VAR A, B, E, J1Y, LP, Q: LIST; BEGIN (*1*) Q:=SIL; LP:=L; WHILE LP <> SIL DO ADV(LP, A,LP); IF A <> 0 THEN WHILE A <> SIL DO DIPMAD(A, B,E,A); J1Y:=LIST1(E); Q:=USUN(J1Y,Q); END; END; END; (*2*) Q:=INV(Q); (*5*) RETURN(Q); END EXPTU; PROCEDURE MAKERN(Q: LIST): LIST; (*UGB rational exponent vector list from integer ev list. Makern transformiert die ganzzahlige struktur der exponententupel in eine rationalzahlige struktur diese funktion wird von den funktionen mklist, neulf und newdif aufgerufen. *) VAR A, A1, B, C, L1, P, QP: LIST; BEGIN (*1*) QP:=Q; P:=SIL; L1:=SIL; (*2*) WHILE QP <> SIL DO ADV(QP, A,QP); A1:=SIL; WHILE A <> SIL DO ADV(A, B,A); C:=RNINT(B); A1:=COMP(C,A1); END; A1:=INV(A1); L1:=COMP(A1,L1); END; P:=INV(L1); (*5*) RETURN(P); END MAKERN; PROCEDURE SCMULT(I,U: LIST): LIST; (*UGB rational exponent vector rational number product. Hilfsfunktion zur berechnung vom skalarprodukt zwischen rationalzahligen vektoren. Diese funktion wird von der funktion mkset aufgerufen. *) VAR A, IP, SKTU, T, UP, V: LIST; BEGIN (*1*) UP:=U; IP:=I; V:=SIL; SKTU:=SIL; (*2*) WHILE UP <> SIL DO ADV(UP, A,UP); T:=RNPROD(A,IP); V:=COMP(T,V); END; (*3*) SKTU:=INV(V); (*6*) RETURN(SKTU); END SCMULT; PROCEDURE PDIF(R,S,DIFALT: LIST): LIST; (*UGB rational exponent vector list difference list, incremental. Berechnet (r-s) vereinigt mit (s-s).Diese prozedur ist im hinblick auf die berechnung von universellen groebner basen geschrieben. S entspricht der menge der neuen terme, die nach der reduktion entstehen. R enspricht der alten menge von termen. Da r-r in einem vorherigen schritt schon berechnet wurde, berechnet die prozedur nur r-r vereinigt mit s-s. Diese funktion wird von den funktionen projec, proj und newdif aufgerufen. *) VAR B, C, C1, D, RP, SP: LIST; BEGIN (*1*) RP:=R; SP:=S; B:=DIFF1(RP,SP); D:=DIFF(SP); C1:=USUN(B,D); C:=USUN(C1,DIFALT); (*4*) RETURN(C); END PDIF; PROCEDURE MKSET(R: LIST; VAR P2,P3,RR: LIST); (*UGB rational exponent vector list difference list. Berechnet die mengen p1, p2, p3 und die reduzierte menge von p - p wie sie im theoretischen teil der diplomarbeit beschrieben ist. Die eingabe ist r. P1 und p2 sind die projektionen. P3 ist die vereinigung von p1 und p2. Rr entspricht der reduzierten menge von p - p. Nur p2, p3 und rr werden zurueckgegeben. Diese funktion wird von den funktionen projec und proj aufgerufen. *) VAR A, B, C, EE, J1Y, P1, P1P, P2P, RP, XP: LIST; BEGIN (*1*) RP:=R; RR:=SIL; P1:=SIL; P2:=SIL; P3:=SIL; (*2*) WHILE RP <> SIL DO ADV(RP, A,RP); XP:=A; ADV(A, B,A); IF NULRNV(A) <> 1 THEN IF B = 0 THEN IF MEMBER(A,P1) <> 1 THEN RR:=COMP(XP,RR); P1:=COMP(A,P1); END; ELSE B:=RNINV(B); C:=SCMULT(B,A); IF MEMBER(C,P2) <> 1 THEN RR:=COMP(XP,RR); P2:=COMP(C,P2); END; END; END; END; P1P:=P1; P2P:=P2; WHILE P1P <> SIL DO ADV(P1P, A,P1P); J1Y:=-1; J1Y:=LIST2(J1Y,1); EE:=SCMULT(J1Y,A); IF (MEMBER(EE,P2P) <> 1) AND (MEMBER(A,P2P) <> 1) THEN P2P:=COMP(A,P2P); END; END; P3:=P2P; P3:=CINV(P3); (*5*) RETURN; END MKSET; PROCEDURE PROJEC(R,S,DIFALT,OLDL,I,PAR: LIST): LIST; (*UGB projection to dimension 1. Berechnet die projektionen der eingabemenge r bis zur dimension 1. Die ausgabe ist ein stapel der tupel der form (p2,p) verschiedener dimensionen enthaelt. P2 wird in jeder dimension zur berechnung der schnitte und p zum vergleich von ordnungen benutzt. Diese prozedur ruft die prozeduren pdif und mkset auf. Die prozedur degre bestimmt fuer jede projektion den maximalen totalgrad der terme. Diese funktion wird von den funktionen lf, plf, ugb und newdif aufgerufen. *) VAR B, C, D, DEG, E, IP, M, RP, RS, SERIE, STAKK: LIST; BEGIN (*1*) SWRITE("Projektionen ... "); BLINES(1); RS:=S; RP:=R; STAKK:=SIL; SERIE:=SIL; IP:=I; M:=IP; (*2*) WHILE M >= 2 DO M:=M-1; IF PAR = 8 THEN SWRITE("Dimension ... "); OWRITE(M); BLINES(1); END; EVLRNBSO(RS); D:=PDIF(RP,RS,DIFALT); MKSET(D, B,C,D); DEG:=DEGRE(C); DEG:=2*DEG; IF PAR = 8 THEN SWRITE("Gradschranke dieser Dimension ist "); OWRITE(DEG); BLINES(1); END; E:=LIST2(D,B); STAKK:=COMP(E,STAKK); RP:=SIL; RS:=C; END; (*5*) RETURN(STAKK); END PROJEC; PROCEDURE PROJ(R,S,DIFALT,OLDL,I: LIST; VAR D,B,DEG: LIST); (*UGB projection, one dimension. Berechnet die projektion der eingabemenge r auf eine niedrigere dimension. Die ausgabe besteht aus b (entspricht p2 in definition 2.2.1), d (entspricht der reduzierten differenz r - r), sowie deg. Diese prozedur ruft die prozeduren pdif und mkset auf. Die prozedur degre bestimmt den maximalen totalgrad deg der terme der projektion. Diese funktion wird von der funktion plf aufgerufen. *) VAR C, IP, M, RP, RS, SERIE, STAKK: LIST; BEGIN (*1*) RS:=S; RP:=R; STAKK:=SIL; SERIE:=SIL; IP:=I; M:=IP; (*2*) EVLRNBSO(RS); D:=PDIF(RP,RS,DIFALT); MKSET(D, B,C,D); DEG:=DEGRE(C); STAKK:=COMP2(D,B,STAKK); (*5*) RETURN; END PROJ; PROCEDURE DIFF(R: LIST): LIST; (*UGB difference set for rational exponent vector list. Diese prozedur berechnet fuer die eingabemenge von tupel r die reduzierte menge r - r. das ergebnis wird in r zurueckgegeben. diese funktion wird von den funktionen mklist und pdif aufgerufen. *) VAR A, AP, B, E, EE, ELT, ERG, RP, SP: LIST; BEGIN (*1*) RP:=R; ERG:=SIL; IF RP = SIL THEN RETURN(ERG); END; (*2*) SP:=RED(R); ELT:=SIL; WHILE RP <> SIL DO ADV(RP, A,RP); WHILE SP <> SIL DO AP:=A; ADV(SP, B,SP); E:=RNVDIF(AP,B); EE:=RNVDIF(B,AP); IF (MEMBER(E,ERG) <> 1) AND (MEMBER(EE,ERG) <> 1) THEN ERG:=COMP(E,ERG); END; END; SP:=RED(RP); END; (*5*) RETURN(ERG); END DIFF; PROCEDURE DIFF1(R,S: LIST): LIST; (*UGB difference set for two rational exponent vector list. Berechnet fuer die eingabemengen r und s von exponeneten tupel die reduzierte menge r - s. das ergebnis wird in erg zurueckgegeben. diese funktion wird von der funktion pdif aufgerufen. *) VAR A, AP, B, ELT, ERG, RP, SP: LIST; BEGIN (*1*) RP:=R; SP:=S; ELT:=SIL; ERG:=SIL; IF (RP = SIL) OR (SP = SIL) THEN RETURN(ERG); END; (*2*) WHILE RP <> SIL DO ADV(RP, A,RP); SP:=S; WHILE SP <> SIL DO AP:=A; ADV(SP, B,SP); ELT:=RNVDIF(AP,B); IF MEMBER(ELT,ERG) <> 1 THEN ERG:=COMP(ELT,ERG); END; END; END; (*4*) RETURN(ERG); END DIFF1; PROCEDURE RNVDIF(A,B: LIST): LIST; (*UGB rational exponent vector difference. Berechnet die komponentenweise differenz von zwei rationalzahligen vektoren. die differenz von zwei rationalzahlen wird durch die prozedur rndif berechnet. diese funktion wird von den funktionen diff und diff1 aufgerufen. *) VAR AA, AQ, BB, BQ, C, CC: LIST; BEGIN (*1*) C:=SIL; AQ:=A; BQ:=B; (*2*) WHILE AQ <> SIL DO ADV(AQ, AA,AQ); ADV(BQ, BB,BQ); CC:=RNDIF(AA,BB); C:=COMP(CC,C); END; (*3*) C:=INV(C); (*6*) RETURN(C); END RNVDIF; PROCEDURE SCPROD(A,B: LIST): LIST; (*UGB rational exponent vector scalar product. Berechnet das skalarprodukt von zwei rationalzahligen vektoren. die prozedur rnprod berechnet das produkt zweier rationalzahlen. die prozedur rnsum berechnet die summe von zwei rationalzahlen. das ergebnis wird in c zurueckgegeben. diese funktion wird von den funktionen cq2, cp2, pkegel und cspur aufgerufen. *) VAR AA, AP, BB, BP, C, CC: LIST; BEGIN (*1*) AP:=A; BP:=B; C:=0; (*2*) WHILE AP <> SIL DO ADV(AP, AA,AP); ADV(BP, BB,BP); CC:=RNPROD(AA,BB); C:=RNSUM(CC,C); END; (*5*) RETURN(C); END SCPROD; PROCEDURE SKPRO2(A,B: LIST): LIST; (*UGB rational exponent vector scalar product with integer ev. Diese funktion ist eine spezielle skalarprodukt-funktion. da die ausgerechneten linearformen rationahlzahlig sind und die exponententupel ganzzahlig sind, werden diese zunaechst als rationahlzahlen dargestellt und dann das skalarprodukt gebildet. diese funktion wird von evlfcp aufgerufen. *) VAR AA, AP, BB, BP, C, CC: LIST; BEGIN (*1*) AP:=A; BP:=B; C:=0; (*2*) WHILE AP <> SIL DO ADV(AP, AA,AP); ADV(BP, BB,BP); BB:=RNINT(BB); CC:=RNPROD(AA,BB); C:=RNSUM(CC,C); END; (*5*) RETURN(C); END SKPRO2; PROCEDURE LRNBMS(L: LIST): LIST; (*List of rational numbers bubble-merge sort. L is an arbitrary list of rational numbers, possibly with repetitions. M is the result of sorting L into non-decreasing order. A combination of bubble-sort and merge- sort is used. The list L is modified to produce M.*) VAR B, BP, C, IL, J1Y, JL, KL, L1, L2, LP, LPP, LPPP, M, ML, NL, QL, QLP, RL, TL: LIST; BEGIN (*1*) (*short list.*) TL:=10; NL:=LENGTH(L); IF NL < TL THEN LRNBS(L); M:=L; RETURN(M); END; (*2*) (*prepare for merge.*) KL:=0; ML:=1; QL:=NL; REPEAT KL:=KL+1; ML:=ML+ML; QL:=QL DIV 2; UNTIL QL < TL; J1Y:=ML*QL; RL:=NL-J1Y; B:=SIL; LP:=L; FOR IL:=1 TO ML DO IF IL <= RL THEN QLP:=QL; ELSE QLP:=QL-1; END; LPP:=LP; FOR JL:=1 TO QLP DO LPP:=RED(LPP); END; LPPP:=RED(LPP); SRED(LPP,SIL); LRNBS(LP); B:=COMP(LP,B); LP:=LPPP; END; (*3*) (*merge.*) FOR IL:=1 TO KL DO C:=SIL; BP:=B; REPEAT ADV2(BP,L1,L2,BP); L1:=LRNM(L1,L2); C:=COMP(L1,C); UNTIL BP = SIL; B:=C; END; M:=FIRST(B); RETURN(M); (*6*) END LRNBMS; PROCEDURE LRNBS(L: LIST); (*List of rational numbers bubble sort. L is an arbitrary list of rational numbers, with possible repetitions. L is sorted into non-decreasing order by the bubble-sort method. The list L, though not its location, is modified.*) VAR ALP, ALPP, LP, LPP, M, MP: LIST; BEGIN (*1*) (*trivial case.*) IF L = SIL THEN RETURN; END; (*2*) (*general case.*) M:=SIL; REPEAT LP:=L; LPP:=RED(LP); ALP:=FIRST(LP); MP:=SIL; WHILE LPP <> M DO ALPP:=FIRST(LPP); IF RNCOMP(ALP,ALPP) > 0 THEN SFIRST(LP,ALPP); SFIRST(LPP,ALP); MP:=LPP; ELSE ALP:=ALPP; END; LP:=LPP; LPP:=RED(LP); END; M:=MP; UNTIL M = SIL; RETURN; (*5*) END LRNBS; PROCEDURE LRNM(L1,L2: LIST): LIST; (*List of rational numbers merge. L1 and L2 are arbitrary lists of rational numbers in non-decreasing order. L is the merge of L1 and L2. L1 and L2 are modified to produce L.*) (*goto-free version of LRNM from ALDES implementation guide, by R. Loos. *) VAR AL1, AL2, L, LP, LS, LP1, LP2, LPP1, LPP2: LIST; BEGIN (*1*) (*initialize. *) LP1:=L1; LP2:=L2; L:=SIL; LS:=SIL; (*2*) (*merge l1 and l2. *) WHILE (LP1 <> SIL) AND (LP2 <> SIL) DO ADV(LP1,AL1,LPP1); ADV(LP2,AL2,LPP2); IF RNCOMP(AL1,AL2) < 0 THEN LP:=LP1; LP1:=LPP1; ELSE LP:=LP2; LP2:=LPP2; END; IF LS = SIL THEN LS:=LP; L:=LP; ELSE SRED(LS,LP); LS:=LP; END; END; (*3*) (*finish. *) IF LP2 <> SIL THEN LP1:=LP2; END; IF LS = SIL THEN L:=LP; ELSE SRED(LS,LP1); END; RETURN(L); (*4*) END LRNM; PROCEDURE COMPLF(C,D,KLIST,NP,JP,M: LIST; VAR LFORM,KLISTP,J: LIST); (*UGB compute linear form from difference set. Diese prozedur berechnet fuer die linearform c und die menge der schnitte d die neuen linearformen. klist enthaelt die spuren der schon berechneten linearformen np entspricht der reduzierten menge p - p und wird dazu verwendet um die neuen spuren zu berechnen. lform enthaelt als ausgabe alle bisher berechneten linearformen. klistp die dazugehoerigen spuren. alle spuren sind verschieden. die funktion wird von der funktion mklf1 aufgerufen. *) VAR A, DP, K, KALT, KLISTH, U: LIST; BEGIN (*1*) DP:=D; LFORM:=SIL; J:=JP; KLISTP:=KLIST; KALT:=SIL; KLISTH:=SIL; (*2*) WHILE DP <> SIL DO ADV(DP, A,DP); IF M <> 1 THEN A:=COMP(A,C); K:=PKEGEL(A,NP,KALT); U:=COMPA1(K,KLISTP); IF U <> 1 THEN KLISTH:=COMP(K,KLISTH); LFORM:=COMP(A,LFORM); END; ELSE A:=LIST1(A); LFORM:=COMP(A,LFORM); END; END; KLISTP:=CCONC(KLISTP,KLISTH); (*5*) RETURN; END COMPLF; PROCEDURE CQ2(C,Q2,M: LIST): LIST; (*UGB linear form product with rational exponent vector list. Diese prozedur berechnet fuer eine linearform c und eine liste q2, beide der gleichen dimension, das produkt c * q2. die elemente von c * q2 bestehen aus dem skalarprodukt von c mit den einzelnen elementen von q2. da diese menge dazu verwendet wird, um die schnitte zu bilden, werden nur die negativen elemente gespeichert. die funktion wird von der funktion mklf1 aufgerufen. *) VAR A, AA, CP, J1Y, Q2P, TR: LIST; BEGIN (*1*) CP:=C; Q2P:=Q2; TR:=SIL; (*2*) WHILE Q2P <> SIL DO ADV(Q2P, A,Q2P); IF M <> 1 THEN AA:=SCPROD(C,A); J1Y:=LASTEL(A); AA:=RNSUM(AA,J1Y); ELSE AA:=FIRST(A); END; IF (RNCOMP(AA,0) <= -1) AND (MEMBER(AA,TR) <> 1) THEN TR:=COMP(AA,TR); END; END; (*5*) RETURN(TR); END CQ2; PROCEDURE RNVABS(A: LIST): LIST; (*Rational number list absolute values. Diese prozedur berechnet fuer die liste a von rational- zahlen den absolutbetrag ihrer komponenten. die prozedur rnabs berechnet den absolutbetrag einer rationalzahl. das ergebnis wird in der liste b zurueckgegeben. die funktion wird von den funktionen mklf1, mklf2 und mklf3 aufgerufen. *) VAR AA, AP, B: LIST; BEGIN (*1*) AP:=A; B:=SIL; (*2*) WHILE AP <> SIL DO ADV(AP, AA,AP); AA:=RNABS(AA); B:=COMP(AA,B); END; B:=INV(B); (*5*) RETURN(B); END RNVABS; PROCEDURE CUT(TR: LIST): LIST; (*UGB set of cuts. Berechnet fuer die eingabemenge tr die menge der schnitte d. fuer die inneren punkte wird das algebraische mittel gebildet. fuer die aeusseren punkte wird 1 addiert beziehungsweise die zahl halbiert. die funktion wird von den funktionen mklf1, mklf2 und mklf3 aufgerufen. *) VAR A, B, D, ERST, G, H, J, J1Y, J2Y, MITTE, ND, TRACEP, Z: LIST; BEGIN (*1*) TRACEP:=TR; D:=SIL; G:=FIRST(TRACEP); J1Y:=RNINT(0); H:=RNSUM(G,J1Y); J:=LAST(TRACEP); J:=FIRST(J); (*2*) J1Y:=RNINT(2); ERST:=RNQ(H,J1Y); J1Y:=RNINT(1); ND:=RNSUM(J,J1Y); D:=COMP(ERST,D); Z:=LENGTH(TRACEP); (*3*) WHILE Z >= 2 DO A:=FIRST(TRACEP); B:=SECOND(TRACEP); TRACEP:=RED(TRACEP); Z:=LENGTH(TRACEP); J1Y:=RNSUM(A,B); J2Y:=RNINT(2); MITTE:=RNQ(J1Y,J2Y); D:=COMP(MITTE,D); END; D:=COMP(ND,D); (*6*) RETURN(D); END CUT; PROCEDURE ALLELN(STAKK,L,KALT,I,PAR: LIST; VAR LF,NURLF: LIST); (*UGB all linear forms from stack of projections. Diese funktion berechnet aus dem stapel der projektionen stakk alle linearformen nurlf. die prozedur mklf1 wird aufgerufen. diese funktion wird von der prozedur lf aufgerufen. *) VAR A, IP, J1Y, LFX, LY, M, N, NEWLF, Q2, STAKKP: LIST; BEGIN (*1*) SWRITE("Rekursive Berechnung der Linearformen ... "); BLINES(1); STAKKP:=STAKK; M:=1; IP:=I; (*2*) J1Y:=RNINT(1); LFX:=LIST1(J1Y); LY:=SIL; LF:=LIST1(LFX); IP:=IP-1; NEWLF:=SIL; WHILE M <= IP DO ADV(STAKKP, A,STAKKP); N:=FIRST(A); Q2:=SECOND(A); IF PAR = 8 THEN SWRITE("Dimension ..."); OWRITE(M+1); BLINES(1); SWRITE("Die Spur hat "); OWRITE(LENGTH(N)); SWRITE(" Elemente"); BLINES(1); END; NURLF:=MKLF1(LF,Q2,N,M); IF (PAR = 8) AND (M <> IP) THEN SWRITE("Die bisher rekursiv berechneten Linearformen sind "); OWRITE(LENGTH(NURLF)); SWRITE(" Linearformen "); BLINES(1); END; M:=M+1; LF:=NURLF; END; SWRITE("Die berechneten Linearformen sind "); OWRITE(LENGTH(LF)); SWRITE(" Linearformen "); BLINES(1); (*5*) RETURN; END ALLELN; PROCEDURE MKLF1(LFP,Q2,NP,M: LIST): LIST; (*UGB make new linear forms 1. Diese prozedur berechnet fuer eine liste von linearformen lfp die neuen linearformen newlf. die menge q2 wird dazu verwendet, die schnitte zu berechnen. die menge np dient dazu, die ueberfluessigen linearformen zu eliminieren. diese funktion wird von der prozedur plf und alleln aufgerufen. *) VAR A, B, D, J, J1Y, KLIST, LF, NEWLF, TR: LIST; BEGIN (*1*) LF:=LFP; NEWLF:=SIL; KLIST:=SIL; J:=0; (*2*) WHILE LF <> SIL DO D:=SIL; ADV(LF, B,LF); IF Q2 = SIL THEN J1Y:=LIST2(1,1); D:=LIST1(J1Y); ELSE TR:=CQ2(B,Q2,M); TR:=RNVABS(TR); TR:=LRNBMS(TR); D:=CUT(TR); END; COMPLF(B,D,KLIST,NP,J,M, A,KLIST,J); NEWLF:=USUN(A,NEWLF); END; (*5*) RETURN(NEWLF); END MKLF1; PROCEDURE NULRNV(A: LIST): LIST; (*Rational number vector null test. Diese prozedur ueberprueft ob ein vektor a der nullvektor ist. i ist 1 falls a der nullvektor ist ansonsten 0. diese funktion wird von der funktion mkset aufgerufen. *) VAR AP, B, I: LIST; BEGIN (*1*) AP:=A; I:=1; (*2*) WHILE AP <> SIL DO ADV(AP, B,AP); IF B <> 0 THEN I:=0; RETURN(I); END; END; (*5*) RETURN(I); END NULRNV; PROCEDURE PKEGEL(C,N,KALT: LIST): LIST; (*UGB trace for linear form. Diese funktion berechnet die spur k bezueglich der linear- form c und der menge n in kodierter form. die spur wird nach der methode der wortkodierung (abschnitt 5.1.4) gebildet. diese funktion wird von der funktion complf aufgerufen. *) VAR A, AA, B, B2, D, I, J1Y, K, NP: LIST; BEGIN (*1*) A:=KALT; NP:=N; K:=SIL; I:=0; B:=0; B2:=BETA DIV 2; (*2*) WHILE NP <> SIL DO ADV(NP, AA,NP); D:=SCPROD(C,AA); J1Y:=LASTEL(AA); D:=RNSUM(D,J1Y); D:=RNSIGN(D); IF D = -1 THEN D:=0; END; J1Y:=2*B; B:=J1Y+D; IF B >= B2 THEN K:=COMP(B,K); B:=0; END; END; (*3*) IF B < B2 THEN K:=COMP(B,K); END; (*6*) RETURN(K); END PKEGEL; PROCEDURE COMPA1(K,KLIST: LIST): LIST; (*UGB trace member in trace list. Diese funktion stellt fest ob eine spur k in einer liste von spuren vorhanden ist. j ist gleich 1 falls k in klist liegt, ansonsten 0. diese funktion wird von den funktionen complf, clf2, clf3 aufgerufen. *) VAR A, J, KLISTP: LIST; BEGIN (*1*) KLISTP:=KLIST; J:=0; (*2*) IF KLISTP = SIL THEN J:=0; ELSE WHILE KLISTP <> SIL DO ADV(KLISTP, A,KLISTP); J:=COMPA2(K,A); IF J = 1 THEN RETURN(J); END; END; END; (*5*) RETURN(J); END COMPA1; PROCEDURE COMPA2(K,A: LIST): LIST; (*UGB trace compare. Diese funktion ueberprueft zwei spuren k und a auf gleichheit. u ist gleich 1 falls a und k gleich sind, ansonsten 0. diese funktion wird von den funktionen compa1, dfp, dipmc2, zulfo und isneu aufgerufen. *) VAR AP, B, C, KP, U: LIST; BEGIN (*1*) KP:=K; U:=1; AP:=A; U:=1; (*2*) WHILE (KP <> SIL) AND (AP <> SIL) DO ADV(KP, B,KP); ADV(AP, C,AP); IF B <> C THEN U:=0; RETURN(U); END; END; IF (KP <> SIL) OR (AP <> SIL) THEN U:=0; END; (*5*) RETURN(U); END COMPA2; PROCEDURE LASTEL(Y: LIST): LIST; (*Last element. X ist das letzte element der liste y. *) VAR X, YP: LIST; BEGIN (*1*) YP:=LAST(Y); X:=FIRST(YP); (*4*) RETURN(X); END LASTEL; PROCEDURE EVLRNBSO(A: LIST); (*Rational exponent vector list bubble sort. a is a list of rational exponent vectors, a is sorted with respect to the termordering defined in EVORD by the bubble-sort method, two exponent vectors with equal exponents will lead to an error. the list a but not its location, is modified.*) VAR AP, APP, B, BP, ELP, ELPP, TL, DUMMY, evo: LIST; BEGIN (*1*) (*Trivial case.*) IF A = 0 THEN RETURN; END; evo:=EVORD; EVORD:=GRLEX; (*???????, others not implem.*) (*2*) (*General case.*) B:=SIL; REPEAT AP:=A; ADV(AP, ELP,APP); BP:=SIL; WHILE APP <> B DO ADV(APP, ELPP,DUMMY); (*DIPMAD???*) TL:=EVRNC(ELP,ELPP); IF TL = 0 THEN (*GO TO 3;*) (*3*) (*To equal exponent vectors.*) ERROR(severe,"RNLBSO: To equal exponent vectors"); EVORD:=evo; RETURN; END; IF TL > 0 THEN SFIRST(AP,ELPP); SFIRST(APP,ELP); BP:=APP; ELSE ELP:=ELPP; END; AP:=APP; APP:=RED(AP); END; B:=BP; UNTIL B = SIL; EVORD:=evo; RETURN; (*6*) END EVLRNBSO; PROCEDURE EVRNGL(U,V: LIST): LIST; (*Rational exponent vector inverse graded lexicographical compare. u=(ul1, ..., ulrl), v=(vl1, ..., vlrl) are rational exponent vectors. tl=0 if u eq v. tl=1 if u gt v. tl=-1 if u lt v. eq, gt, lt with respect to the inverse graded lexicographical ordering of the exponent vectors. rl is the length of u and v.*) VAR SL, TL, UL, ULP, US, VL, VLP, VS: LIST; BEGIN (*1*) (*lexicographical compare.*) TL:=0; US:=U; VS:=V; LOOP IF US = SIL THEN EXIT END; ADV(US, UL,US); ADV(VS, VL,VS); SL:=RNCOMP(UL,VL); IF SL > 0 THEN TL:=1; EXIT; ELSE IF SL < 0 THEN TL:=-1; EXIT; END; END; END; IF TL = 0 THEN RETURN(TL) END; (*2*) (*graduaded compare.*) WHILE US <> SIL DO ADV(US, ULP,US); ADV(VS, VLP,VS); UL:=RNSUM(UL,ULP); VL:=RNSUM(VL,VLP); END; SL:=RNCOMP(UL,VL); IF SL <> 0 THEN TL:=SL; END; RETURN(TL); (*5*) END EVRNGL; PROCEDURE EVRNC(U,V: LIST): LIST; (*Rational exponent vector compare. u=(ul1, ...,ulrl), v=(vl1, ...,vlrl) are exponent vectors. rl is the length of u and v. tl=0 if u eq v. tl=1 if u gt v. tl=-1 if u lt v. eq, gt, lt with respect to the ordering of the exponent vectors specified in the global variable EVORD. lexicographical, inverse lexicographical, graded lexicograhpical, inverse graded lexicographical orderings are possible. *) VAR TL: LIST; BEGIN (*1*) (*Compare.*) CASE EVORD OF GRLEX : TL:=EVRNGL(U,V); TL:=-TL; | IGRLEX : TL:=EVRNGL(U,V); END; (*4*) RETURN(TL); END EVRNC; PROCEDURE DEGRE(Q: LIST): LIST; (*UGB total degree of a list of rational exponent vectors. Q ist eine liste von rationalzahligen tupeln. der maximale totalgrad der in q vorkommt wird berechnet. diese prozedur wird von den funktionen projec und proj aufgerufen. *) VAR A, B, D, D1, H, J1Y, Q1, Q1P, QP, T: LIST; BEGIN (*1*) D:=0; QP:=Q; (*2*) WHILE QP <> SIL DO H:=1; ADV(QP, Q1,QP); Q1P:=Q1; WHILE Q1 <> SIL DO ADV(Q1, A,Q1); IF A <> 0 THEN J1Y:=SECOND(A); H:=ILCM(H,J1Y); END; END; H:=RNINT(H); D1:=0; WHILE Q1P <> SIL DO ADV(Q1P, B,Q1P); T:=RNPROD(B,H); T:=RNABS(T); D1:=RNSUM(T,D1); END; D:=RNMAX(D1,D); END; IF D <> 0 THEN D:=FIRST(D) END; (*5*) RETURN(D); END DEGRE; PROCEDURE RDPAR(): LIST; (*UGB read parameter. Diese funktion liest aus der eingabedatei den parameter par. zulaessige werte sind y oder n. bei y werden zwischen berechnungen ausgegeben, bei n nicht. diese funktion wird von der prozedur opread aufgerufen. *) VAR PAR: LIST; BEGIN (*1*) PAR:=CREADB(); (*2*) IF PAR = MASORD("Y") THEN PAR:=8; ELSE IF PAR = MASORD("N") THEN PAR:=9; ELSE SWRITE("*** Fehler bei Parameterangabe"); BLINES(1); SWRITE("*** Bitte nur Y oder N angeben"); BLINES(1); PAR:=9; END; END; (*5*) RETURN(PAR); END RDPAR; PROCEDURE EXECRD(): LIST; (*UGB execution options read. Diese funktion liest aus der eingabedatei die auszufuehrende option. moegliche optionen sind lf plf ugb und pugb. vor der option muss das wort exec stehen. die option ist mit einem punkt abzuschliessen. beispiel exec ugb. diese funktion wurde mit geringfuegigen aenderungen aus der aldes-bibliothek entnommen. diese funktion wird von der hauptprozedur ugbbin aufgerufen. *) VAR A, C, NP, NR, NRLIST, S: LIST; BEGIN (*1*) C:=CREADB(); IF C <> MASORD(".") THEN ERROR(severe,"EXECRD: . expected."); RETURN(NRLIST); END; NRLIST:=SIL; (*2*) (* Read exec .*) C:=CREADB(); NP:=SIL; (*3*) (* Check options .*) IF LETTER(C) THEN BKSP; S:=SREAD1(); IF EQUAL(S,LISTS("EXEC")) = 1 THEN REPEAT C:=CREADB(); IF C <> MASORD(".") THEN BKSP; A:=SREAD1(); SEENR(A, NR); IF NR <> SIL THEN NRLIST:=COMP(NR,NRLIST); END; END; UNTIL C = MASORD("."); ELSE ERROR(severe,"EXECRD: EXEC expected."); RETURN(NRLIST); END; END; (*4*) IF NRLIST = SIL THEN ERROR(severe,"EXECRD: no options found."); END; (*7*) RETURN(NRLIST); END EXECRD; PROCEDURE SEENR(AC: LIST; VAR NR: LIST); (*UGB number of option. Diese funktion ermittelt fuer eine option ac eine schluesselzahl nr. die funktion stammt bis auf einige aenderungen aus der aldes-bibliothek. diese funktion wird von der funktion execrd aufgerufen. *) VAR NM: LIST; BEGIN (*1*) (*Berechnung der linearformen.*) NM:=LISTS("LF"); IF EQUAL(AC,NM) = 1 THEN NR:=1; RETURN; END; (*2*) (*Berechnung der linearformen mittels preprocessing*) NM:=LISTS("PLF"); IF EQUAL(AC,NM) = 1 THEN NR:=2; RETURN; END; (*3*) (*Universelle groebner basis.*) NM:=LISTS("UGB"); IF EQUAL(AC,NM) = 1 THEN NR:=3; RETURN; END; (*4*) (*Universelle groebner basis mittels preprocessing.*) NM:=LISTS("PUGB"); IF EQUAL(AC,NM) = 1 THEN NR:=4; RETURN; END; (*8*) (*Error .*) ERROR(severe,"SEENR: unknown option."); (*11*) RETURN; END SEENR; PROCEDURE LFGET(DEG,LF: LIST): LIST; (*UGB get linear form from list of linear forms. Diese funktion holt aus der liste lf der gespeicherten linearformen, abhaengig vom grad deg, die benoetigten linearformen. diese funktion wird von den funktionen plf, pugb und pug aufgerufen. *) VAR D, LFP, LFQ: LIST; BEGIN (*1*) LFP:=LF; D:=0; IF DEG > LENGTH(LF) THEN SWRITE("******************************"); BLINES(1); SWRITE(" Berechnung nicht Fortsetzbar "); BLINES(1); SWRITE(" Grad zu hoch "); BLINES(1); SWRITE("******************************"); BLINES(1); RETURN(SIL); END; (*2*) WHILE D < DEG DO ADV(LFP, LFQ,LFP); D:=D+1; END; (*5*) RETURN(LFQ); END LFGET; PROCEDURE MKLF2(LFP,Q2,NP,M,L: LIST; VAR NEWLF,LISTLF: LIST); (*UGB make new linear forms 2. Diese funktion ist genau analog zu mklf1. die linear- formen werden im gegensatz zu onenlf auch mit der zahl 1 als letzte komponente der linearformen berechnet. diese funktion wird von der funktion lfall aufgerufen. *) VAR A, AA, B, D, J, J1Y, KLIST, LF, TR: LIST; BEGIN (*1*) LF:=LFP; NEWLF:=SIL; KLIST:=SIL; J:=0; LISTLF:=SIL; (*2*) WHILE LF <> SIL DO D:=SIL; ADV(LF, B,LF); IF Q2 = SIL THEN J1Y:=LIST2(1,1); D:=LIST1(J1Y); ELSE TR:=CP2(B,Q2); TR:=RNVABS(TR); TR:=LRNBMS(TR); D:=CUT(TR); END; CLF2(B,D,KLIST,NP,J,M,L, A,KLIST,J,AA); NEWLF:=USUN(A,NEWLF); LISTLF:=USUN(AA,LISTLF); END; (*5*) RETURN; END MKLF2; PROCEDURE CLF2(C,D,KLIST,NP,JP,M,L: LIST; VAR LFORM,KLISTP,J,RECLF: LIST); (*UGB compute linear form from difference set 2. Diese funktion funktionniert genauso wie complf, mit dem unterschied, dass das element 1 als letzte komponente der linearform gespeichert wird. diese funktion wird von der funktion mklf2 aufgerufen. *) VAR A, DP, J1Y, K, KALT, KLISTH, U: LIST; BEGIN (*1*) DP:=D; LFORM:=SIL; J:=JP; KLISTP:=KLIST; KALT:=SIL; KLISTH:=SIL; RECLF:=SIL; (*2*) WHILE DP <> SIL DO ADV(DP, A,DP); A:=COMP(A,C); K:=CSPUR(A,NP,KALT); IF M <> 1 THEN U:=COMPA1(K,KLISTP); IF U <> 1 THEN KLISTH:=COMP(K,KLISTH); J1Y:=LIST4(A,L,K,NP); RECLF:=COMP(J1Y,RECLF); LFORM:=COMP(A,LFORM); END; ELSE LFORM:=COMP(A,LFORM); J1Y:=LIST4(A,L,K,NP); RECLF:=COMP(J1Y,RECLF); END; END; KLISTP:=CCONC(KLISTP,KLISTH); (*5*) RETURN; END CLF2; PROCEDURE CP2(C,Q2: LIST): LIST; (*UGB linear form product with rational exponent vector list 2. Diese funktion funktionniert genauso wie cq2, mit dem unterschied, dass das element 1 als letzte komponente der linearform gespeichert wird. diese funktion wird von den funktionen mklf2 und mklf3 aufgerufen. *) VAR A, AA, CP, Q2P, TR: LIST; BEGIN (*1*) CP:=C; Q2P:=Q2; TR:=SIL; (*2*) WHILE Q2P <> SIL DO ADV(Q2P, A,Q2P); AA:=SCPROD(C,A); IF (RNCOMP(AA,0) <= -1) AND (MEMBER(AA,TR) <> 1) THEN TR:=COMP(AA,TR); END; END; (*5*) RETURN(TR); END CP2; PROCEDURE CSPUR(C,N,KALT: LIST): LIST; (*UGB trace for linear form 2. Diese funktion funktionniert genauso wie pkegel, mit dem unterschied, dass das element 1 als letzte komponente der linearform gespeichert wird. diese funktion wird von den funktionen clf2, clf3 und zulfo aufgerufen. *) VAR A, AA, B, B2, D, I, J1Y, K, NP: LIST; BEGIN (*1*) A:=KALT; NP:=N; K:=SIL; I:=0; B:=0; B2:=SIL DIV 2; (*3*) WHILE NP <> SIL DO ADV(NP, AA,NP); D:=SCPROD(C,AA); D:=RNSIGN(D); IF D = -1 THEN D:=0; END; J1Y:=2*B; B:=J1Y+D; IF B >= B2 THEN K:=COMP(B,K); B:=0; END; END; (*4*) IF B < B2 THEN K:=COMP(B,K); END; (*7*) RETURN(K); END CSPUR; PROCEDURE MKNEWP(P,POL,PRS: LIST): LIST; (*UGB make new critical pairs. Diese funktion aktualisiert die menge der paare prs der polynomliste p um die paare der form (pol,f) wobei f aus p und pol ein polynom ist. das ergebnis ist ppairs. das buchberger-kriterium ist implementiert. diese funktion wird von der funktion gs2 aufgerufen. *) VAR C, COL1, COL2, DL, EL, ELI, ELJ, PAIRS, PLI, PP, PPAIRS, SL: LIST; BEGIN (*1*) PP:=P; PPAIRS:=SIL; PAIRS:=PRS; (*2*) (*Update pairs .*) COL1:=POL; ELI:=DIPEVL(COL1); WHILE PP <> SIL DO ADV(PP, PLI,PP); COL2:=PLI; ELJ:=DIPEVL(COL2); EL:=EVLCM(ELI,ELJ); SL:=EVSUM(ELI,ELJ); C:=EQUAL(EL,SL); IF C <> 1 THEN DL:=LIST3(EL,POL,PLI); PPAIRS:=COMP(DL,PPAIRS); END; END; (*3*) PPAIRS:=EVPLSO(PPAIRS); IF PAIRS <> SIL THEN PAIRS:=INV(CINV(PAIRS)); (*copy*) PPAIRS:=EVPLM(PAIRS,PPAIRS); END; (*6*) RETURN(PPAIRS); END MKNEWP; PROCEDURE MKPAIR(PP: LIST; VAR PAIRS: LIST); (*UGB make critical pairs for polynomial list. Diese funktion berechnet aus der liste pp von polynomen die menge der paare pairs. das buchberger-kriterium ist implementiert. diese funktion wird von der funktion gs1 aufgerufen. *) VAR C, COL1, COL2, DL, EL, ELI, ELJ, PI, PJ, PSS, Q, QP, SL: LIST; BEGIN (*1*) PAIRS:=SIL; IF (PP = SIL) OR (RED(PP) = SIL) THEN RETURN; END; (*2*) (*Construct pairs. *) PSS:=PP; REPEAT ADV(PSS, PI,QP); COL1:=PI; ELI:=DIPEVL(COL1); WHILE QP <> SIL DO ADV(QP, PJ,QP); COL2:=PJ; ELJ:=DIPEVL(COL2); EL:=EVLCM(ELI,ELJ); SL:=EVSUM(ELI,ELJ); C:=EQUAL(EL,SL); IF C <> 1 THEN DL:=LIST3(EL,PI,PJ); PAIRS:=COMP(DL,PAIRS); Q:=COMP(PJ,Q); END; END; PSS:=RED(PSS); UNTIL PSS = SIL; (*3*) IF PAIRS <> SIL THEN PAIRS:=EVPLSO(PAIRS); END; (*6*) RETURN; END MKPAIR; PROCEDURE MKSP1(X,L,PAIRS,I,V: LIST; VAR D,PAIRSP: LIST); (*UGB compute next non-zero reduced S-polynomial. Diese funktion bildet bezueglich der linearform x und der polynommenge l aus der liste von paaren pairs solange ein s-polynom (dirpsp) und fuehrt es zu normalform (dirrnf) bis das s-polynom d nicht null ist oder die liste der paare pairsp leer ist. diese funktion wird von den funktionen ug und pug aufgerufen. *) VAR B, B1, B2, B3, C: LIST; BEGIN (*1*) PAIRSP:=PAIRS; D:=0; (*2*) WHILE (PAIRSP <> SIL) AND (D = 0) DO ADV(PAIRSP,B,PAIRSP); FIRST2(RED(B),B2,B3); C:=DIRPSP(B2,B3,X); D:=DIRRNF(L,C,X,V); END; (*5*) RETURN; END MKSP1; PROCEDURE GS1(LF,V,PAR: LIST): LIST; (*UGB generate stack of sorted polynomials and critical pairs 1. Lf ist ein tupel der form (a,l,k,n). dabei ist a eine linear- form, l eine liste von polynomen, k die dazugehoerige spur und n die reduzierte differenz p - p der entsprechenden menge von exponententupel. diese prozedur ordnet die polynome nach den linearformen und berechnet die menge der dazugehoerigen paare b. die ausgabe stak besteht aus tupeln der form (a,l,k,n,b). diese funktion wird von den funktionen ug und pug aufgerufen. *) VAR A, B, J1Y, J2Y, LFP, LP, PAIRS, STAK, X, evo: LIST; BEGIN (*1*) LFP:=LF; STAK:=SIL; evo:=EVORD; IF PAR = 8 THEN SWRITE("Ordne die Polynome nach den Linearformen"); BLINES(1); END; (*2*) WHILE LFP <> SIL DO ADV(LFP, A,LFP); FIRST2(A,B,LP); EVORD:=B; LP:=POLCOP(LP); DILBSO(LP); MKPAIR(LP, PAIRS); J1Y:=THIRD(A); J2Y:=FOURTH(A); X:=LIST5(B,LP,J1Y,J2Y,PAIRS); J1Y:=LIST1(X); STAK:=USUN(J1Y,STAK); END; EVORD:=evo; (*5*) RETURN(STAK); END GS1; PROCEDURE MERGE(STALT,STNEU: LIST): LIST; (*UGB merge stacks. Diese funktion mischt die zwei stapel stalt und stneu zu einem stapel stak wie in 5.2.3 beschrieben ist. diese funktion wird von der funktion neulf aufgerufen. *) VAR A, B, C, D, J1Y, J2Y, STAK, STALTP, STNEUP: LIST; BEGIN (*1*) STALTP:=STALT; STNEUP:=STNEU; STAK:=SIL; (*2*) WHILE STALTP <> SIL DO ADV(STALTP, A,STALTP); ADV(STNEUP, B,STNEUP); J1Y:=FIRST(A); J2Y:=FIRST(B); D:=USUN(J1Y,J2Y); J1Y:=SECOND(A); J2Y:=SECOND(B); C:=USUN(J1Y,J2Y); J1Y:=LIST2(D,C); STAK:=COMP(J1Y,STAK); STAK:=INV(STAK); END; (*5*) RETURN(STAK); END MERGE; PROCEDURE WRUGF(X,V,PAR: LIST): LIST; (*Write universal Groebner family. Diese funktion gibt eine berechnete universelle groebnerfamilie auf dem ausgabegeraet aus. es wird jeweils eine linearform und die dazugehoerige polynommenge ausgegeben. diese funktion wird von den prozeduren ugb und pugb aufgerufen. *) VAR evo, A, L, LP, p, UL, XP: LIST; BEGIN (*1*) XP:=X; UL:=SIL; IF PAR = 8 THEN SWRITE(" ************************************"); BLINES(1); SWRITE(" Universelle Groebnerfamilie"); BLINES(1); SWRITE(" ************************************"); BLINES(2); END; evo:=EVORD; EVORD:=INVLEX; (*2*) WHILE XP <> SIL DO ADV(XP, A,XP); IF PAR = 8 THEN SWRITE("-----------------------------"); BLINES(1); OWRITE(FIRST(A)); BLINES(1); SWRITE("-----------------------------"); BLINES(1); DIRLWR(SECOND(A),V,-1); BLINES(1); END; L:=SECOND(A); L:=POLCOP(L); DILBSO(L); LP:=L; WHILE LP <> SIL DO p:=DIRPMC(FIRST(LP)); SFIRST(LP,p); LP:=RED(LP); END; UL:=USUN(L,UL); END; UL:=DIPLPM(UL); EVORD:=evo; (*5*) RETURN(UL); END WRUGF; PROCEDURE WRUGB(UL,V: LIST); (*Write universal Groebner base. Diese funktion gibt eine berechnete universelle groebnerbasis ul auf dem ausgabegeraet aus. diese prozedur wird von den prozeduren ugb und pugb aufgerufen. *) BEGIN (*1*) SWRITE(" ************************************"); BLINES(1); SWRITE(" Universelle Groebnerbasis"); BLINES(1); SWRITE(" ************************************"); BLINES(1); DIRLWR(UL,V,-1); (*4*) RETURN; END WRUGB; PROCEDURE POLCOP(L: LIST): LIST; (*Two level list copy. Diese funktion macht eine kopie p der polynomliste l. diese funktion wird von den funktionen gs1, gs2 und wrugf aufgerufen. *) VAR A, B, J1Y, LP, P: LIST; BEGIN (*1*) LP:=L; P:=SIL; (*2*) WHILE LP <> SIL DO ADV(LP, A,LP); B:=INV(CINV(A)); P:=COMP(B,P); END; P:=INV(P); (*5*) RETURN(P); END POLCOP; PROCEDURE DFP(A,B: LIST): LIST; (*UGB distributive rational polynomial difference. Diese funktion bildet aus den beiden polynomen a und b die distributive differenz a - b. das ergebnis ist cp. diese funktion unterscheidet sich von der in der aldes bibliothek vorhandenen funktion. sie berechnet die differenz bezueglich der in der globalen variablen EVORD gesetzten ordnung. diese funktion wird von den funktionen dirrnf und dirpsp aufgerufen. *) VAR AL, AP, APP, BL, BP, C, CL, CP, CPP, EL, FL, SL: LIST; BEGIN (*1*) (* a or b zero.*) IF A = 0 THEN C:=DIRPNG(B); RETURN(C); END; IF B = 0 THEN C:=A; RETURN(C); END; (*2*) (*match coefficients.*) AP:=A; BP:=B; CP:=SIL; REPEAT EL:=DIPEVL(AP); FL:=DIPEVL(BP); SL:=EVCOMP(EL,FL); IF SL = 0 THEN SL:=EVILCP(EL,FL); END; IF SL = 1 THEN DIPMAD(AP, AL,EL,AP); CP:=DIPMCP(EL,AL,CP); ELSE IF SL = -1 THEN DIPMAD(BP, BL,FL,BP); CL:=RNNEG(BL); CP:=DIPMCP(FL,CL,CP); ELSE DIPMAD(AP,AL,EL,AP); DIPMAD(BP, BL,FL,BP); CL:=RNDIF(AL,BL); IF CL <> 0 THEN CP:=DIPMCP(EL,CL,CP); END; END; END; UNTIL (AP = SIL) OR (BP = SIL); (*3*) (*finish.*) APP:=AP; IF AP = SIL THEN IF BP <> SIL THEN APP:=DIRPNG(BP); END; END; IF CP = SIL THEN C:=APP; ELSE CPP:=CP; C:=INV(CP); SRED(CPP,APP); END; IF C = SIL THEN C:=0; END; RETURN(C); (*5*) END DFP; PROCEDURE SFP(A,B: LIST): LIST; (*UGB distributive rational polynomial sum. Diese funktion bildet aus den beiden polynomen a und b die distributive summe a + b. das ergebnis ist cp. diese funktion unterscheidet sich von der in der aldes bibliothek vorhandenen funktion. sie berechnet die differenz bezueglich der in der globalen variablen EVORD gesetzten ordnung. diese funktion wird von den funktionen dirrnf aufgerufen. *) VAR AL, AP, APP, BL, BP, C, CL, CP, CPP, EL, FL, SL: LIST; BEGIN (*1*) (* a or b zero.*) IF A = 0 THEN C:=B; RETURN(C); END; IF B = 0 THEN C:=A; RETURN(C); END; (*2*) (*match coefficients.*) AP:=A; BP:=B; CP:=SIL; REPEAT EL:=DIPEVL(AP); FL:=DIPEVL(BP); SL:=EVCOMP(EL,FL); IF SL = 0 THEN SL:=EVILCP(EL,FL); END; IF SL = 1 THEN DIPMAD(AP, AL,EL,AP); CP:=DIPMCP(EL,AL,CP); ELSE IF SL = -1 THEN DIPMAD(BP, BL,FL,BP); CP:=DIPMCP(FL,BL,CP); ELSE DIPMAD(AP,AL,EL,AP); DIPMAD(BP, BL,FL,BP); CL:=RNSUM(AL,BL); IF CL <> 0 THEN CP:=DIPMCP(EL,CL,CP); END; END; END; UNTIL (AP = SIL) OR (BP = SIL); (*3*) (*finish.*) APP:=AP; IF AP = SIL THEN IF BP <> SIL THEN APP:=BP; END; END; IF CP = SIL THEN C:=APP; ELSE CPP:=CP; C:=INV(CP); SRED(CPP,APP); END; IF C = SIL THEN C:=0; END; RETURN(C); (*5*) END SFP; PROCEDURE EVLFCP(L,U,V: LIST): LIST; (*UGB exponent vector linear form compare. Diese funktion vergleicht die exponententupel u und v zweier terme bezueglich der linearform l. das ergebnis t ist gleich 1 falls u groesser als v ist, 0 falls sie gleich sind und -1 ansonsten. diese funktion wird von der funktion evcomp aufgerufen. *) VAR A, B, T: LIST; BEGIN (*1*) A:=SKPRO2(L,U); B:=SKPRO2(L,V); T:=RNCOMP(A,B); (*4*) RETURN(T); END EVLFCP; PROCEDURE PCOMP(X,Y: LIST): LIST; (*UGB distributive polynomial composition. Diese funktion bildet aus den beiden polynomen x und y ein polynom z, sodass das polynom x der ersten teil, und y der zweite teil ist. diese funktion wird von den funktionen dfp und dipmc2 aufgerufen. *) VAR A, C, XP, Z: LIST; BEGIN (*1*) XP:=X; Z:=Y; (*2*) IF X = SIL THEN Z:=Y; RETURN(Z); END; (*3*) IF Y = SIL THEN Z:=X; RETURN(Z); END; WHILE XP <> SIL DO DIPMAD(XP, A,C,XP); Z:=DIPMCP(A,C,Z); END; (*6*) RETURN(Z); END PCOMP; PROCEDURE EVCOMP(U,V: LIST): LIST; (*UGB exponent vector compare. Diese funktion vergleicht die exponententupel u und v zweier terme bezueglich der termordnung, die in der globalen variable EVORD gespeichert ist. das ergebnis tl ist gleich 1 falls u groesser als v ist, 0 falls sie gleich sind und -1 ansonsten. *) VAR TL: LIST; BEGIN (*1*) (*Compare with linear form.*) IF EVORD > SIL THEN TL:=EVLFCP(EVORD,U,V); RETURN(TL); END; (*2*) (*Compare with evord.*) CASE EVORD OF LEX : TL:=EVILCP(U,V); TL:=-TL | INVLEX : TL:=EVILCP(U,V); | GRLEX : TL:=EVIGLC(U,V); TL:=-TL | IGRLEX : TL:=EVIGLC(U,V); END; (*5*) RETURN(TL); END EVCOMP; PROCEDURE DIPMC2(A,C,P: LIST): LIST; (*UGB distributive polynomial composition 2. Diese funktion bildet aus dem koeffizient a, dem term c und dem polynom p ein neues polynom dp. diese funktion wird von der funktione dirrnf aufgerufen. *) VAR AA, AP, CC, DP, PP, U: LIST; BEGIN (*1*) PP:=P; DP:=SIL; U:=0; AP:=A; (*2*) WHILE (PP <> SIL) AND (U <> 1) DO DIPMAD(PP, AA,CC,PP); U:=COMPA2(CC,C); IF U = 1 THEN AP:=RNSUM(AP,AA); ELSE DP:=DIPMCP(AA,CC,DP); END; END; DP:=PCOMP(PP,DP); IF AP <> 0 THEN DP:=DIPMCP(AP,C,DP); END; (*5*) RETURN(DP); END DIPMC2; PROCEDURE DIRRNF(P,S,X,V: LIST): LIST; (*UGB distributive polynomial normalform. Diese funktion berechnet die normalform r eines polynoms s mit rationalen koeffizienten bezueglich der liste von polynomen p und der ordnung, die von der linearform x induziert wird. diese funktion wird von der funktione mksp1 aufgerufen. *) VAR AP, APP, BL, FL, PP, Q, QA, QE, QP, R, RP, SL, SP, TA, TE: LIST; BEGIN (*1*) (*S=0. *) IF (S = 0) OR (P = SIL) THEN R:=S; RETURN(R); END; (*2*) (*Reduction step.*) R:=0; SP:=S; REPEAT DIPMAD(SP, TA,TE,SP); IF SP = SIL THEN SP:=0; END; PP:=P; REPEAT ADV(PP, Q,PP); DIPMAD(Q, QA,QE,QP); SL:=EVMT(TE,QE); UNTIL (PP = SIL) OR (SL = 1); IF SL = 0 THEN RP:=DIPFMO(TA,TE); R:=SFP(R,RP); ELSE IF QP <> SIL THEN FL:=EVDIF(TE,QE); BL:=RNQ(TA,QA); AP:=DIPFMO(BL,FL); APP:=DIRPPR(QP,AP); SP:=DFP(SP,APP); END; END; UNTIL SP = 0; (*3*) (*Finish.*) (*6*) RETURN(R); END DIRRNF; PROCEDURE DIRPSP(A,B,X: LIST): LIST; (*UGB distributive polynomial S-polynomial. Diese funktion berechnet das s-polynom c der polynome a und b bezueglich der ordnung, die von der linearform x induziert wird. diese funktion wird von der funktion mksp1 aufgerufen. *) VAR evo, AL, AP, APP, BL, BP, BPP, C, CL, EL, EL1, FL, FL1, GL: LIST; BEGIN (*1*) C:=0; IF (A = 0) OR (B = 0) THEN RETURN(C); END; DIPMAD(A, AL,EL,AP); DIPMAD(B, BL,FL,BP); IF (AP = SIL) AND (BP = SIL) THEN RETURN(C); END; (*2*) (*Reduction. *) GL:=EVLCM(EL,FL); IF AP = SIL THEN FL1:=EVDIF(GL,FL); CL:=RNNEG(AL); BPP:=DIPFMO(CL,FL1); C:=DIRPPR(BP,BPP); RETURN(C); END; IF BP = SIL THEN EL1:=EVDIF(GL,EL); APP:=DIPFMO(BL,EL1); C:=DIRPPR(AP,APP); RETURN(C); END; (*3*) (*General case. *) evo:=EVORD; EVORD:=X; EL1:=EVDIF(GL,EL); FL1:=EVDIF(GL,FL); APP:=DIPFMO(BL,EL1); BPP:=DIPFMO(AL,FL1); APP:=DIRPPR(AP,APP); BPP:=DIRPPR(BP,BPP); C:=DFP(APP,BPP); (*????*) EVORD:=evo; (*6*) RETURN(C); END DIRPSP; PROCEDURE UG(LF,I,V,STAP,P,NURLF,PAR: LIST): LIST; (*Universal Groebner base. Diese funktion berechnet eine universelle groebner- familie ugf. lf sind tupel der form (a,l,k,n), wobei l die eingabemenge von polynomen, a eine von allen dazugehoerigen linearformen, k die spur und n die reduzierte differenz der eingabemenge der exponententupel ist. die berechnung realisiert die option ugb. diese funktion wird von der funktion ugb aufgerufen. *) VAR evo, D, DS, DSUM, FLAG, J1Y, J2Y, J3Y, L, LFALT, LFEND, LFNEU, LFP, LFTEMP, LNEU, LSUM, PAARE, PAIRS, SEMA, STAPP, U, UGF, X: LIST; fin: BOOLEAN; BEGIN (*1*) UGF:=SIL; LFP:=LF; STAPP:=STAP; LFTEMP:=SIL; LFEND:=SIL; (*2*) LFP:=GS1(LFP,V,PAR); LSUM:=EXPTU(P); DSUM:=SIL; LFALT:=NURLF; IF PAR = 8 THEN SWRITE("Reduktionsschritt"); BLINES(1); END; evo:=EVORD; REPEAT (*3*) LSUM:=USUN(LSUM,DSUM); LFTEMP:=SIL; FLAG:=0; DSUM:=SIL; WHILE LFP <> SIL DO DS:=SIL; ADV(LFP, X,LFP); EVORD:=FIRST(X); L:=SECOND(X); PAIRS:=LASTEL(X); MKSP1(FIRST(X),L,PAIRS,I,V, D,PAARE); IF D = 0 THEN UGF:=COMP(X,UGF); J1Y:=FIRST(X); LFEND:=COMP(J1Y,LFEND); ELSE LNEU:=COMP(D,L); J1Y:=LIST1(D); DSUM:=USUN(J1Y,DSUM); J1Y:=FIRST(X); J2Y:=THIRD(X); J3Y:=FOURTH(X); J1Y:=LIST5(J1Y,LNEU,J2Y,J3Y,PAARE); LFTEMP:=COMP(J1Y,LFTEMP); FLAG:=1; END; END; LOOP fin:=FALSE; IF FLAG = 1 THEN ISNEU(DSUM,LSUM,PAR, SEMA,DSUM); IF SEMA = 1 THEN NEULF(STAPP,DSUM,LSUM,I,V,PAR,LFNEU,STAPP); U:=ISNEUL(LFNEU,LFALT,PAR); LFALT:=LFNEU; IF U = 0 THEN IF PAR = 8 THEN SWRITE("Keine neuen Linearformen"); BLINES(1); END; LFP:=NONEWL(LFTEMP); LFP:=GS2(LFP,V,PAR); BLINES(1); EXIT; (*GO TO 3*) END; IF U = 1 THEN IF PAR = 8 THEN SWRITE("Neue Linearformen entstanden "); BLINES(1); END; LFP:=NEWL(LFTEMP,LFNEU,LFEND); BLINES(1); LFP:=GS2(LFP,V,PAR); EXIT; (*GO TO 3*) END; END; IF SEMA = 0 THEN LFP:=NONEWL(LFTEMP); LFP:=GS2(LFP,V,PAR); BLINES(1); EXIT; (*GO TO 3*) END; END; fin:=TRUE; EXIT END; (*loop*) UNTIL fin; EVORD:=evo; (*6*) RETURN(UGF); END UG; PROCEDURE PUG(LF,I,V,P,DEGP,NURLF,PAR,LFQ: LIST): LIST; (*Universal Groebner base using precomputation. Diese funktion berechnet eine universelle groebner- familie ugf. lf sind tupel der form (a,l,k,n), wobei l die eingabemenge von polynomen, a eine von allen dazugehoerigen linearformen, k die spur und n die reduzierte differenz der eingabemenge der exponententupel ist. die berechnung realisiert die option pugb. diese funktion wird von der funktion pugb aufgerufen. *) VAR evo, D, DEG, DEG1, DS, DSUM, DSUM1, FLAG, J1Y, J2Y, J3Y, L, LFALT, LFEND, LFNEU, LFP, LFTEMP, LNEU, LSUM, PAARE, PAIRS, R, SEMA, U, UGF, X: LIST; fin: BOOLEAN; BEGIN (*1*) UGF:=SIL; LFP:=LF; LFTEMP:=SIL; LFEND:=SIL; DEG:=DEGP; (*2*) LFP:=GS1(LFP,V,PAR); LSUM:=EXPTU(P); DSUM:=SIL; LFALT:=NURLF; IF PAR = 8 THEN SWRITE("Reduktionsschritt"); BLINES(1); END; evo:=EVORD; REPEAT (*3*) LSUM:=USUN(LSUM,DSUM); LFTEMP:=SIL; FLAG:=0; DSUM:=SIL; WHILE LFP <> SIL DO DS:=SIL; ADV(LFP, X,LFP); EVORD:=FIRST(X); L:=SECOND(X); PAIRS:=LASTEL(X); MKSP1(FIRST(X),L,PAIRS,I,V, D,PAARE); IF D = 0 THEN UGF:=COMP(X,UGF); J1Y:=FIRST(X); LFEND:=COMP(J1Y,LFEND); ELSE LNEU:=COMP(D,L); J1Y:=LIST1(D); DSUM:=USUN(J1Y,DSUM); J1Y:=FIRST(X); J2Y:=THIRD(X); J3Y:=FOURTH(X); J1Y:=LIST5(J1Y,LNEU,J2Y,J3Y,PAARE); LFTEMP:=COMP(J1Y,LFTEMP); FLAG:=1; END; END; LOOP fin:=FALSE; IF FLAG = 1 THEN DSUM1:=DSUM; ISNEU(DSUM,LSUM,PAR,SEMA,DSUM); IF SEMA = 1 THEN DEG1:=LDEG(DSUM1); IF PAR = 8 THEN SWRITE("Grad der Polynome "); OWRITE(DEG1); BLINES(1); END; IF DEG1 > DEG THEN SWRITE("Lese Linearfomen ... "); IF I = 2 THEN IQR(DEG1,2, DEG1,R); IF R <> 0 THEN DEG1:=DEG1+1; END; END; IF PAR = 8 THEN BLINES(1); END; LFNEU:=LFGET(DEG1,LFQ); LFNEU:=DO1(LFNEU); U:=ISNEUL(LFNEU,LFALT,PAR); DEG:=DEG1; ELSE U:=0; LFNEU:=LFALT; END; LFALT:=LFNEU; IF U = 0 THEN IF PAR = 8 THEN SWRITE("Keine neuen Linearformen"); BLINES(1); END; LFP:=NONEWL(LFTEMP); LFP:=GS2(LFP,V,PAR); BLINES(1); EXIT; (*GO TO 3*) END; IF U = 1 THEN IF PAR = 8 THEN SWRITE("Neue linearformen entstanden "); BLINES(1); END; LFP:=NEWL(LFTEMP,LFNEU,LFEND); BLINES(1); LFP:=GS2(LFP,V,PAR); EXIT; (*GO TO 3*) END; END; IF SEMA = 0 THEN LFNEU:=LFALT; LFP:=NONEWL(LFTEMP); BLINES(1); LFP:=GS2(LFP,V,PAR); BLINES(1); EXIT; (*GO TO 3*) END; END; fin:=TRUE; EXIT END; (*loop*) UNTIL fin; EVORD:=evo; (*6*) RETURN(UGF); END PUG; PROCEDURE NEWL(LFTEMP,LFNEU,LFEND: LIST): LIST; (*UGB update linear forms from new terms. Lfneu ist die menge der linearformen auf der neuen menge von termen. die funktion stellt fest welche von diesen linearformen die alten fortsetzen und aktualisiert das zwischenergebnis lftemp durch lfp. die funktion wird auch nur aufgerufen wenn neue linearformen enstanden sind. diese funktion wird von den funktionen ug und pug aufgerufen. *) VAR LF, LFNEUP, LFP, LL, SP, X: LIST; BEGIN (*1*) SP:=LFTEMP; LFNEUP:=LFNEU; LL:=SIL; (*2*) WHILE SP <> SIL DO ADV(SP, X,SP); ZULFO(LFNEUP,X,LL,LFEND,LFP,LF); LFNEUP:=LF; LL:=LFP; END; (*5*) RETURN(LFP); END NEWL; PROCEDURE ZULFO(LFNEU,X,LL,LFEND: LIST; VAR LFP,LF: LIST); (*UGB find admissible extensions of linear forms. Diese funktion stellt fest, welche linearformen aus lfneu die linearform von x fortsetzen. diese linearformen mit den aktualisierten daten (spur, paare) ersetzen dann x in ll. das ergebnis ist lfp. diese funktion wird von der funktion newl aufgerufen. *) VAR A, D, DIFNEU, J1Y, K1, KALT, L, LFNEU1, LFNEUP, LNEU, NEWKEG, U: LIST; BEGIN (*1*) LFNEUP:=LFNEU; KALT:=SIL; LFNEU1:=SIL; LFP:=LL; (*2*) WHILE LFNEUP <> SIL DO ADV(LFNEUP, A,LFNEUP); J1Y:=FOURTH(X); K1:=CSPUR(A,J1Y,KALT); J1Y:=THIRD(X); U:=COMPA2(J1Y,K1); IF U = 1 THEN LNEU:=SECOND(X); ADV(LNEU, D,L); J1Y:=FOURTH(X); DIFNEU:=NEWDIF(L,D,J1Y); NEWKEG:=CSPUR(A,DIFNEU,KALT); J1Y:=LASTEL(X); J1Y:=LIST5(A,LNEU,NEWKEG,DIFNEU,J1Y); LFP:=COMP(J1Y,LFP); ELSE LFNEU1:=COMP(A,LFNEU1); END; END; LF:=LFNEU1; (*5*) RETURN; END ZULFO; PROCEDURE NONEWL(LFTEMP: LIST): LIST; (*UGB update linear forms without new terms. Diese funktion wird aufgerufen wenn keine linearformen entstanden sind. sie aktualisiert lftemp durch lfp. diese funktion wird von den funktionen ug und pug aufgerufen. *) VAR D, DIFNEU, J1Y, J2Y, KALT, L, LFP, LFTEP, LNEU, NEWKEG, X: LIST; BEGIN (*1*) LFTEP:=LFTEMP; KALT:=SIL; LFP:=SIL; (*2*) WHILE LFTEP <> SIL DO ADV(LFTEP, X,LFTEP); LNEU:=SECOND(X); ADV(LNEU, D,L); J1Y:=FOURTH(X); DIFNEU:=NEWDIF(L,D,J1Y); J1Y:=FIRST(X); NEWKEG:=CSPUR(J1Y,DIFNEU,KALT); J1Y:=FIRST(X); J2Y:=LASTEL(X); J1Y:=LIST5(J1Y,LNEU,NEWKEG,DIFNEU,J2Y); LFP:=COMP(J1Y,LFP); END; (*5*) RETURN(LFP); END NONEWL; PROCEDURE ISNEUL(LFALT,LFNEU,PAR: LIST): LIST; (*UGB new linear form test. Lfalt ist die alte liste von linearformen, lfneu die neue. diese funktion stellt fest ob neue linearformen entstanden sind (u gleich 1) oder nicht (u gleich 0). diese funktion wird von den funktionen ug und pug aufgerufen. *) VAR I, J, U: LIST; BEGIN (*1*) I:=LENGTH(LFALT); J:=LENGTH(LFNEU); (*2*) IF I = J THEN U:=0; ELSE U:=1; END; (*5*) RETURN(U); END ISNEUL; PROCEDURE NEULF(STAP,DSUM,LSUM,I,V,PAR: LIST; VAR LFNEU,NEUST: LIST); (*UGB compute new linear forms from new terms. Diese funktion berechnet, nachdem neue terme entstanden sind, die neuen linearformen. die berechnung basiert auf die bereits beschriebenen funktionen und prozeduren zur berechnung von linearformen. dsum ist die liste der neuen s-polynome, lsum die liste der alten polynome, stap der alte stapel der projektionen. das ergebnis ist die liste der neuen linearformen lfneu und der neue stapel von projektionen neust. diese funktion wird von der funktion ug aufgerufen. *) VAR DIFALT, E, KALT, OLDL, PSUM: LIST; BEGIN (*1*) E:=DSUM; E:=MAKERN(E); DIFALT:=SIL; OLDL:=SIL; KALT:=SIL; (*2*) PSUM:=LSUM; PSUM:=MAKERN(PSUM); NEUST:=SIL; OLDL:=LIST3(SIL,SIL,SIL); (*3*) NEUST:=PROJEC(PSUM,E,DIFALT,OLDL,I,PAR); (*4*) NEUST:=MERGE(STAP,NEUST); (*5*) LFNEU:=ALLLF(NEUST,KALT,I); (*8*) RETURN; END NEULF; PROCEDURE ISNEU(DSUM,LSUM,PAR: LIST; VAR SEMA,DD: LIST); (*UGB new terms test. Diese funktion stellt fest, ob neue terme in dusm entstanden sind. dsum ist die liste der neuen s-polynome in normalform, lsum die alte liste von polynomen. die ausgabe sema ist gleich 1 falls neue terme entstanden sind. ansonsten 0. dd ist die liste der neuen terme. diese funktion wird von den funktionen ug und pug aufgerufen. *) VAR A, B, D, LP, TEMP, U, COUNT: LIST; BEGIN (*1*) LP:=LSUM; D:=EXPTU(DSUM); COUNT:=0; DD:=SIL; (*2*) WHILE D <> SIL DO ADV(D, A,D); TEMP:=SIL; U:=0; WHILE (LP <> SIL) AND (U <> 1) DO ADV(LP, B,LP); U:=COMPA2(A,B); IF U <> 1 THEN TEMP:=COMP(B,TEMP); END; END; LP:=TCOMP(TEMP,LP); IF U <> 1 THEN COUNT:=COUNT+1; DD:=COMP(A,DD); END; END; IF COUNT > 0 THEN SEMA:=1; IF (COUNT = 1) AND (PAR = 8) THEN SWRITE("Es ist nur ein neuer Term entstanden"); BLINES(1); END; IF (COUNT >= 2) AND (PAR = 8) THEN SWRITE("es sind "); OWRITE(COUNT); SWRITE(" neue Terme entstanden"); BLINES(1); END; END; IF COUNT = 0 THEN SEMA:=0; IF PAR = 8 THEN SWRITE("es ist kein neuer Term entstanden"); BLINES(1); END; END; (*5*) RETURN; END ISNEU; PROCEDURE TCOMP(X,Y: LIST): LIST; (*UGB list constructive conc. ??CCONC?? X und y sind zwei listen. diese prozedur konkatiniert sie zu einer liste z. diese funktion wird von der funktion isneu aufgerufen. *) VAR A, XP, Z: LIST; BEGIN (*1*) XP:=X; Z:=Y; (*2*) IF X = SIL THEN Z:=Y; RETURN(Z); END; (*3*) IF Y = SIL THEN Z:=X; RETURN(Z); END; WHILE XP <> SIL DO ADV(XP, A,XP); Z:=COMP(A,Z); END; (*6*) RETURN(Z); END TCOMP; PROCEDURE NEWDIF(L,D,DIFALT: LIST): LIST; (*UGB exponent vector list difference from polynomials. Diese funktion liest durch die funktion exptu die exponententupel der terme von l und d und berechnet mit hilfe der funktion pdif die differenz. fuer die berechnung der neuen differenz wird das schon berechnete ergebnis genutzt. diese funktion wird von den funktionen zulfo und nonewl aufgerufen. *) VAR D1, D2, DIFALP, DIFNEU, J1Y, L1, L2: LIST; BEGIN (*1*) L2:=EXPTU(L); L1:=MAKERN(L2); J1Y:=LIST1(D); D2:=EXPTU(J1Y); D1:=MAKERN(D2); DIFALP:=DIFALT; (*2*) DIFNEU:=PDIF(L1,D1,DIFALP); (*5*) RETURN(DIFNEU); END NEWDIF; PROCEDURE GS2(LF,V,PAR: LIST): LIST; (*UGB generate stack of sorted polynomials and critical pairs 2. Diese funktion funktioniert aehnlich zu gs1. sie ist wegen der uebersichtlichkeit getrennt geschrieben. die funktion aktualisiert die zwischenergebnisse lf (tupel der form (a,l,k,n,b) wie die ausgabe von gs1), d.h sie ordnet die polynome neu und aktualisiert die mengen von paaren. diese funktion wird von den funktionen ug und pug aufgerufen. *) VAR evo, A, B, J1Y, J2Y, J3Y, LFP, LP, LP1, PAIRS, STAK, X: LIST; BEGIN (*1*) LFP:=LF; STAK:=SIL; evo:=EVORD; IF PAR = 8 THEN SWRITE("Ordne die Polynome nach den neuen Linearformen"); BLINES(1); END; (*2*) WHILE LFP <> SIL DO ADV(LFP, A,LFP); B:=FIRST(A); LP:=SECOND(A); EVORD:=B; LP:=POLCOP(LP); DILBSO(LP); LP1:=LP; J1Y:=RED(LP); J2Y:=FIRST(LP); J3Y:=LASTEL(A); PAIRS:=MKNEWP(J1Y,J2Y,J3Y); J1Y:=THIRD(A); J2Y:=FOURTH(A); X:=LIST5(B,LP1,J1Y,J2Y,PAIRS); J1Y:=LIST1(X); STAK:=USUN(J1Y,STAK); END; EVORD:=evo; (*5*) RETURN(STAK); END GS2; PROCEDURE ALLLF(STAKK,KALT,I: LIST): LIST; (*UGB all linear forms from stack of projections and print. Die funktion funktionniert genauso wie lfall. hier werden nur die linearformen berechnet und ausgegeben. diese funktion wird von der funktion neulf aufgerufen. *) VAR A, IP, J1Y, LENG, LF, LFX, LISTLF, LY, M, N, NEWLF, NURLF, Q2, STAKKP: LIST; BEGIN (*1*) STAKKP:=STAKK; M:=1; IP:=I; LISTLF:=SIL; (*2*) J1Y:=RNINT(1); LFX:=LIST1(J1Y); LY:=SIL; LF:=LIST1(LFX); IP:=IP-1; NEWLF:=SIL; WHILE M <= IP DO ADV(STAKKP, A,STAKKP); N:=FIRST(A); Q2:=SECOND(A); NURLF:=MKLF3(LF,Q2,N,M); M:=M+1; LF:=NURLF; END; SWRITE("Die disjunkten Linearformen sind "); OWRITE(LENGTH(NURLF)); SWRITE(" Linearformen "); BLINES(1); NURLF:=LF; (*5*) RETURN(NURLF); END ALLLF; PROCEDURE LFALL(STAKK,L,KALT,I: LIST; VAR LISTLF,NURLF: LIST); (*UGB all linear forms from stack of projections 1. Diese funktion funktionniert genauso wie alleln, mit dem unterschied, dass das element 1 als letzte komponente der linearform gespeichert wird. diese funktion wird von der funktion ugb aufgerufen. *) VAR A, IP, J1Y, LF, LFX, LY, M, N, NEWLF, Q2, STAKKP: LIST; BEGIN (*1*) STAKKP:=STAKK; M:=1; IP:=I; LISTLF:=SIL; (*2*) J1Y:=RNINT(1); LFX:=LIST1(J1Y); LY:=SIL; LF:=LIST1(LFX); IP:=IP-1; NEWLF:=SIL; WHILE M <= IP DO ADV(STAKKP, A,STAKKP); N:=FIRST(A); Q2:=SECOND(A); MKLF2(LF,Q2,N,M,L, NURLF,LISTLF); M:=M+1; LF:=NURLF; END; NURLF:=LF; SWRITE("Die berechneten Linearformen sind "); OWRITE(LENGTH(NURLF)); BLINES(1); (*5*) RETURN; END LFALL; PROCEDURE MKLF3(LFP,Q2,NP,M: LIST): LIST; (*UGB make new linear forms 3. Diese funktionniert genauso wie mklf2. hier werden nur die linearformen (newlf) berechnet und ausgegeben. diese funktion wird von der funktion alllf aufgerufen. *) VAR A, B, D, J, J1Y, KLIST, LF, LISTLF, NEWLF, TR: LIST; BEGIN (*1*) LF:=LFP; NEWLF:=SIL; KLIST:=SIL; J:=0; LISTLF:=SIL; (*2*) WHILE LF <> SIL DO D:=SIL; ADV(LF, B,LF); IF Q2 = SIL THEN J1Y:=LIST2(1,1); D:=LIST1(J1Y); ELSE TR:=CP2(B,Q2); TR:=RNVABS(TR); TR:=LRNBMS(TR); D:=CUT(TR); END; CLF3(B,D,KLIST,NP,J,M, A,KLIST,J); NEWLF:=USUN(A,NEWLF); END; (*5*) RETURN(NEWLF); END MKLF3; PROCEDURE CLF3(C,D,KLIST,NP,JP,M: LIST; VAR LFORM,KLISTP,J: LIST); (*UGB compute linear form from difference set 3. Diese funktionniert genauso wie clf2. hier werden nur die linearformen (lform) berechnet und ausgegeben. diese funktion wird von der funktion mklf3 aufgerufen. *) VAR A, DP, K, KALT, KLISTH, U: LIST; BEGIN (*1*) DP:=D; LFORM:=SIL; J:=JP; KLISTP:=KLIST; KALT:=SIL; KLISTH:=SIL; (*2*) WHILE DP <> SIL DO ADV(DP, A,DP); A:=COMP(A,C); K:=CSPUR(A,NP,KALT); IF M <> 1 THEN U:=COMPA1(K,KLISTP); IF U <> 1 THEN KLISTH:=COMP(K,KLISTH); LFORM:=COMP(A,LFORM); END; ELSE LFORM:=COMP(A,LFORM); END; END; KLISTP:=CCONC(KLISTP,KLISTH); (*5*) RETURN; END CLF3; PROCEDURE DO1(LFP: LIST): LIST; (*UGB add last component to exponent vector. Um speicherplatz zu sparen wurden die linearformen ohne das 1 element als letzte komponente gespeichert. diese funktion fuegt fuer die liste der linearformen lfp das element 1 ein. das ergebnis ist lf1. diese funktion wird von der funktion pugb aufgerufen. *) VAR A, LF, LF1, E: LIST; BEGIN (*1*) LF:=LFP; LF1:=SIL; E:=LIST1(RNINT(1)); WHILE LF <> SIL DO ADV(LF, A,LF); A:=CCONC(A,E); LF1:=COMP(A,LF1); END; LF1:=INV(LF1); (*4*) RETURN(LF1); END DO1; PROCEDURE MKLIST(LF,L: LIST; VAR LFLIST,NURLF: LIST); (*UGB make trace and cuts. Diese funktion wird aufgerufen bei der option pugb. die liste der eingelesenen linearformen lf ist groesser als noetig. diese funktion reduziert diese linearformen, sodass bezueglich der menge p von polynomen verschiedene ordnungen ergeben. nurlf ist dann das ergebnis. listlf besteht aus tupel der form (a,l,k,n) wie das ergebnis von lfall. diese funktion wird von der funktion pugb aufgerufen. *) VAR A, J1Y, K, KALT, KLIST, LFP, P, Q: LIST; BEGIN (*1*) LFP:=LF; KALT:=SIL; KLIST:=SIL; NURLF:=SIL; LFLIST:=SIL; Q:=EXPTU(L); P:=MAKERN(Q); (*2*) P:=DIFF(P); (*3*) WHILE LFP <> SIL DO ADV(LFP, A,LFP); K:=CSPUR(A,P,KALT); NURLF:=COMP(A,NURLF); J1Y:=LIST4(A,L,K,P); LFLIST:=COMP(J1Y,LFLIST); END; (*6*) RETURN; END MKLIST; PROCEDURE LDEG(L: LIST): LIST; (*Distributive polynomial list total degree. Diese funktion bestimmt fuer eine liste von polynomen l den maximalen totalgrad, der darin auftaucht. diese funktion wird von den funktionen pug und pugb aufgerufen. *) VAR DEG, DEG1, L1, LP: LIST; BEGIN (*1*) LP:=L; DEG:=0; (*2*) WHILE LP <> SIL DO ADV(LP, L1,LP); DEG1:=DIPTDG(L1); DEG:=IMAX(DEG,DEG1); END; (*5*) RETURN(DEG); END LDEG; END MASUGB.