|
##############################################################################
##
#W idrels.gi IdRel Package Chris Wensley
#W & Anne Heyworth
## Implementation file for functions of the IdRel package.
##
#Y Copyright (C) 1999-2025 Anne Heyworth and Chris Wensley
##
## This file contains generic methods for identities among relators
############################################*##################*##############
##
#M LogSequenceLessThan
##
InstallMethod( LogSequenceLessThan, "for two grp rel sequences",
true, [ IsList, IsList ], 0,
function( y, z )
if ( Length( y ) < Length( z ) ) then
return true;
elif ( Length( y ) > Length( z ) ) then
return false;
else
return ( y < z );
fi;
end );
##############################################################################
##
#M ModuleRelatorSequenceReduce
##
InstallMethod( ModuleRelatorSequenceReduce, "generic method for a Ysequence",
true, [ IsList ], 0,
function( y )
local k, leny, w, found;
leny := Length( y );
k := 1;
## remove consecutive terms when one is the inverse of the other
while ( k < leny ) do
if ( ( y[k][1] = y[k+1][1]^(-1) ) and ( y[k][2] = y[k+1][2] ) ) then
y := Concatenation( y{[1..k-1]}, y{[k+2..leny]} );
k := k - 2;
leny := leny - 2;
if ( ( k = -1 ) and ( leny > 0 ) ) then
k := 0;
fi;
fi;
k := k + 1;
od;
## remove first and last terms when one is the inverse of the other
found := true;
while found do
found := false;
if ( ( leny > 1 ) and ( y[1][1] = - y[leny][1] )
and ( y[1][2] = y[leny][2] ) ) then
y := y{[2..leny-1]};
leny := leny - 2;
found := true;
fi;
od;
return y;
end );
##############################################################################
##
#M YSequenceConjugateAndReduce
##
InstallMethod( YSequenceConjugateAndReduce, "generic method for a Ysequence",
true, [ IsList, IsHomogeneousList ], 0,
function( y, rws )
local k, leny, w;
leny := Length( y );
if ( leny > 0 ) then
w := y[1][2]^(-1);
y := List( y, c -> [ c[1], ReduceWordKB( c[2]*w, rws ) ] );
fi;
return y;
end );
##############################################################################
##
#M ConvertToGroupRelatorSequences
##
## this operation takes a list of monoid relator sequences mseq for the
## group G which involve numbers for the relators and monoid conjugating
## words and replaces them with the relators and conjugating words in G
##
InstallMethod( ConvertToGroupRelatorSequences,
"generic method for an fp-group and a monoid relator sequence", true,
[ IsFpGroup, IsHomogeneousList ], 0,
function( G, mseq )
local monG, mu, fmG, gfmG, ngfmG, numgen2, F, genF, idF, freerels,
FR, genFR, omega, len, gseq, i, s0, s1, s2, s3, s4, leni,
t, t1, rt, wt, z, z1, z2;
monG := MonoidPresentationFpGroup( G );
mu := HomomorphismOfPresentation( monG );
fmG := FreeGroupOfPresentation( monG );
gfmG := GeneratorsOfGroup( fmG );
ngfmG := Length( gfmG );
F := FreeGroupOfFpGroup( G );
genF := GeneratorsOfGroup( F );
idF := One( F );
freerels := RelatorsOfFpGroup( G );
FR := FreeRelatorGroup( G );
genFR := GeneratorsOfGroup( FR );
omega := GroupHomomorphismByImages( FR, F, genFR, freerels );
len := Length( mseq );
gseq := ListWithIdenticalEntries( len, 0 );
for i in [1..len] do
s0 := mseq[i];
s1 := ShallowCopy( s0[2] );
s2 := ShallowCopy( s0[2] );
leni := Length( s1 );
for t in [1..leni] do
t1 := s1[t][1];
if ( t1 > 0 ) then
rt := genFR[ t1 - ngfmG ];
else
rt := genFR[ - t1 - ngfmG ]^-1;
fi;
wt := Image( mu, s1[t][2] );
s2[t] := [ rt, wt ];
od;
s3 := ModuleRelatorSequenceReduce( s2 );
## check that this really is an identity
leni := Length( s3 );
if ( leni > 0 ) then
s4 := ShallowCopy( s3 );
for t in [1..Length(s4)] do
z := s4[t];
z1 := Image( omega, z[1] );
z2 := z[2];
s4[t] := z1^z2;
od;
if not( Product( s4 ) = idF ) then
Print( "s0 = ", s0, "\n" );
Print( "s1 = ", s1, "\n" );
Print( "s2 = ", s2, "\n" );
Print( "s3 = ", s3, "\n" );
Print( "s4 = ", s4, "\n" );
Error( "supposed identity fails to reduce to idF" );
fi;
fi;
gseq[i] := [ s0[1], s3 ];
od;
return gseq;
end );
##############################################################################
##
#M IdentityRelatorSequences
##
InstallMethod( IdentityRelatorSequences, "generic method for an fp-group",
true, [ IsFpGroup ], 0,
function( G )
local genG, mG, haslabs, Glabs, amg, fmG, gfmG, id, igfmG, invrels,
invrules, ninvrules, grprels, mu, genpos, logrws, rws, F, genF,
idF, numgenF, genrangeF, g, k, gfmGpos, freerels, numrel, relrange,
FR, genFR, idR, omega, uptolen, words, fam, iwords, numelts,
edgesT, mseq, e, elt, rho, numa, ide, r, lenr, edgelist,
edge, w, lw, v, posv, inv, lenv, j, numids, rules;
genG := GeneratorsOfGroup( G );
mG := MonoidPresentationFpGroup( G );
haslabs := HasMonoidPresentationLabels( mG );
if haslabs then
Glabs := MonoidPresentationLabels( mG );
else
Glabs := [ ];
fi;
amg := ArrangementOfMonoidGenerators( G );
fmG := FreeGroupOfPresentation( mG );
gfmG := GeneratorsOfGroup( fmG );
igfmG := InverseGeneratorsOfFpGroup( fmG );
id := One( fmG );
invrels := InverseRelatorsOfPresentation( mG );
invrules := InverseRulesOfPresentation( mG );
ninvrules := Length( invrules );
grprels := GroupRelatorsOfPresentation( mG );
mu := HomomorphismOfPresentation( mG );
genpos := MonoidGeneratorsFpGroup( G );
logrws := LoggedRewritingSystemFpGroup( G );
rws := List( logrws, r -> [ r[1], r[3] ] );
if ( InfoLevel( InfoIdRel ) >= 2 ) then
Print( "logrws = \n" );
Display( logrws );
Print( "\nrws = \n" );
Display( rws );
Print( "\n" );
fi;
F := FreeGroupOfFpGroup( G );
genF := GeneratorsOfGroup( F );
idF := One( F );
numgenF := Length( genF );
genrangeF := [1..numgenF];
gfmGpos := gfmG{ genrangeF };
freerels := RelatorsOfFpGroup( G );
numrel := Length( freerels );
relrange := [1..numrel];
FR := FreeRelatorGroup( G );
idR := One( FR );
genFR := GeneratorsOfGroup( FR );
omega := GroupHomomorphismByImages( FR, F, genFR, freerels );
if ( InfoLevel( InfoIdRel ) > 1 ) then
Print( "\nhom from FR to F is: \n", omega, "\n\n" );
fi;
## construct the first few elements in the group
uptolen := 2; ###################### temporary value
if ( HasPartialElements( G ) and
( PartialElementsLength( G ) >= uptolen ) ) then
words := PartialElements( G );
uptolen := PartialElementsLength( G );
else
words := PartialElementsOfMonoidPresentation( G, uptolen );
fi;
fam := FamilyObj( words[1] );
iwords := PartialInverseElements( G );
words := List( words, w -> ReduceWordKB( w, invrules ) );
iwords := List( iwords, w -> ReduceWordKB( w, invrules ) );
if ( InfoLevel( InfoIdRel ) > 0 ) then
if haslabs then
Print( " words = " );
PrintLnUsingLabels( words, gfmG, Glabs );
Print( "iwords = " );
PrintLnUsingLabels( iwords, gfmG, Glabs );
else
Print( "words = ", words, "\niwords = ", iwords, "\n" );
fi;
fi;
numelts := Length( words );
edgesT := GenerationTree( G );
rules := LogSequenceRewriteRules( mG );
mseq := ShallowCopy( RootIdentities( G ) );
Info( InfoIdRel, 2, "initial mseq:\n", mseq );
## now work through the list of elements, adding each relator in turn
Info( InfoIdRel, 2, "adding relators at each element:" );
e := 1; ## number of monoid elements processed - no need to process id
while ( e < numelts ) do
e := e+1;
elt := words[e];
for rho in relrange do
numa := (e-1)*numrel + rho;
ide := [ ];
### cycle [g,r] (from vertex g and reading r along edges)
### is converted to a list of its component edges:
### [source vertex, edge label] (some may be inverse edges)
r := grprels[rho];
lenr := Length( r );
edgelist := ListWithIdenticalEntries( lenr, 0 );
edgelist[1] := [ elt, Subword(r,1,1) ];
### Edges of the cycle which are in the tree are removed,
### and the rest are represented by their position in the
### list of alpha edges.
for k in [1..lenr] do
edge := edgelist[k];
w := Product( edge );
lw := LoggedReduceWordKB( w, logrws );
v := lw[2]; ## the new vertex
posv := Position( words, v );
if ( v = w ) then ## no reduction
if ( posv = fail ) then ## v=w is not yet in the tree
Add( words, v );
inv := InverseWordInFreeGroupOfPresentation( fmG, v );
Add( iwords, inv );
Add( edgesT, edge );
j := Position( gfmG, edge[2] );
Add( edgesT, [ v, iwords[j] ] );
fi;
else ## v<>w, so there is some logging to include in the ide
if ( posv = fail ) then
Add( words, v );
inv := InverseWordInFreeGroupOfPresentation( fmG, v );
Add( iwords, inv );
lenv := Length( v );
g := Subword( v, lenv, lenv );
Add( edgesT, [ Subword( v, 1, lenv-1 ), g ] );
j := Position( gfmG, g );
Add( edgesT, [ v, iwords[j] ] );
fi;
Append( ide, lw[1] );
fi;
if ( k < lenr ) then
edgelist[k+1] := [ v, Subword(r,k+1,k+1) ];
else
if not ( v = elt ) then
Error( "v <> elt" );
fi;
fi;
od;
Add( ide, [ - rho, iwords[e] ] );
for k in [1..Length(ide)] do
ide[k][2] := ReduceWordKB( ide[k][2], invrules );
od;
ide := LogSequenceReduce( mG, ide );
Assert( 0, ExpandLogSequence( mG, ide ) = id );
if ( ide <> [ ] ) then
posv := Position( mseq, ide );
if ( posv = fail ) then
Info( InfoIdRel, 2, "[numa,elt,rho,ide] = ",
[numa,elt,rho,ide] );
Add( mseq, ide );
fi;
fi;
od;
od;
Info( InfoIdRel, 1, "mseq has length: ", Length(mseq) );
if ( InfoLevel( InfoIdRel ) > 1 ) then
Print( "mseq prior to being sorted:\n" );
for k in [1..Length(mseq)] do
if haslabs then
PrintLnUsingLabels( mseq[k], gfmG, Glabs );
else
Print( mseq[k], "\n" );
fi;
od;
Info( InfoIdRel, 2, "-----------------------------------------" );
fi;
Sort( mseq, LogSequenceLessThan );
return mseq;
end );
##############################################################################
##
#M ExpandLogSequence
#M MoveLeftLogSequence
#M MoveRightLogSequence
#M SwapLogSequence
##
## permute the entries in J according to the cycle (p,p+1,...,q)
## (conjugating intermediate terms) so as to bring J[q] adjacent to J[p-1]
## swap J[p] with J[p+1]
##
InstallMethod( ExpandLogSequence,
"for an fp-group presentation and an identity sequence", true,
[ IsMonoidPresentationFpGroup, IsHomogeneousList ], 0,
function( mG, J )
local fmG, gfmG, invrels, ninvrels, invrules, ninvrules, gprels,
len, id, w, i, m, u, r;
fmG := FreeGroupOfPresentation( mG );
gfmG := GeneratorsOfGroup( fmG );
invrels := InverseRelatorsOfPresentation( mG );
ninvrels := Length( invrels );
invrules := InverseRulesOfPresentation( mG );
ninvrules := Length( invrules );
gprels := GroupRelatorsOfPresentation( mG );
len := Length( J );
id := One( fmG );
w := id;
for i in [1..len] do
m := J[i][1];
u := J[i][2];
if ( m > 0 ) then
r := gprels[m];
else
r := gprels[-m]^-1;
fi;
w := w * u^-1 * r * u;
w := ReduceWordKB( w, invrules );
od;
return w;
end );
InstallMethod( MoveLeftLogSequence,
"for an fp-group presentation and an identity sequence", true,
[ IsMonoidPresentationFpGroup, IsHomogeneousList, IsList, IsPosInt ], 0,
function( mG, S, L, q )
local J, invrules, invnum, gpwords, lenJ, lenL, p, r,
Y, m, x, u, y, K, i, n, v, w, H, rules;
J := ShallowCopy( S );
invrules := InverseRulesOfPresentation( mG );
invnum := Length( invrules );
gpwords := GroupRelatorsOfPresentation( mG );
lenJ := Length( J );
if not IsRange( L ) then
Error( "L is not a range" );
fi;
lenL := Length( L );
p := L[1];
r := L[lenL];
if not ( L = [p..r] ) then
Error( "incorrect range" );
fi;
if not (0<q) and (q<p) and (r<=lenJ) then
Error( "require 0 < q < p < r <= lenJ" );
fi;
Y := [p..r];
for i in [p..r] do
u := ConjugatingWordOfLoggedTerm( mG, J[i] );
Y[i-p+1] := ReduceWordKB( u, invrules );
od;
y := Product( Y );
y := ReduceWordKB( y, invrules );
K := J{[q..p-1]};
for i in [1..p-q] do
n := K[i][1];
v := K[i][2];
w := ReduceWordKB( v*y, invrules );
K[i] := [ n, w ];
od;
H := Concatenation( J{[1..q-1]}, J{[p..r]}, K, J{[r+1..lenJ]} );
Info( InfoIdRel, 2, "result of MoveLeftLogSequence:" );
Info( InfoIdRel, 2, "H = ", H );
rules := LogSequenceRewriteRules( mG );
return OnePassReduceLogSequence( H, rules );
end );
InstallMethod( MoveRightLogSequence,
"for an fp-group presentation and an identity sequence", true,
[ IsMonoidPresentationFpGroup, IsHomogeneousList, IsList, IsPosInt ], 0,
function( mG, S, L, q )
local J, invrules, invnum, gpwords, lenJ, lenL, p, r,
Y, m, x, u, y, K, i, n, v, w, H, rules;
J := ShallowCopy( S );
invrules := InverseRulesOfPresentation( mG );
invnum := Length( invrules );
gpwords := GroupRelatorsOfPresentation( mG );
lenJ := Length( J );
if not IsRange( L ) then
Error( "L is not a range" );
fi;
lenL := Length( L );
p := L[1];
r := L[lenL];
if not ( L = [p..r] ) then
Error( "incorrect range" );
fi;
if not (0<p) and (p<q) and (q+r-p <= lenJ) then
Error( "require 0 < p < q and q+r-p <= lenJ" );
fi;
Y := [p..r];
for i in [p..r] do
u := ConjugatingWordOfLoggedTerm( mG, J[i] );
Y[i-p+1] := ReduceWordKB( u^-1, invrules );
od;
y := Product( Y );
y := ReduceWordKB( y, invrules );
K := J{[r+1..q]};
for i in [1..q-r] do
n := K[i][1];
v := K[i][2];
w := ReduceWordKB( v*y, invrules );
K[i] := [ n, w ];
od;
H := Concatenation( J{[1..p-1]}, K, J{[p..r]}, J{[q+1..lenJ]} );
rules := LogSequenceRewriteRules( mG );
return OnePassReduceLogSequence( H, rules );
end );
InstallMethod( SwapLogSequence,
"for an fp-group presentation and an identity sequence", true,
[ IsMonoidPresentationFpGroup, IsHomogeneousList, IsPosInt, IsPosInt ], 0,
function( mG, S, p, q )
local J, lenJ, lt, rt, L;
J := ShallowCopy( S );
lenJ := Length( J );
if not (0<p) and (p<q) and (q <= lenJ) then
Error( "require 1 <= p < q <= lenJ" );
fi;
L := MoveRightLogSequence( mG, J, [p], q );
if ( q-p > 1 ) then
L := MoveLeftLogSequence( mG, L, [q-1], p );
fi;
return L;
end );
##############################################################################
##
#M ConjugateByWordLogSequence
##
InstallMethod( ConjugateByWordLogSequence,
"for an fp-group presentation, an identity sequence, and a word", true,
[ IsMonoidPresentationFpGroup, IsHomogeneousList, IsWord ], 0,
function( mG, J, w )
local invrules, idrules, K, lenK, c, k, j, v;
invrules := InverseRulesOfPresentation( mG );
idrules := LogSequenceRewriteRules( mG );
K := ShallowCopy( J );
lenK := Length( K );
for j in [1..lenK] do
c := ShallowCopy( K[j] );
v := ReduceWordKB( c[2]*w, invrules );
K[j] := [ c[1], v ];
od;
return OnePassReduceLogSequence( K, idrules );
end );
InstallMethod( FixFirstTermLogSequence,
"for an fp-group presentation and an identity sequence", true,
[ IsMonoidPresentationFpGroup, IsHomogeneousList ], 0,
function( mG, J )
## make sure each identity starts with [\rho,id]
local fmG, id, invrules, idrules, G, roots, lenJ, w, H, j, v, c;
fmG := FreeGroupOfPresentation( mG );
id := One( fmG );
invrules := InverseRulesOfPresentation( mG );
idrules := LogSequenceRewriteRules( mG );
G := UnderlyingGroupOfPresentation( mG );
roots := RootIdentities( G );
lenJ := Length( J );
w := J[1][2];
H := ListWithIdenticalEntries( lenJ, 0 );
if ( w <> id ) then
w := ReduceWordKB( w^-1, invrules );
for j in [1..lenJ] do
v := ReduceWordKB( J[j][2]*w, invrules );
H[j] := [ J[j][1], v ];
od;
fi;
return OnePassReduceLogSequence( H, idrules );
end );
InstallMethod( ChangeStartLogSequence,
"for an fp-group presentation and an identity sequence", true,
[ IsMonoidPresentationFpGroup, IsHomogeneousList, IsPosInt ], 0,
function( mG, J, p )
## make the p-th entry the first entry
local K, lenK, L, R, H;
K := ShallowCopy( J );
lenK := Length( K );
if ( p < 2 ) or ( p > lenK ) then
Error( "choose p in [2..lenK]" );
fi;
L := K{[p..lenK]};
R := K{[1..p-1]};
H := Concatenation( L, R );
return H;
end );
InstallMethod( InverseLogSequence,
"for an identity sequence", true, [ IsHomogeneousList ], 0,
function( S )
local J, lenJ, H, j, k;
J := ShallowCopy( S );
lenJ := Length( J );
H := ListWithIdenticalEntries( lenJ, 0 );
for j in [1..lenJ] do
k := lenJ - j + 1;
H[j] := [ - J[k][1], J[k][2] ];
od;
return H;
end );
InstallMethod( ConjugatingWordOfLoggedTerm,
"for an fp-group presentation and a term in a sequence", true,
[ IsMonoidPresentationFpGroup, IsList ], 0,
function( mG, t )
local invrules, invnum, gpwords, lenJ, lenL, p, r,
Y, m, x, u, y, K, i, n, v, w;
invrules := InverseRulesOfPresentation( mG );
invnum := Length( invrules );
gpwords := GroupRelatorsOfPresentation( mG );
m := t[1];
if ( m > 0 ) then
x := gpwords[m];
else
x := gpwords[-m]^(-1);
fi;
u := t[2];
return ReduceWordKB( x^u, invrules );
end );
##############################################################################
##
#M CancelInversesLogSequence
#M CancelImmediateInversesLogSequence
##
InstallMethod( CancelImmediateInversesLogSequence,
"for an fp-group presentation and an identity sequence", true,
[ IsHomogeneousList ], 0,
function( J )
local K, lenK, H, changed, j, t, k, u, c;
K := ShallowCopy( J );
lenK := Length( K );
changed := false;
j := 0;
while ( j < lenK-1 ) do
j := j+1;
t := K[j];
u := K[j+1];
if ( ( t[1] = -u[1] ) and ( t[2] = u[2] ) ) then
K := Concatenation( K{[1..j-1]}, K{[j+2..lenK]} );
lenK := lenK - 2;
if ( j > 1 ) then
j := j-2;
fi;
changed := true;
fi;
od;
if changed then
Info( InfoIdRel, 2, "changes made by cancelinverses" );
fi;
return K;
end );
InstallMethod( CancelInversesLogSequence,
"for an fp-group presentation and an identity sequence", true,
[ IsMonoidPresentationFpGroup, IsHomogeneousList ], 0,
function( mG, J )
local K, lenK, changed, j, t, k, u, H;
K := ShallowCopy( J );
## now check for occurrences of: [-p,w] ... [p,w]
changed := true;
while changed and ( K <> [ ] ) do
changed := false;
lenK := Length( K );
j := 0;
while ( j < lenK - 1 ) and ( not changed ) do
j := j+1;
k := 0;
while ( k < lenK - j ) and ( not changed ) do
k := k+1;
t := K[k];
u := K[k+j];
if ( ( t[1] = -u[1] ) and ( t[2] = u[2] ) ) then
H := MoveLeftLogSequence( mG, K, [k+j], k+1 );
K := Concatenation( H{[1..k-1]}, H{[k+2..lenK]} );
changed := true;
fi;
od;
od;
od;
if changed then
Info( InfoIdRel, 2, "changes made by cancelinverses to" );
Info( InfoIdRel, 2, " J = ", J );
Info( InfoIdRel, 2, " --> K = ", K );
fi;
return K;
end );
##############################################################################
##
#M AreEquivalentIdentities
##
InstallMethod( AreEquivalentIdentities,
"for an fp-group and two relator sequences", true,
[ IsFpGroup, IsHomogeneousList, IsHomogeneousList ], 0,
function( G, L1, L2 )
local mG, fmG, gfmG, Glabs, J1, J2, rules, len, R1, R2, found,
i, j, p1, k, p2, K1, K2;
mG := MonoidPresentationFpGroup( G );
fmG := FreeGroupOfPresentation( mG );
gfmG := GeneratorsOfGroup( fmG );
if not HasMonoidPresentationLabels( mG ) then
Glabs := [ ];
else
Glabs := MonoidPresentationLabels( mG );
fi;
rules := LogSequenceRewriteRules( mG );
J1 := ShallowCopy( L1 );
J2 := ShallowCopy( L2 );
if ( J1 = J2 ) then
return true;
fi;
len := Length( J1 );
if not ( Length( J2 ) = len ) then
return false;
fi;
R1 := Set( List( J1, p -> p[1] ) );
R2 := Set( List( J2, p -> p[1] ) );
if not ( R1 = R2 ) then
return false;
fi;
found := false;
i := 0;
while ( ( J1[i+1] = J2[i+1] ) and ( i < len ) ) do
i := i+1;
od;
while ( i<len ) do
i := i+1;
j := i-1;
while ( ( not found ) and ( j < len ) ) do
j := j+1;
p1 := J1[j];
k := i-1;
while ( ( not found ) and ( k < len ) ) do
k := k+1;
p2 := J2[k];
if ( p1 = p2 ) then
K1 := MoveLeftLogSequence( mG, J1, [j], i );
J1 := OnePassReduceLogSequence( [K1], rules )[1];
K2 := MoveLeftLogSequence( mG, J2, [k], i );
J2 := OnePassReduceLogSequence( [K2], rules )[1];
if ( InfoLevel( InfoIdRel ) > 1 ) then
Print( "revised J1 and J2:\n" );
PrintLnUsingLabels( J1, gfmG, Glabs );
PrintLnUsingLabels( J2, gfmG, Glabs );
fi;
found := true;
if ( J1 = J2 ) then
return true;
fi;
fi;
od;
od;
found := false;
od;
return ( J1 = J2 );
end );
##############################################################################
##
#M LogSequenceRewriteRules
##
InstallMethod( LogSequenceRewriteRules,
"for an fp-group presentation", true, [ IsMonoidPresentationFpGroup ], 0,
function( mG )
local G, fmG, gfmG, igfmG, id, invrules, len, roots, numroots, rewrites,
i, root, n, w, v, rule, p, x, y, rels, nrels, irels, rpos, r, ir;
G := UnderlyingGroupOfPresentation( mG );
fmG := FreeGroupOfPresentation( mG );
gfmG := GeneratorsOfGroup( fmG );
igfmG := InverseGeneratorsOfFpGroup( fmG );
id := One( fmG );
invrules := InverseRulesOfPresentation( mG );
len := Length( InverseRulesOfPresentation( mG ) );
roots := RootIdentities( G );
numroots := Length( roots );
rewrites := [ ];
for i in [1..numroots] do
root := roots[i];
n := root[2][1];
w := root[2][2];
if not ( ( root[1][1] = -n ) and ( root[1][2] = id ) ) then
Error( "unexpected root" );
fi;
rule := [ [ n, w ], [ n, id ] ];
p := Position( rewrites, rule );
if ( p = fail ) then
Add( rewrites, rule );
fi;
rule := [ [ -n, w ], [ -n, id ] ];
p := Position( rewrites, rule );
if ( p = fail ) then
Add( rewrites, rule );
fi;
v := ReduceWordKB( w^-1, invrules );
rule := [ [ n, v ], [ n, id ] ];
p := Position( rewrites, rule );
if ( p = fail ) then
Add( rewrites, rule );
fi;
rule := [ [ -n, v ], [ -n, id ] ];
p := Position( rewrites, rule );
if ( p = fail ) then
Add( rewrites, rule );
fi;
if ( Length( w ) = 2 ) then
x := Subword( w, 1, 1 );
y := Subword( w, 2, 2 );
p := Position( gfmG, y );
y := igfmG[ p ];
if ( x > y ) then
rule := [ [ n, x ], [ n, y ] ];
else
rule := [ [ n, y ], [ n, x ] ];
fi;
p := Position( rewrites, rule );
if ( p = fail ) then
Add( rewrites, rule );
fi;
if ( x > y ) then
rule := [ [ -n, x ], [ -n, y ] ];
else
rule := [ [ -n, y ], [ -n, x ] ];
fi;
p := Position( rewrites, rule );
if ( p = fail ) then
Add( rewrites, rule );
fi;
fi;
od;
Info( InfoIdRel, 2, "rewrites from root identities:\n", rewrites );
## now add rules from relators which are not roots
rels := GroupRelatorsOfPresentation( mG );
nrels := Length( rels );
irels := List( rels, r -> ReduceWordKB( r^-1, invrules ) );
rpos := RootPositions( G );
for n in [1..nrels] do
if not rpos[n] then
r := rels[n];
ir := irels[n];
Add( rewrites, [ [ n, r ], [ n, id ] ] );
Add( rewrites, [ [ n, ir ], [ n, id ] ] );
Add( rewrites, [ [ -n, r ], [ -n, id ] ] );
Add( rewrites, [ [ -n, ir ], [ -n, id ] ] );
fi;
od;
return rewrites;
end );
##############################################################################
##
#M OnePassReduceLogSequence
##
InstallMethod( OnePassReduceLogSequence,
"for an identity and a list of sequence rewrite rules", true,
[ IsHomogeneousList, IsHomogeneousList ], 0,
function( J, rules )
local idi, leni, j, u, m, w, lenw, found, rule, x, lenx;
## apply rewrite rules to the sequence J
idi := ShallowCopy( J );
leni := Length( idi );
for j in [1..leni] do
u := idi[j];
m := u[1];
w := u[2];
lenw := Length( w );
found := true;
while found do
found := false;
for rule in rules do
if ( rule[1][1] = m ) then
x := rule[1][2];
lenx := Length( x );
if ( ( lenx <= lenw ) and
( Subword( w, 1, lenx ) = x ) ) then
w := rule[2][2] * Subword( w, lenx+1, lenw );
lenw := Length( w );
idi[j] := [ m, w ];
Info( InfoIdRel, 2, "u -> v where u = ",
u, " and v = ", [m,w] );
Info( InfoIdRel, 2, " J = ", J );
Info( InfoIdRel, 2, "rule = ", rule );
found := true;
fi;
fi;
od;
od;
od;
return idi;
end );
##############################################################################
##
#M SubstituteLogSubsequence
##
InstallMethod( SubstituteLogSubsequence,
"for three log sequences", true, [ IsMonoidPresentationFpGroup,
IsHomogeneousList, IsHomogeneousList, IsHomogeneousList ], 0,
function( mG, K, J1, J2 )
local lenK, len1, pos, H, rules;
lenK := Length( K );
len1 := Length( J1 );
pos := PositionSublist( K, J1 );
if ( pos = fail ) then
return fail;
fi;
H := Concatenation( K{[1..pos-1]}, J2, K{[pos+len1..lenK]} );
rules := LogSequenceRewriteRules( mG );
return OnePassReduceLogSequence( H, rules );
end );
##############################################################################
##
#M ReduceLogSequences
##
InstallMethod( ReduceLogSequences,
"for an fp-group and a list of Ysequences", true,
[ IsFpGroup, IsHomogeneousList ], 0,
function( G, L )
local startwithid, findconjugates, removeempties, info,
mG, fmG, gfmG, id, arr, invrules, invnum, gpwords, Glabs, roots,
L1, L2, L3, L4, lenL, idrules, idnum,
i, j, k, idj, idk, m, w;
startwithid := function( K )
## make sure each identity starts with [\rho,id]
local J, lenJ, k, idk, lenk, w, cidk, j, v;
J := ShallowCopy( K );
lenJ := Length( J );
for k in [1..lenJ] do
idk := ShallowCopy( J[k] );
lenk := Length( idk );
w := idk[1][2];
if ( w <> id ) then
w := ReduceWordKB( w^-1, invrules );
cidk := ListWithIdenticalEntries( lenk, 0 );
for j in [1..lenk] do
v := ReduceWordKB( idk[j][2]*w, invrules );
cidk[j] := [ idk[j][1], v ];
od;
J[k] := cidk;
fi;
od;
Sort( J, LogSequenceLessThan );
return J;
end;
findconjugates := function( J )
## search for conjugate of one identity lying within another
local K, lenK, i, idi, leni, rho, j, idj, lenj, k, w, c, ok;
K := ShallowCopy( J );
lenK := Length( K );
for i in [1..lenK] do
idi := K[i];
leni := Length( idi );
if ( leni > 0 ) then
rho := idi[1][1];
for j in [i+1..lenK] do
idj := K[j];
lenj := Length( idj );
k := 1;
while ( k <= (lenj-leni+1) ) do
if ( idj[k][1] = rho ) then
w := idj[k][2];
c := 1;
ok := true;
while ( ok and ( c < leni ) ) do
c := c+1;
if ([idi[c][1],idi[c][2]*w]<>idj[k+c-1]) then
ok := false;
fi;
od;
if ok then
idj := Concatenation( idj{[1..k-1]},
idj{[(k+leni)..lenj]} );
K[j] := idj;
Info( InfoIdRel, 1, "reduction (1) at [i,j] = ",
[i,j], ", L4[j] = ", idj );
lenj := lenj - leni;
k := k-1;
fi;
fi;
k := k+1;
od;
od;
idi := Reversed( List( idi, c -> [ - c[1], c[2] ] ) );
w := ReduceWordKB( idi[1][2]^(-1), invrules );
for j in [1..Length(idi)] do
idi[j][2] := ReduceWordKB( idi[j][2]*w, invrules );
od;
rho := idi[1][1];
for j in [i+1..lenK] do
idj := K[j];
lenj := Length( idj );
k := 1;
while ( k <= (lenj-leni+1) ) do
if ( idj[k][1] = rho ) then
w := idj[k][2];
c := 1;
ok := true;
while ( ok and ( c < leni ) ) do
c := c+1;
if ([idi[c][1],idi[c][2]*w]<>idj[k+c-1]) then
ok := false;
fi;
od;
if ok then
idj := Concatenation( idj{[1..k-1]},
idj{[(k+leni)..lenj]} );
K[j] := idj;
Info( InfoIdRel, 1, "reduction (2) at [i,j] = ",
[i,j], ", L4[j] = ", idj );
lenj := lenj - leni;
k := k-1;
fi;
fi;
k := k+1;
od;
od;
fi;
od;
return K;
end;
removeempties := function( J )
## remove all [ ]'s from J
local lenJ, M, N, K, i, lenK;
lenJ := Length( J );
M := List( J, L -> L = [ ] );
N := [ ];
for i in [1..lenJ] do
if not M[i] then
Add( N, i );
fi;
od;
K := Filtered( J, L -> L <> [ ] );
lenK := Length( K );
if ( lenJ <> lenK ) then
Info( InfoIdRel, 2, "in removeempties length reduced from ",
lenJ, " to ", lenK );
fi;
return K;
end;
#####################################################################
## function proper starts here
info := InfoLevel( InfoIdRel );
mG := MonoidPresentationFpGroup( G );
fmG := FreeGroupOfPresentation( mG );
gfmG := GeneratorsOfGroup( fmG );
## id := One( fmG );
id := One( FamilyObj( L[1][1][2] ) );
arr := ArrangementOfMonoidGenerators( G );
invrules := InverseRulesOfPresentation( mG );
invnum := Length( invrules );
gpwords := GroupRelatorsOfPresentation( mG );
if not HasMonoidPresentationLabels( mG ) then
Glabs := [ ];
else
Glabs := MonoidPresentationLabels( mG );
fi;
L4 := startwithid( L );
for j in [1..Length(L4)] do
idj := CancelInversesLogSequence( mG, L4[j] );
w := ExpandLogSequence( mG, idj );
Assert( 0, w = id );
L4[j] := idj;
od;
lenL := Length( L4 );
if ( info > 1 ) then
Print( "in ReduceLogSequences\n" );
Print( "after sorting L4 has length ", lenL, "\n" );
Print( List( L4, Length ), "\n" );
PrintLnUsingLabels( L4, gfmG, Glabs );
Print( "\ndetermining the rewrite rules\n" );
fi;
idrules := LogSequenceRewriteRules ( mG );
roots := RootIdentities( G );
idnum := Length( idrules );
if ( info > 1 ) then
Print( "there are ", Length(idrules), " rewrite rules:\n" );
PrintLnUsingLabels( idrules, gfmG, Glabs );
fi;
L1 := [ ];
while ( L1 <> L4 ) do
L1 := ShallowCopy ( L4 );
Info( InfoIdRel, 2, "running CancelInverses:");
L3 := List( L1, L -> CancelInversesLogSequence( mG, L ) );
for m in [1..Length(L3)] do
w := ExpandLogSequence( mG, L3[m] );
Assert( 0, w = id );
od;
if ( info > 1 ) then
Print( "L3 has length ", Length(L3), " :-\n" );
Print( List( L3, Length ), "\n" );
PrintLnUsingLabels( L3, gfmG, Glabs );
Print( "running removeempties:\n" );
fi;
L2 := removeempties( L3 );
for m in [1..Length(L2)] do
w := ExpandLogSequence( mG, L2[m] );
Assert( 0, w = id );
od;
if ( info > 1 ) then
Print( "L2 has length ", Length(L2), " :-\n" );
Print( List( L2, Length ), "\n" );
PrintLnUsingLabels( L2, gfmG, Glabs );
Print( "running findconjugates:\n" );
fi;
L3 := findconjugates( L2 );
for m in [1..Length(L3)] do
w := ExpandLogSequence( mG, L3[m] );
Assert( 0, w = id );
od;
if ( info > 1 ) then
Print( "L3 has length ", Length(L3), " :-\n" );
Print( List( L3, Length ), "\n" );
PrintLnUsingLabels( L3, gfmG, Glabs );
Print( "running removeempties:\n" );
fi;
L2 := removeempties( L3 );
for m in [1..Length(L2)] do
w := ExpandLogSequence( mG, L2[m] );
Assert( 0, w = id );
od;
if ( info > 1 ) then
Print( "L2 has length ", Length(L2), " :-\n" );
Print( List( L2, Length ), "\n" );
PrintLnUsingLabels( L2, gfmG, Glabs );
Print( "running startwithid:\n" );
fi;
L3 := startwithid( L2 );
for m in [1..Length(L3)] do
w := ExpandLogSequence( mG, L3[m] );
Assert( 0, w = id );
od;
if ( info > 1 ) then
Print( "L3 has length ", Length(L3), " :-\n" );
PrintLnUsingLabels( L3, gfmG, Glabs );
Print( "running OnePassReduceLogSequence:\n" );
fi;
lenL := Length( L3 );
for j in [1..lenL] do
idj := L3[j];
if not ( idj in roots ) then
L3[j] := OnePassReduceLogSequence( idj, idrules );
fi;
od;
for m in [1..Length(L3)] do
w := ExpandLogSequence( mG, L3[m] );
Assert( 0, w = id );
od;
L4 := ShallowCopy( L3 );
lenL := Length( L4 );
for j in [1..lenL] do
idj := L4[j];
if not ( idj in roots ) then
L4[j] := OnePassReduceLogSequence( idj, idrules );
fi;
od;
if ( info > 1 ) then
Print( "L4 has length ", lenL, " :-\n" );
Print( List( L4, Length ), "\n" );
PrintLnUsingLabels( L4, gfmG, Glabs );
fi;
od;
Sort( L4, LogSequenceLessThan );
## now test for equivalence
lenL := Length( L4 );
i := 1;
while ( ( Length( L4[i] ) = 2 ) and ( i <= lenL ) ) do
i := i+1;
od;
for j in [i..lenL] do
idj := L4[j];
if ( idj <> [ ] ) then
for k in [j+1..lenL] do
idk := L4[k];
if ( idk <> [ ] ) then
if AreEquivalentIdentities( G, idj, idk ) then
L4[k] := [ ];
fi;
fi;
od;
fi;
od;
Info( InfoIdRel, 2, "adjusted L4 = ", List( L4, Length ) );
if ( InfoLevel( InfoIdRel ) > 1 ) then
PrintLnUsingLabels( L4, gfmG, Glabs );
fi;
return removeempties( L4 );
end );
#############################################################################
##
#M ConvertToYSequences( <G> )
##
InstallMethod( ConvertToYSequences, "for an fp-group and group relator seq",
true, [ IsFpGroup, IsFreeGroup, IsHomogeneousList ], 0,
function( G, FY, iseq )
local mG, elmon, oneM, gprels, invrules, numinv, frgp, frgens, fmG, FMfam,
hom, L, FYgens, lrws, rws, numids, gseq, polys, k, j, pos, ident,
leni, irange, gp, npols, i, i1, w, hw, len, rp, nyp, yp, lp,
lbest;
mG := MonoidPresentationFpGroup( G );
if HasElementsOfMonoidPresentation( G ) then
elmon := ElementsOfMonoidPresentation( G );
elif HasPartialElements( G ) then
elmon := PartialElements( G );
elif ( HasIsFinite( G ) and IsFinite( G ) ) then
elmon := ElementsOfMonoidPresentation( G );
else
## using 3 as a suitable word length
elmon := PartialElementsOfMonoidPresentation( G, 3 );
fi;
oneM := elmon[1];
gprels := GroupRelatorsOfPresentation( mG );
invrules := InverseRulesOfPresentation( mG );
numinv := Length( invrules );
frgp := FreeRelatorGroup( G );
frgens := GeneratorsOfGroup( frgp );
fmG := FreeGroupOfPresentation( mG );
FMfam := ElementsFamily( FamilyObj( fmG ) );
lrws := LoggedRewritingSystemFpGroup( G );
rws := List( lrws, r -> [ r[1], r[3] ] );
hom := HomomorphismOfPresentation( mG );
L := ArrangementOfMonoidGenerators( G );
FYgens := GeneratorsOfGroup( FY );
numids := Length( iseq );
gseq := List( [1..numids], i -> [ i, iseq[i] ] );
polys := [ ];
k := 0;
for j in [1..numids] do
Info( InfoIdRel, 2, "=============== j = ", j, " ===============" );
pos := gseq[j][1];
ident := gseq[j][2];
Info( InfoIdRel, 2, "gseq[j] = ", gseq[j] );
leni := Length( ident );
if ( leni > 0 ) then
k := k+1;
Info( InfoIdRel, 2, "k = ", k );
irange := [1..leni];
gp := ListWithIdenticalEntries( leni, 0 );
npols := ListWithIdenticalEntries( leni, 0 );
for i in irange do
i1 := ident[i][1];
w := ImageElm( hom, ident[i][2] );
w := MonoidWordFpWord( w, FMfam, L );
w := ReduceWordKB( w, rws );
if ( i1 > 0 ) then
gp[i] := frgens[i1];
npols[i] := MonoidPolyFromCoeffsWords( [+1], [w] );
else
gp[i] := frgens[-i1]^(-1);
npols[i] := MonoidPolyFromCoeffsWords( [-1], [w] );
fi;
od;
Info( InfoIdRel, 2, "npols = ", npols );
rp := ModulePolyFromGensPolys( gp, npols );
Info( InfoIdRel, 2, "rp = ", rp );
len := Length( rp );
if not ( len = 0 ) then
nyp := MonoidPolyFromCoeffsWords( [ 1 ], [ oneM ] );
Info( InfoIdRel, 2, "nyp = ", nyp );
yp := ModulePolyFromGensPolys( [ FYgens[pos] ], [ nyp ] );
Info( InfoIdRel, 2, "yp = ", yp );
lp := LoggedModulePolyNC( yp, rp );
Info( InfoIdRel, 2, "lp = ", lp );
lbest := MinimiseLeadTerm( lp, G, rws );
lp := lbest*(-1);
Info( InfoIdRel, 2, "lp = ", lp );
if ( lbest < lp ) then
Add( polys, lbest );
else
Add( polys, lp );
fi;
fi;
fi;
od;
Sort( polys );
return polys;
end );
#############################################################################
##
#M ReduceModulePolyList( <L> )
##
InstallMethod( ReduceModulePolyList, "for a list of identities", true,
[ IsFpGroup, IsHomogeneousList, IsHomogeneousList, IsHomogeneousList ], 0,
function( G, elmon, rws, modpols )
local irrepols, irrerems, sats, irrenum, m1, m0, i, lp, rp, leadgp, yp,
logrem, remyp, remrp, rem, remsat, m, r;
irrepols := [ ];
irrerems:= [ ];
sats := [ ];
irrenum := 0;
m1 := RelatorModulePoly( modpols[1] );
m0 := m1 - m1;
for i in [1..Length(modpols)] do
lp := modpols[i];
if ( InfoLevel( InfoIdRel ) > 2 ) then
Print( "\n\n", i, " : ");Display( lp );Print( "\n" );
fi;
rp := RelatorModulePoly( lp );
leadgp := LeadGenerator( rp );
yp := YSequenceModulePoly( lp );
if ( InfoLevel( InfoIdRel ) > 2 ) then
Print( "\nlooking at polynomial number ", i, ": \n" );
Display( lp );
Print( "\n" );
fi;
##################### saturation used here: #######################
if ( sats = [ ] ) then
logrem := lp;
remyp := yp;
remrp := rp;
else
rem := LoggedReduceModulePoly( rp, rws, sats, m0 );
remyp := yp + YSequenceModulePoly( rem );
remrp := RelatorModulePoly( rem );
logrem := LoggedModulePoly( remyp, remrp );
fi;
if ( remrp = m0 ) then
if ( InfoLevel( InfoIdRel ) > 2 ) then
Print( "reduced to zero by:\n" );
Display( remyp );
Print( "\n" );
fi;
else
if ( LeadGenerator( remrp ) <> leadgp ) then
if ( InfoLevel( InfoIdRel ) > 2 ) then
Print( "\n! minimising leading term: !\n\n" );
logrem := MinimiseLeadTerm( logrem, G, rws );
fi;
fi;
if ( InfoLevel( InfoIdRel ) > 2 ) then
Print( "logrem = " );Display(logrem);Print("\n");
fi;
irrenum := irrenum + 1;
remsat := SaturatedSetLoggedModulePoly( logrem, elmon, rws, sats );
if ( InfoLevel( InfoIdRel ) > 2 ) then
Print( "\nsaturated set:\n" );
for m in [1..Length(remsat)] do
Print( m, ": ");Display(remsat[m]);Print("\n");
od;
Print( "irreducible number ", irrenum, " :-\n" );
Display( lp );
Print( "\n" );
fi;
Add( irrepols, lp );
Add( irrerems, logrem );
Add( sats, remsat );
SortParallel( irrerems, sats );
if ( InfoLevel( InfoIdRel ) > 2 ) then
Print( "\ncurrent state of reduced list, irrerems:\n" );
for r in irrerems do
Display( r );
Print( "\n" );
od;
fi;
fi;
od;
return [ irrepols, irrerems, irrenum, sats ];
end );
#############################################################################
##
#M IdentitiesAmongRelators( <G> )
##
InstallMethod( IdentitiesAmongRelators, "for an fp-group", true,
[ IsFpGroup ], 0,
function( G )
local L, mG, elmon, rws, F, FR, genFR, fmG, FMgens, FY, FYgens,
gseq, modpols, redpols, irrepols, irrerems, irrenum, sats,
r, ids, pol, ymp, gymp, pos, seq, iseq;
if HasArrangementOfMonoidGenerators( G ) then
L := ArrangementOfMonoidGenerators( G );
else
L := ArrangeMonoidGenerators( G );
fi;
mG := MonoidPresentationFpGroup( G );
if HasPartialElements( G ) then
elmon := PartialElements( G );
else
elmon := ElementsOfMonoidPresentation( G );
fi;
rws := List( LoggedRewritingSystemFpGroup( G ), r -> [ r[1], r[3] ] );
F := FreeGroupOfFpGroup( G );
FR := FreeGroupOfPresentation( mG );
genFR := GeneratorsOfGroup( FR );
fmG := FreeGroupOfPresentation( mG );
FMgens := GeneratorsOfGroup( fmG );
gseq := IdentityRelatorSequences( G );
iseq := ReduceLogSequences( G, gseq );
Info( InfoIdRel, 1, "iseq has length: ", Length(iseq) );
FY := FreeYSequenceGroup( G );
FYgens := GeneratorsOfGroup( FY );
modpols := ConvertToYSequences( G, FY, iseq );
redpols := ReduceModulePolyList( G, elmon, rws, modpols );
irrepols := redpols[1];
irrerems := redpols[2];
irrenum := redpols[3];
sats := redpols[4];
if ( InfoLevel( InfoIdRel ) > 0 ) then
Print( "\nThere were ", irrenum, " irreducibles found.\n" );
Print( "The corresponding saturated sets have size:\n" );
Print( List( sats, Length ), "\n\n" );
Print( "The irreducibles and the (reordered) remainders are:\n\n" );
for r in [1..irrenum] do
Print( r, " : ", irrepols[r], "\n" );
od;
Print( "-------------------------------------------------------\n\n" );
for r in [1..irrenum] do
Print( r, " : ", irrerems[r], "\n" );
od;
fi;
SetIdentityYSequences( G, irrepols );
## now pick out the relator sequences corresponding to these polys
ids := ListWithIdenticalEntries( irrenum, 0 );
for r in [1..irrenum] do
pol := irrepols[r];
ymp := YSequenceModulePoly( pol );
gymp := GeneratorsOfModulePoly( ymp )[1];
pos := Position( FYgens, gymp );
seq := iseq[pos];
ids[r] := seq;
od;
#? return [ irrepols, irrerems ];
return ids;
end );
#############################################################################
##
#M RootIdentities( <G> )
##
InstallMethod( RootIdentities, "for an FpGroup", true, [ IsFpGroup ], 0,
function( G )
local rels, nrels, rpos, roots, mG, fmG, gens, fam, id, inv,
i, r, L, len, w, iw, div, num, d, q, K, ok, k, J;
roots := [ ];
mG := MonoidPresentationFpGroup( G );
fmG := FreeGroupOfPresentation( mG );
gens := GeneratorsOfGroup( fmG );
fam := FamilyObj( gens[1] );
id := One( fmG );
inv := InverseRulesOfPresentation( mG );
rels := GroupRelatorsOfPresentation( mG );
nrels := Length( rels );
rpos := ListWithIdenticalEntries( nrels, false );
for i in [1..nrels] do
r := rels[i];
L := ExtRepOfObj( r );
len := Length( L );
if ( len = 2 ) then
w := gens[ L[1] ];
Add( roots, [ [ -i, id ], [ i, w ] ] );
iw := ReduceWordKB( w^-1, inv );
Add( roots, [ [ -i, id ], [ i, iw ] ] );
rpos[i] := true;
else
div := DivisorsInt( len );
num := Length( div );
for d in div do
if ( ( d > 1 ) and ( d <= len/2 ) ) then
q := len/d;
K := L{[1..q]};
ok := true;
for k in [2..d] do
J := L{[(k-1)*q+1..k*q]};
if ( J <> K ) then
ok := false;
fi;
od;
if ok then
w := ObjByExtRep( fam, K );
Add( roots, [ [ -i, id ], [ i, w ] ] );
iw := ReduceWordKB( w^-1, inv );
Add( roots, [ [ -i, id ], [ i, iw ] ] );
rpos[i] := true;
fi;
fi;
od;
fi;
od;
SetRootPositions( G, rpos );
return roots;
end );
##############################################################################
##
#M PrintLnYSequence
#M PrintYSequence
##
InstallMethod( PrintLnYSequence, "for (list of) Ysequences",
true, [ IsObject, IsList, IsList, IsList, IsList ], 0,
function( obj, gens1, labs1, gens2, labs2 )
IdRelOutputPos := 0;
IdRelOutputDepth := 0;
PrintYSequence( obj, gens1, labs1, gens2, labs2 );
Print( "\n" );
IdRelOutputPos := 0;
end );
InstallMethod( PrintYSequence, "for (list of) module polynomials",
true, [ IsObject, IsList, IsList, IsList, IsList ], 0,
function( obj, gens1, labs1, gens2, labs2 )
local j, len, ys, gys, mys, rp;
IdRelOutputPos := 0;
IdRelOutputDepth := 0;
if IsList( obj ) then
len := Length( obj );
if ( len = 0 ) then
Print( "[ ]" );
else
Print( "[ " );
IdRelOutputPos := IdRelOutputPos + 2;
for j in [1..len] do
PrintYSequence( obj[j], gens1, labs1, gens2, labs2 );
if ( j < len ) then
Print( ", " );
IdRelOutputPos := IdRelOutputPos + 2;
fi;
od;
Print( " ]" );
IdRelOutputPos := IdRelOutputPos + 2;
fi;
else ## IsYSequence( obj ) we hope
ys := YSequenceModulePoly( obj );
gys := GeneratorsOfModulePoly( ys )[1];
mys := MonoidPolys( ys )[1];
Print( gys, "*(" );
PrintUsingLabels( mys, gens1, labs1 );
Print( "), " );
rp := RelatorModulePoly( obj );
PrintModulePoly( rp, gens1, labs1, gens2, labs2 );
Print( ") " );
IdRelOutputPos := IdRelOutputPos + 6;
fi;
end );
###############*#############################################################
##
#E idrels.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
##
[ Dauer der Verarbeitung: 0.53 Sekunden
(vorverarbeitet)
]
|