(* ---------------------------------------------------------------------------- * $Id: GSYMFURN.mi,v 1.1 1995/11/05 15:57:30 pesch Exp $ * ---------------------------------------------------------------------------- * This file is part of MAS. * ---------------------------------------------------------------------------- * Copyright (c) 1995 Universitaet Passau * ---------------------------------------------------------------------------- * $Log: GSYMFURN.mi,v $ * Revision 1.1 1995/11/05 15:57:30 pesch * Diplomarbeit Manfred Goebel, Reduktion G-symmetrischer Polynome fuer * beliebige Permutationsgruppen G, slightly edited. * * ---------------------------------------------------------------------------- *) IMPLEMENTATION MODULE GSYMFURN; (* G-Symmetric Rational Polynomial System Implementation Module. *) FROM MASELEM IMPORT GAMMAINT; FROM MASSTOR IMPORT ADV, COMP, FIRST, INV, LENGTH, LIST, LIST1, RED, SIL; FROM MASBIOS IMPORT BLINES, SWRITE; FROM SACLIST IMPORT CINV, EQUAL, LEINST, LELT, LREAD, MEMBER, OWRITE, SLELT; FROM SACSET IMPORT LBIBS; FROM SACRN IMPORT RNINT, RNSIGN, RNSUM; FROM LINALGRN IMPORT MTRANS, RNMGELUD, RNMSDS; FROM DIPC IMPORT DIPFMO, DIPMAD, EVCOMP, EVDEL, EVDIF, EVILCI, EVSIGN; FROM DIPRN IMPORT DIRPDF, DIRPEX, DIRPPR, DIRPRP, DIRPSM; FROM DIPRNGB IMPORT DIRGBA, DIRPNF; FROM GSYMFUIN IMPORT GSYADD, GSYMLT, GSYSPG, GSYTWG; CONST rcsidi = "$Id: GSYMFURN.mi,v 1.1 1995/11/05 15:57:30 pesch Exp $"; CONST copyrighti = "Copyright (c) 1995 Universitaet Passau"; PROCEDURE GRNORP(PG, MO: LIST): LIST; VAR HK, HT, HTL, TERM, RES, NRES, NPG, XX, DUMMY: LIST; I, N, L, NL: GAMMAINT; BEGIN RES := 0; L := 0; IF PG = SIL THEN RETURN(RES); END; N := LENGTH(FIRST(PG)); IF MO = 0 THEN RETURN(RES); END; IF LENGTH(MO) # 2 THEN RETURN(-1); END; IF LENGTH(FIRST(MO)) # N THEN RETURN(-1); END; DIPMAD(MO, HK, HT, DUMMY); HTL := SIL; HTL := COMP(HT, HTL); WHILE HTL # SIL DO ADV(HTL, HT, HTL); NPG := PG; WHILE NPG # SIL DO ADV(NPG, XX, NPG); TERM := INV(CINV(HT)); FOR I := 1 TO N DO SLELT(TERM, N+1-LELT(XX, I), LELT(HT, N+1-I)); END; (* of for *) NRES := DIRPSM(RES, DIPFMO(HK, TERM)); IF NRES # 0 THEN NL := LENGTH(NRES); ELSE NL := 0; END; IF NL > L THEN RES := NRES; L := NL; HTL := COMP(TERM, HTL); END; (* of if *) END; (* of while *) END; (* of while *) RETURN(RES); END GRNORP; PROCEDURE GRNOPL(PG, ML: LIST): LIST; VAR HM, RES: LIST; BEGIN RES := SIL; WHILE ML # SIL DO ADV(ML, HM, ML); RES := COMP(GRNORP(PG, HM), RES); END; (* of while *) RETURN(INV(RES)); END GRNOPL; PROCEDURE GRNCUT(PG, POL: LIST; VAR POL1, POL2: LIST); VAR ORBIT, HM, HT, HK, DUMMY: LIST; BEGIN POL1 := 0; POL2 := 0; WHILE POL # 0 DO DIPMAD(POL, HK, HT, DUMMY); HM := DIPFMO(HK, HT); ORBIT := GRNORP(PG, HM); IF EQUAL(HT, FIRST(ORBIT)) = 1 THEN POL1 := DIRPSM(POL1, ORBIT); POL := DIRPDF(POL, ORBIT); ELSE POL2 := DIRPSM(POL2, HM); POL := DIRPDF(POL, HM); END; (* of if *) END; (* of while *) END GRNCUT; PROCEDURE GRNCHK(PG, BASE, POL: LIST): LIST; VAR RES, HK, HT, BASE_ORBIT, PROD: LIST; I, N: GAMMAINT; BEGIN RES := 0; IF POL = 0 THEN RETURN(RES); END; N := LENGTH(BASE); IF N = 0 THEN RETURN(RES); END; BASE_ORBIT := GRNOPL(PG, BASE); WHILE POL # 0 DO DIPMAD(POL, HK, HT, POL); IF POL = SIL THEN POL := 0; END; PROD := DIRPEX(LELT(BASE_ORBIT, 1), 0); FOR I := 1 TO N DO PROD := DIRPPR(PROD, DIRPEX(LELT(BASE_ORBIT, I), LELT(HT, I))); END; (* of for *) RES := DIRPSM(RES, DIRPRP(PROD, HK)); END; (* of while *) RETURN(RES); END GRNCHK; PROCEDURE GRNCHKBAS(VAR BASE, POL: LIST); VAR NBASE, NPOL, HT, HK, POS, DUMMY: LIST; I, J, N1, N2: GAMMAINT; BEGIN IF POL = 0 THEN BASE := SIL; END; IF BASE = SIL THEN RETURN; END; N1 := LENGTH(BASE); NBASE := BASE; BASE := SIL; FOR I := 1 TO N1 DO NPOL := POL; LOOP IF NPOL = SIL THEN EXIT; END; DIPMAD(NPOL, HK, HT, NPOL); IF LELT(HT, I) # 0 THEN BASE := COMP(LELT(NBASE, I), BASE); EXIT; END; (* of if *) END; (* of loop *) END; (* of for *) BASE := INV(BASE); N2 := LENGTH(BASE); IF N1 = N2 THEN RETURN; END; (* nothing has changed *) NPOL := POL; POL := 0; J := 1; POS := SIL; FOR I := 1 TO N1 DO IF (J<=N2) AND (EQUAL(LELT(NBASE, I), LELT(BASE, J)) = 1) THEN J := J + 1; ELSE POS := COMP(I, POS); END; (* of if *) END; (* of for *) WHILE NPOL # SIL DO DIPMAD(NPOL, HK, HT, NPOL); FOR I := 1 TO LENGTH(POS) DO EVDEL(HT, LELT(POS, I), HT, DUMMY); END; (* of for *) POL := DIRPSM(POL, DIPFMO(HK, HT)); END; (* of while *) END GRNCHKBAS; PROCEDURE EXTRACT(PG, POL_1, POL_2, POL_3: LIST; VAR BASE, POL: LIST); VAR NPOL, TERM, TERM1, HT, HK, HM, ORBIT, DUMMY: LIST; POS, I, N, SIGN: GAMMAINT; BEGIN BASE := SIL; POL := SIL; IF (POL_1 # 0) AND (POL_2 # 0) THEN TERM := FIRST(POL_1); TERM1 := FIRST(POL_2); SIGN := GSYTWG(TERM, TERM1); IF SIGN = 0 THEN POL := DIPFMO(RNINT(1), LIST1(2)); BASE := LIST1(DIPFMO(RNINT(1), TERM)); ELSE SIGN := SIGN + 1; IF SIGN = 2 THEN SIGN := 1; END; POL := DIPFMO(RNINT(1), COMP(1, LIST1(1))); BASE := LEINST(LIST1(DIPFMO(RNINT(1), TERM)), SIGN, DIPFMO(RNINT(1), TERM1)); END; (* of if *) END; (* of if *) WHILE POL_3 # 0 DO DIPMAD(POL_3, HK, HT, DUMMY); HM := DIPFMO(HK, HT); ORBIT := GRNORP(PG, HM); POL_3 := DIRPDF(POL_3, ORBIT); IF BASE = SIL THEN POL := DIPFMO(HK, LIST1(1)); BASE := LIST1(DIPFMO(RNINT(1), HT)); ELSE N := LENGTH(BASE); POS := 0; LOOP POS := POS + 1; IF POS > N THEN EXIT; END; HM := LELT(BASE, POS); IF GSYTWG(FIRST(HM), HT) <= 0 THEN EXIT; END; END; (* of loop *) POS := POS - 1; BASE := LEINST(BASE, POS, DIPFMO(RNINT(1), HT)); NPOL := POL; HT := SIL; FOR I := 1 TO N DO HT := COMP(0, HT); END; (* of for *) HT := LEINST(HT, POS, 1); POL := DIPFMO(HK, HT); WHILE NPOL # SIL DO DIPMAD(NPOL, HK, HT, NPOL); HT := LEINST(HT, POS, 0); POL := DIRPSM(DIPFMO(HK, HT), POL); END; (* of while *) END; (* of if *) END; (* of while *) END EXTRACT; PROCEDURE MERGE(K: GAMMAINT; BASE_1, POL_1: LIST; VAR BASE_2, POL_2: LIST); VAR XBASE, NPOL1, NPOL2, HK1, HT1, HM1, HK2, HT2, HM2, POS1, POS2, DUMMY: LIST; I, J, L1, L2, N, EL, SIGN: GAMMAINT; BEGIN L1 := LENGTH(BASE_1); L2 := LENGTH(BASE_2); XBASE := SIL; POS1 := SIL; POS2 := SIL; I := 0; J := 0; WHILE BASE_2 # SIL DO ADV(BASE_2, HM2, BASE_2); HT2 := FIRST(HM2); LOOP IF BASE_1 # SIL THEN ADV(BASE_1, HM1, DUMMY); HT1 := FIRST(HM1); SIGN := GSYTWG(HT2, HT1); ELSE SIGN := 1; END; (* of if *) IF SIGN = 1 THEN IF J < L2 THEN J := J + 1; END; POS1 := COMP(I, POS1); IF J # K THEN XBASE := COMP(HM2, XBASE); END; EXIT; END; (* of if *) IF SIGN = 0 THEN IF I < L1 THEN I := I + 1; END; IF J < L2 THEN J := J + 1; END; XBASE := COMP(HM2, XBASE); BASE_1 := RED(BASE_1); EXIT; END; (* of if *) IF SIGN = -1 THEN IF I < L1 THEN I := I + 1; END; POS2 := COMP(J, POS2); XBASE := COMP(HM1, XBASE); BASE_1 := RED(BASE_1); END; (* of if *) END; (* of loop *) END; (* of while *) WHILE BASE_1 # SIL DO ADV(BASE_1, HM1, BASE_1); XBASE := COMP(HM1, XBASE); POS2 := COMP(J, POS2); END; (* of while *) BASE_2 := INV(XBASE); N := LENGTH(BASE_2); NPOL1 := 0; IF POL_1 = 0 THEN POL_1 := SIL; END; WHILE POL_1 # SIL DO DIPMAD(POL_1, HK1, HT1, POL_1); FOR I := 1 TO LENGTH(POS1) DO HT1 := LEINST(HT1, LELT(POS1, I), 0); END; (* of for *) NPOL1 := DIRPSM(DIPFMO(HK1, HT1), NPOL1); END; (* of while *) NPOL2 := 0; IF POL_2 = 0 THEN POL_2 := SIL; END; WHILE POL_2 # SIL DO DIPMAD(POL_2, HK2, HT2, POL_2); FOR I := 1 TO LENGTH(POS2) DO HT2 := LEINST(HT2, LELT(POS2, I), 0); END; (* of for *) NPOL2 := DIRPSM(DIPFMO(HK2, HT2), NPOL2); END; (* of while *) IF K = 0 THEN POL_2 := DIRPSM(NPOL1, NPOL2); RETURN; END; POL_1 := 0; IF NPOL1 = 0 THEN NPOL1 := SIL; END; WHILE NPOL1 # SIL DO DIPMAD(NPOL1, HK1, HT1, NPOL1); EVDEL(HT1, K, HT1, DUMMY); POL_1 := DIRPSM(POL_1, DIPFMO(HK1, HT1)); END; (* of while *) POL_2 := 0; IF NPOL2 = 0 THEN NPOL2 := SIL; END; WHILE NPOL2 # SIL DO DIPMAD(NPOL2, HK2, HT2, NPOL2); EVDEL(HT2, K, HT2, EL); POL_2 := DIRPSM(POL_2, DIRPPR(DIRPEX(POL_1, EL), DIPFMO(HK2, HT2))); END; (* of while *) END MERGE; PROCEDURE REDUCE(PG, ORBIT: LIST; VAR BASE, POL: LIST); VAR HK, HT, HM, RED_HT, BHM, BHT, PHM, PHK, PHT, TERM, XX, XHT, XHK, SIGMA, SIGMA_TL, BTL, NBTL, ORBIT_S, ORBIT_RED, OMEGA, PBASE, PPOL, SPG, PAIRS, MAT, NMAT, RS, ROW, NROW, SIGN, XLS, KOEFF, POS, LOWER, UPPER, SUM, DUMMY: LIST; ACT, LOW, MINI, MAXI, I, J, L, N: GAMMAINT; FLAG: BOOLEAN; BEGIN BASE := SIL; POL := 0; IF ORBIT = 0 THEN RETURN; END; DIPMAD(ORBIT, HK, HT, DUMMY); N := LENGTH(HT); HM := DIPFMO(HK, HT); SIGMA := SIL; RED_HT := SIL; (*-------------------------------------------------------------------------*) (* ORBIT is a constant polynomial *) (*-------------------------------------------------------------------------*) IF EVSIGN(HT) = 0 THEN EXTRACT(PG, 0, 0, ORBIT, BASE, POL); RETURN; END; MAXI := 0; MINI := 999999; FOR I := 1 TO N DO ACT := LELT(HT, I); IF ACT > MAXI THEN MAXI := ACT; END; IF ACT < MINI THEN MINI := ACT; END; END; (* of for *) LOW := MAXI; I := MAXI - 1; WHILE I >= MINI DO J := 1; WHILE (J <= N) AND (LELT(HT, J) # I) DO J:=J+1; END; (* of while *) IF J = (N+1) THEN I := -1; ELSE LOW := I; END; (* of if *) I := I - 1; END; (* of while *) (*-------------------------------------------------------------------------*) (* ORBIT is not max. n-linked or max. n-linked with no zero exponents *) (*-------------------------------------------------------------------------*) IF (LOW # MINI) OR ((LOW # 0) AND (MAXI > 1)) THEN FOR I := N TO 1 BY -1 DO ACT := LELT(HT, I); IF ACT >= LOW THEN RED_HT := COMP(ACT-1, RED_HT); ELSE RED_HT := COMP(ACT, RED_HT); END; (* of if *) END; (* of for *) SIGMA := EVDIF(HT, RED_HT); ORBIT_S := GRNORP(PG, DIPFMO(RNINT(1), SIGMA)); ORBIT_RED := GRNORP(PG, DIPFMO(RNINT(1), RED_HT)); OMEGA := DIRPDF(ORBIT, DIRPPR(ORBIT_RED, ORBIT_S)); EXTRACT(PG, ORBIT_RED, ORBIT_S, OMEGA, BASE, POL); RETURN; END; (* of if *) (*-------------------------------------------------------------------------*) (* ORBIT is max. n-linked and not multilinear --> try simple reduction *) (*-------------------------------------------------------------------------*) IF MAXI > 1 THEN FOR LOW := 1 TO MAXI DO RED_HT := SIL; FOR I := N TO 1 BY -1 DO ACT := LELT(HT, I); IF ACT >= LOW THEN RED_HT := COMP(ACT-1, RED_HT); ELSE RED_HT := COMP(ACT, RED_HT); END; (* of if *) END; (* of for *) SIGMA := EVDIF(HT, RED_HT); ORBIT_S := GRNORP(PG, DIPFMO(RNINT(1), SIGMA)); ORBIT_RED := GRNORP(PG, DIPFMO(RNINT(1), RED_HT)); OMEGA := DIRPDF(ORBIT, DIRPPR(ORBIT_RED, ORBIT_S)); EXTRACT(PG, ORBIT_RED, ORBIT_S, OMEGA, BASE, POL); IF GSYTWG(HT, FIRST(FIRST(BASE))) = 1 THEN RETURN; END; END; (* of for *) END; (* of if *) (*-------------------------------------------------------------------------*) (* ORBIT is max. n-linked and not multilinear --> try extended reduction 1 *) (*-------------------------------------------------------------------------*) BLINES(0); SWRITE("HT = "); OWRITE(HT); BASE := SIL; POL := SIL; SPG := GSYSPG(N); BTL := SIL; PAIRS := SIL; MAT := SIL; RS := SIL; SIGMA_TL := GSYMLT(N); WHILE SIGMA_TL # SIL DO ADV(SIGMA_TL, SIGMA, SIGMA_TL); RED_HT := EVDIF(HT, SIGMA); IF EVSIGN(RED_HT) > 0 THEN ORBIT_RED := GRNORP(PG, DIPFMO(RNINT(1), RED_HT)); XX := GRNORP(SPG, DIPFMO(RNINT(1), SIGMA)); ELSE XX := 0; END; (* of if *) WHILE XX # 0 DO DIPMAD(XX, XHK, XHT, DUMMY); XX := DIRPDF(XX, GRNORP(PG, DIPFMO(RNINT(1), XHT))); ORBIT_S := GRNORP(PG, DIPFMO(RNINT(1), XHT)); EXTRACT(PG, ORBIT_RED, ORBIT_S, 0, PBASE, DUMMY); FLAG := FALSE; IF MEMBER(PBASE, PAIRS) # 1 THEN PAIRS := COMP(PBASE, PAIRS); PPOL := DIRPPR(ORBIT_RED, ORBIT_S); FLAG := TRUE; ELSE PPOL := 0; END; (* of if *) KOEFF := SIL; PBASE := SIL; WHILE PPOL # 0 DO DIPMAD(PPOL, PHK, PHT, DUMMY); PPOL := DIRPDF(PPOL, GRNORP(PG, DIPFMO(PHK, PHT))); L := LENGTH(PBASE); I := 0; LOOP I := I + 1; IF I > L THEN EXIT; END; PHM := LELT(PBASE, I); IF GSYTWG(FIRST(PHM), PHT) <= 0 THEN EXIT; END; END; (* of loop *) I := I - 1; PBASE := LEINST(PBASE, I, DIPFMO(RNINT(1), PHT)); KOEFF := LEINST(KOEFF, I, PHK); END; (* of while *) ROW := SIL; POS := SIL; L := LENGTH(BTL); NBTL := INV(BTL); BTL := SIL; LOOP IF PBASE = SIL THEN EXIT; END; ADV(PBASE, BHM, PBASE); BHT := FIRST(BHM); ADV(KOEFF, PHK, KOEFF); IF GSYTWG(BHT, HT) < 0 THEN EXIT; END; LOOP IF NBTL # SIL THEN ADV(NBTL, TERM, DUMMY); SIGN := GSYTWG(TERM, BHT); ELSE SIGN := -1; END; IF SIGN = 1 THEN L := L - 1; BTL := COMP(TERM, BTL); ROW := COMP(RNINT(0), ROW); NBTL := RED(NBTL); END; (* of if *) IF SIGN = 0 THEN L := L - 1; BTL := COMP(TERM, BTL); ROW := COMP(PHK, ROW); NBTL := RED(NBTL); EXIT; END; (* of if *) IF SIGN = -1 THEN POS := COMP(L, POS); BTL := COMP(BHT, BTL); ROW := COMP(PHK, ROW); EXIT; END; (* of if *) END; (* of loop *) END; (* of loop *) WHILE NBTL # SIL DO ADV(NBTL, TERM, NBTL); BTL := COMP(TERM, BTL); ROW := COMP(RNINT(0), ROW); END; (* of while *) POS := INV(POS); NMAT := INV(MAT); MAT := SIL; WHILE NMAT # SIL DO ADV(NMAT, NROW, NMAT); FOR I := 1 TO LENGTH(POS) DO NROW := LEINST(NROW, LELT(POS,I), 0); END; (* of for *) MAT := COMP(NROW, MAT); END; (* of while *) SUM := RNINT(0); FOR I := 1 TO LENGTH(ROW) DO SUM := RNSUM(SUM, LELT(ROW,I)); END; (* of for *) IF RNSIGN(SUM) # 0 THEN MAT := COMP(ROW, MAT); ELSE IF FLAG THEN PAIRS := RED(PAIRS); END; END; (* of if *) END; (* of while *) END; (* of while *) XLS := SIL; IF MAT # SIL THEN BLINES(0); SWRITE("C/R = "); OWRITE(LENGTH(MAT)); SWRITE("/"); OWRITE(LENGTH(FIRST(MAT))); FOR I := 1 TO LENGTH(FIRST(MAT))-1 DO RS := COMP(RNINT(0), RS); END; RS := COMP(RNINT(1), RS); MAT := MTRANS(MAT); RNMGELUD(MAT, LOWER, UPPER); XLS := RNMSDS(LOWER, UPPER, RS); SWRITE(" XLS = "); OWRITE(XLS); END; (* of if *) IF XLS # SIL THEN OMEGA := ORBIT; WHILE XLS # SIL DO ADV(XLS, XHK, XLS); ADV(PAIRS, PBASE, PAIRS); IF XHK # 0 THEN IF LENGTH(PBASE) = 1 THEN PPOL := DIPFMO(RNINT(1), LIST1(2)); ELSE PPOL := DIPFMO(RNINT(1), COMP(1, LIST1(1))); END; PPOL := DIRPRP(PPOL, XHK); OMEGA := DIRPDF(OMEGA, GRNCHK(PG, PBASE, PPOL)); MERGE(0, PBASE, PPOL, BASE, POL); END; (* of if *) END; (* of while *) EXTRACT(PG, 0, 0, OMEGA, PBASE, PPOL); MERGE(0, PBASE, PPOL, BASE, POL); GRNCHKBAS(BASE, POL); RETURN; END; (* of if *) (*-------------------------------------------------------------------------*) (* ORBIT is max. n-linked and not multilinear --> try extended reduction 2 *) (*-------------------------------------------------------------------------*) BASE := SIL; POL := SIL; SPG := GSYSPG(N); BTL := SIL; PAIRS := SIL; MAT := SIL; RS := SIL; SIGMA_TL := GSYMLT(N); WHILE SIGMA_TL # SIL DO ADV(SIGMA_TL, SIGMA, SIGMA_TL); RED_HT := EVDIF(HT, SIGMA); IF EVSIGN(RED_HT) > 0 THEN ORBIT_S := GRNORP(PG, DIPFMO(RNINT(1), SIGMA)); XX := GRNORP(SPG, DIPFMO(RNINT(1), RED_HT)); ELSE XX := 0; END; (* of if *) WHILE XX # 0 DO DIPMAD(XX, XHK, XHT, DUMMY); XX := DIRPDF(XX, GRNORP(PG, DIPFMO(RNINT(1), XHT))); ORBIT_RED := GRNORP(PG, DIPFMO(RNINT(1), XHT)); EXTRACT(PG, ORBIT_RED, ORBIT_S, 0, PBASE, DUMMY); FLAG := FALSE; IF MEMBER(PBASE, PAIRS) # 1 THEN PAIRS := COMP(PBASE, PAIRS); PPOL := DIRPPR(ORBIT_RED, ORBIT_S); FLAG := TRUE; ELSE PPOL := 0; END; (* of if *) KOEFF := SIL; PBASE := SIL; WHILE PPOL # 0 DO DIPMAD(PPOL, PHK, PHT, DUMMY); PPOL := DIRPDF(PPOL, GRNORP(PG, DIPFMO(PHK, PHT))); L := LENGTH(PBASE); I := 0; LOOP I := I + 1; IF I > L THEN EXIT; END; PHM := LELT(PBASE, I); IF GSYTWG(FIRST(PHM), PHT) <= 0 THEN EXIT; END; END; (* of loop *) I := I - 1; PBASE := LEINST(PBASE, I, DIPFMO(RNINT(1), PHT)); KOEFF := LEINST(KOEFF, I, PHK); END; (* of while *) ROW := SIL; POS := SIL; L := LENGTH(BTL); NBTL := INV(BTL); BTL := SIL; LOOP IF PBASE = SIL THEN EXIT; END; ADV(PBASE, BHM, PBASE); BHT := FIRST(BHM); ADV(KOEFF, PHK, KOEFF); IF GSYTWG(BHT, HT) < 0 THEN EXIT; END; LOOP IF NBTL # SIL THEN ADV(NBTL, TERM, DUMMY); SIGN := GSYTWG(TERM, BHT); ELSE SIGN := -1; END; IF SIGN = 1 THEN L := L - 1; BTL := COMP(TERM, BTL); ROW := COMP(RNINT(0), ROW); NBTL := RED(NBTL); END; (* of if *) IF SIGN = 0 THEN L := L - 1; BTL := COMP(TERM, BTL); ROW := COMP(PHK, ROW); NBTL := RED(NBTL); EXIT; END; (* of if *) IF SIGN = -1 THEN POS := COMP(L, POS); BTL := COMP(BHT, BTL); ROW := COMP(PHK, ROW); EXIT; END; (* of if *) END; (* of loop *) END; (* of loop *) WHILE NBTL # SIL DO ADV(NBTL, TERM, NBTL); BTL := COMP(TERM, BTL); ROW := COMP(RNINT(0), ROW); END; (* of while *) POS := INV(POS); NMAT := INV(MAT); MAT := SIL; WHILE NMAT # SIL DO ADV(NMAT, NROW, NMAT); FOR I := 1 TO LENGTH(POS) DO NROW := LEINST(NROW, LELT(POS,I), 0); END; (* of for *) MAT := COMP(NROW, MAT); END; (* of while *) SUM := RNINT(0); FOR I := 1 TO LENGTH(ROW) DO SUM := RNSUM(SUM, LELT(ROW,I)); END; (* of for *) IF RNSIGN(SUM) # 0 THEN MAT := COMP(ROW, MAT); ELSE IF FLAG THEN PAIRS := RED(PAIRS); END; END; (* of if *) END; (* of while *) END; (* of while *) XLS := SIL; IF MAT # SIL THEN BLINES(0); SWRITE("C/R = "); OWRITE(LENGTH(MAT)); SWRITE("/"); OWRITE(LENGTH(FIRST(MAT))); FOR I := 1 TO LENGTH(FIRST(MAT))-1 DO RS := COMP(RNINT(0), RS); END; RS := COMP(RNINT(1), RS); MAT := MTRANS(MAT); RNMGELUD(MAT, LOWER, UPPER); XLS := RNMSDS(LOWER, UPPER, RS); SWRITE(" XLS = "); OWRITE(XLS); END; (* of if *) (*-------------------------------------------------------------------------*) (* return ORBIT without reduction *) (*-------------------------------------------------------------------------*) IF XLS = SIL THEN EXTRACT(PG, 0, 0, ORBIT, BASE, POL); RETURN; END; OMEGA := ORBIT; WHILE XLS # SIL DO ADV(XLS, XHK, XLS); ADV(PAIRS, PBASE, PAIRS); IF XHK # 0 THEN IF LENGTH(PBASE) = 1 THEN PPOL := DIPFMO(RNINT(1), LIST1(2)); ELSE PPOL := DIPFMO(RNINT(1), COMP(1, LIST1(1))); END; PPOL := DIRPRP(PPOL, XHK); OMEGA := DIRPDF(OMEGA, GRNCHK(PG, PBASE, PPOL)); MERGE(0, PBASE, PPOL, BASE, POL); END; (* of if *) END; (* of while *) EXTRACT(PG, 0, 0, OMEGA, PBASE, PPOL); MERGE(0, PBASE, PPOL, BASE, POL); GRNCHKBAS(BASE, POL); END REDUCE; PROCEDURE GRNRED(PG, POL: LIST; VAR BASE, BASE_POL, REM_POL: LIST); VAR HK, HT, HM, ORBIT, BASE_1, BASE_POL_1, DUMMY: LIST; I: GAMMAINT; BEGIN BASE := SIL; BASE_POL := SIL; REM_POL := 0; IF POL = 0 THEN RETURN; END; WHILE POL # 0 DO DIPMAD(POL, HK, HT, DUMMY); HM := DIPFMO(HK, HT); ORBIT := GRNORP(PG, HM); IF EQUAL(HT, FIRST(ORBIT)) = 1 THEN POL := DIRPDF(POL, ORBIT); EXTRACT(PG, 0, 0, ORBIT, BASE_1, BASE_POL_1); MERGE(0, BASE_1, BASE_POL_1, BASE, BASE_POL); ELSE POL := DIRPDF(POL, HM); REM_POL := DIRPSM(REM_POL, HM); END; (* of if *) END; (* of while *) I := 1; WHILE I <= LENGTH(BASE) DO BLINES(0); SWRITE("GRNRED working... (BASE) "); OWRITE(BASE); HM := LELT(BASE,I); ORBIT := GRNORP(PG, HM); REDUCE(PG, ORBIT, BASE_1, BASE_POL_1); HT := FIRST(HM); IF EQUAL(HT, FIRST(FIRST(BASE_1))) = 1 THEN I := I + 1; ELSE MERGE(I, BASE_1, BASE_POL_1, BASE, BASE_POL); END; (* of if *) END; (* of while *) GRNCHKBAS(BASE, BASE_POL); BLINES(1); SWRITE("GRNRED exit (BASE): "); OWRITE(BASE); BLINES(0); SWRITE("GRNRED exit (BASE_POL): "); OWRITE(BASE_POL); BLINES(0); SWRITE("GRNRED exit (REM_POL): "); OWRITE(REM_POL); END GRNRED; PROCEDURE GRNBAS(PG: LIST): LIST; VAR BASE, XBASE, SPG, ORBIT_SPG, ORBIT_PG, POL, TERM, HK, HT: LIST; I, N, MAX, NR1, NR2: GAMMAINT; BEGIN NR1 := 0; NR2 := 0; XBASE := 0; BASE := SIL; IF PG = SIL THEN RETURN(BASE); END; N := LENGTH(FIRST(PG)); SPG := GSYSPG(N); IF N <= 2 THEN MAX := 1; END; IF N > 2 THEN MAX := N - 1; END; TERM := SIL; FOR I := 1 TO N DO TERM := COMP(0, TERM); END; LOOP TERM := GSYADD(TERM); IF FIRST(TERM) > MAX THEN EXIT; END; (* of if *) ORBIT_SPG := GRNORP(SPG, DIPFMO(RNINT(1), TERM)); WHILE ORBIT_SPG # 0 DO NR1 := NR1 + 1; HT := FIRST(ORBIT_SPG); ORBIT_PG := GRNORP(PG, DIPFMO(RNINT(1), HT)); ORBIT_SPG := DIRPDF(ORBIT_SPG, ORBIT_PG); REDUCE(PG, ORBIT_PG, BASE, POL); IF EQUAL(HT, FIRST(FIRST(BASE))) = 1 THEN NR2 := NR2 + 1; BLINES(0); SWRITE("GRNBAS working... (Term "); OWRITE(NR1); SWRITE("/"); OWRITE(NR2); SWRITE("): "); OWRITE(HT); XBASE := DIRPSM(XBASE, DIPFMO(RNINT(1), HT)); END; (* of if *) END; (* of while *); END; (* of loop *) BASE := SIL; IF XBASE = 0 THEN XBASE := SIL; END; WHILE XBASE # SIL DO DIPMAD(XBASE, HK, HT, XBASE); BASE := COMP(DIPFMO(RNINT(1), HT), BASE); END; (* of while *) BLINES(1); SWRITE("GRNBAS exit (BASE): "); OWRITE(BASE); BLINES(0); SWRITE("Number of special polynomials: ");OWRITE(NR1); BLINES(0); SWRITE("Number of base polynomials: ");OWRITE(NR2); RETURN(BASE); END GRNBAS; PROCEDURE GRNGGB(PG: LIST): LIST; VAR BASE, GB, SPG, ORBIT_SPG, ORBIT_PG, TERM, POL, HT, XX: LIST; I, N, MAX, NR1, NR2: GAMMAINT; BEGIN NR1 := 0; NR2 := 0; GB := SIL; BASE := SIL; IF PG = SIL THEN RETURN(BASE); END; N := LENGTH(FIRST(PG)); SPG := GSYSPG(N); IF N <= 2 THEN MAX := 1; END; IF N > 2 THEN MAX := N - 1; END; TERM := SIL; FOR I := 1 TO N DO TERM := COMP(0, TERM); END; LOOP TERM := GSYADD(TERM); IF FIRST(TERM) > MAX THEN EXIT; END; (* of if *) ORBIT_SPG := GRNORP(SPG, DIPFMO(RNINT(1), TERM)); XX := SIL; WHILE ORBIT_SPG # 0 DO ORBIT_PG := GRNORP(PG, DIPFMO(RNINT(1), FIRST(ORBIT_SPG))); ORBIT_SPG := DIRPDF(ORBIT_SPG, ORBIT_PG); XX := COMP(ORBIT_PG, XX); END; (* of while *) WHILE XX # SIL DO NR1 := NR1 + 1; ADV(XX, ORBIT_PG, XX); HT := FIRST(ORBIT_PG); POL := DIRPNF(GB, ORBIT_PG); IF POL # 0 THEN NR2 := NR2 + 1; BLINES(0); SWRITE("GRNGGB working... (Term "); OWRITE(NR1); SWRITE("/"); OWRITE(NR2); SWRITE("): "); OWRITE(HT); BASE := COMP(DIPFMO(RNINT(1), HT), BASE); GB := DIRGBA(POL, GB, 0); END; (* of if *) END; (* of while *); END; (* of loop *) BASE := INV(BASE); BLINES(1); SWRITE("GRNGGB exit (BASE): "); OWRITE(BASE); BLINES(0); SWRITE("Number of special polynomials: ");OWRITE(NR1); BLINES(0); SWRITE("Number of base polynomials: ");OWRITE(NR2); RETURN(BASE); END GRNGGB; END GSYMFURN. (* -EOF- *)