GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
##
#W AutGrp.gi FGA package Christian Sievers
##
## Methods for automorphism groups of free groups
##
#Y 2003 - 2012
##
#############################################################################
##
#M AutomorphismGroup( <group> )
##
InstallMethod( AutomorphismGroup,
"for free groups",
[ CanComputeWithInverseAutomaton ],
function( G )
local n, aut;
n := RankOfFreeGroup( G );
if n = 0 then
aut := AsGroup( [ IdentityMapping ( G ) ] );
elif n = 1 then
aut := Group( FreeGroupAutomorphismsGeneratorO( G ) );
SetSize( aut, 2 );
elif n = 2 then
aut := Group( FreeGroupAutomorphismsGeneratorO( G ),
FreeGroupAutomorphismsGeneratorP( G ),
FreeGroupAutomorphismsGeneratorU( G ) );
elif n = 3 then
aut := Group( FreeGroupAutomorphismsGeneratorS( G ),
FreeGroupAutomorphismsGeneratorT( G ),
FreeGroupAutomorphismsGeneratorU( G ) );
elif IsEvenInt( n ) then
aut := Group( FreeGroupAutomorphismsGeneratorQ( G ),
FreeGroupAutomorphismsGeneratorR( G ) );
else # n > 3, odd
aut := Group( FreeGroupAutomorphismsGeneratorS( G ),
FreeGroupAutomorphismsGeneratorR( G ) );
fi;
SetIsFinite( aut, n <= 1 );
SetFilterObj( aut, IsAutomorphismGroupOfFreeGroup );
return aut;
end );
#############################################################################
##
#M \in( <hom>, <autgrp> )
##
## tests whether <hom> is in <autgrp>.
##
## Code contributed by Max Horn.
InstallMethod( \in,
"for automorphism groups of free groups",
[ IsGroupGeneralMapping, IsAutomorphismGroupOfFreeGroup ],
function( hom, aut )
local G;
G := AutomorphismDomain( aut );
return Source( hom ) = G and Range( hom ) = G and IsBijective( hom );
end );
#############################################################################
##
#M IsomorphismFpGroup( <group> )
##
## returns an isomorphism from an automorphism group of a free group
## to a finitely presented group.
##
## The presentation follows Bernhard Neumann (see ../doc/manual.bib)
## Numbers in the comments refer to the equation numbers in that paper.
##
InstallMethod( IsomorphismFpGroup,
"for automorphism groups of free groups",
[ IsAutomorphismGroupOfFreeGroup ],
function( aut )
local n, f, fp, O, P, U, S, T, Q, R, rels, moreRels,
o, p, u, s, t, q, r, iso, isoinv;
n := RankOfFreeGroup( AutomorphismDomain ( aut ));
if n = 0 then
fp := FreeGroup( 0 );
iso := aut -> One( fp );
elif n = 1 then
f := FreeGroup( "O" );
O := f.1;
rels := [ O^2 ]; # 6a
fp := f / rels;
o := fp.1;
iso := aut -> o ^ (Order(aut) - 1);
elif n = 2 then
f := FreeGroup( "O", "P", "U" );
O := f.1; P := f.2; U := f.3;
rels := [ P^2 # 5a
, O^2 # 6a
, (O*P)^4 # 8a
, Comm( U, O*U*O ) # 7e
, (P*O*P*U)^2 # 7i
, (U*P*O)^3 # 8b
];
fp := f / rels;
o := fp.1; p := fp.2; u := fp.3;
iso := FGA_CurryAutToPQOU( p, p, o, u); # Q=P
elif n = 3 then
f := FreeGroup( "S", "T", "U" );
S := f.1; T := f.2; U := f.3;
rels := [ (S^5*T^-1)^2 # 19a
, T^-1*S*T^2*S^8*T^-1*S*T^2*S^-4 # 19b
, (S^4*T^-1*S*T^-1)^2 # 19c
, T^4 # 19d
, Comm( U, S^2*T^-1*S*T^-1*S^2 ) # 19e
, Comm( U, S^-2*T^-1*S*T^-1*U*S^-2*T^-1*S*T^-1) # 19f
# wrong: Comm( U, S^2*T^-1*S*T*S*T^-1*U*T*S^-1*T^-1*S^-1*T*S^2 ) # 19g
, Comm( U, S^-2*T^-1*S*T*S*T^-1*U*
T*S^-1*T^-1*S^-1*T*S^2 ) # 19g corrected
, Comm( U, T^-1*S*T^2*U*T^-1*S*T^2 ) # 19h
, S^-2*T^-1*S*T^2*S^2*U*S^2*T^-1*S*T^2*S^2*
U*S^-2*U*S^2*U^-1*S^-2*U^-1 # 19i
, (S^-2*T^-1*S*T*U)^2 # 19j
, (U*T)^3 # 19k
];
fp := f / rels;
s := fp.1; t := fp.2; u := fp.3;
iso := FGA_CurryAutToPQOU( t*s^3*(s*t^-1)^2 # 16c
, s^4 # 16a
, s^3*(s*t^-1)^2 # 16b
, u
);
elif IsEvenInt(n) then
f := FreeGroup( "Q", "R" );
Q := f.1; R := f.2;
rels := [ (R^3*(Q*R^3)^(n-1))^2 # 22a
, (Q*R^3)^(2*(n-1)) # 22d
, Q^n # 22e
, Comm( (Q*R^3)^(n-1),
Q^-1*R^3*(Q*R^3)^(n-1)*Q ) # 22f
, Comm( Q^-2*R^4*Q^2*R^-3,
Q*R^-3*Q^-1*R^-3*Q ) # 22h
, Comm( R^4, (Q*R^3)^(n-1) ) # 22j
, Comm( R^4, Q^-2*R^4*Q^2 ) # 22k
, Comm( Q^-2*R^4*Q^2*R^-3,
(Q*R^3)^(n-1)*Q^-2*R^4*Q^2*R^-3*(Q*R^3)^(n-1) ) # 22l
, Comm( Q^-2*R^4*Q^2*R^-3,
R^-3*Q^-1*Q^-2*R^4*Q^2*R^-3*Q*R^3 ) # 22m
, Comm( Q^-2*R^4*Q^2*R^-3,
R^-3*Q^-1*R^-3*(Q*R^3)^n*Q^-2*R^4*
Q^2*R^-3*(Q*R^3)^-n*R^3*Q*R^3 ) # 22n
, (Q*R^3)^-n*Q^-2*R^4*Q^2*R^-3*(Q*R^3)^n*
Q^-3*R^4*Q^2*R^-3*Q^-1*R^4*Q^2*R^-3*
Q^-1*R^3*Q^-2*R^-4*Q^3*R^3*Q^-2*R^-4*Q^2 # 22o
, (R^3*(Q*R^3)^(n-1)*Q^-2*R^4*Q^2)^2 # 22p
, R^12 # 22q
];
# finally the relations 22c:
moreRels := List( [ 2 .. n/2 ],
i -> Comm( R^3*(Q*R^3)^(n-1),
Q^-i*R^3*(Q*R^3)^(n-1)*Q^i ) );
fp := f / Concatenation(rels, moreRels);
q := fp.1; r := fp.2;
iso := FGA_CurryAutToPQOU( r^3*(q*r^3)^(n-1) # 21b
, q
, (q*r^3)^(n-1) # 21a
, q^-2*r^4*q^2*r^-3 # 21c
);
else # n > 3, odd
f := FreeGroup( "S", "R" );
S := f.1; R := f.2;
rels := [ (R^3*S^n*(S*R^-3)^(n-1))^2 # 25a
, (S^(n+1)*R^3*S^n*(S*R^-3)^(n-1))^(n-1)*
S^((-n)*(n-1)) # 25b
, ((S^n)*(S*R^-3)^(n-1))^2 # 25d
, Comm( S^n*(S*R^-3)^(n-1),
S^-(n+1)*R^3*S^n*
(S*R^-3)^(n-1)*S^(n+1) ) # 25e
, Comm( S^-2*R^4*S^2*R^3,
S*R^-3*S^(n-1)*R^-3*S ) # 25f
, Comm( R^4, S^n*(S*R^-3)^(n-1) ) # 25g
, Comm( R^4, S^-2*R^4*S^2 ) # 25h
, Comm( S^-2*R^4*S^2*R^-3,
S^n*(S*R^-3)^(n-1)*S^-2*R^4*S^2*
R^-3*S^n*(S*R^-3)^(n-1) ) # 25i
, Comm( S^-2*R^4*S^2*R^-3,
R^-3*S^-(n+1)*S^-2*R^4*S^2*
R^-3*S^(n+1)*R^3 ) # 25j
# wrong: , Comm( S^-2*R^4*S^2*R^-3,
# R^-3*S^-1*R^-3*S*R^3*S^n*
# (S*R^-3)^(n-1)*S^-2*R^4*S^2*R^3*
# (S*R^-3)^(n-1)*S^n*R^-3*S^-1*
# R^3*S*R^3 ) # 25k
, Comm( S^-2*R^4*S^2*R^-3,
R^-3*S^-1*R^-3*S*R^3*S^n*
(S*R^-3)^(n-1)*S^-2*R^4*S^2*R^-3*
(S*R^-3)^(n-1)*S^n*R^-3*S^-1*
R^3*S*R^3 ) # 25k corrected
, R^3*(S*R^-3)^(n-1)*S^-3*R^4*S^2*R^-3*S*
R^3*(S*R^-3)^(n-1)*S^(n-3)*R^4*S^2*R^-3*
S^(n-1)*R^4*S^2*R^-3*S^(n-1)*R^3*S^-2*
R^-4*S^(n+3)*R^3*S^-2*R^-4*S^2 # 25l
, (R^3*(S*R^-3)^(n-1)*S^(n-2)*R^4*S^2)^2 # 25m
, R^12 # 22q
] ;
# and finally the relations 25c:
moreRels := List( [ 2 .. (n-1)/2 ],
i -> Comm( R^3*S^n*(S*R^-3)^(n-1),
S^(-i*(n+1))*R^3*S^n*
(S*R^-3)^(n-1)*S^(i*(n+1)) ) );
fp := f / Concatenation( rels, moreRels );
s := fp.1; r := fp.2;
iso := FGA_CurryAutToPQOU( r^3*s^n*(s*r^-3)^(n-1) # 24c
, s^(n+1) # 24a
, s^n*(s*r^-3)^(n-1) # 24b
, s^(-2*(n+1))*r^4*s^(2*(n+1))*r^-3 # 24d
);
fi;
isoinv := GroupHomomorphismByImagesNC( fp, aut,
GeneratorsOfGroup( fp ),
GeneratorsOfGroup( aut ) );
return GroupHomomorphismByFunction( aut, fp, iso,
x -> x ^ isoinv );
end );
#############################################################################
##
#F FreeGroupEndomorphismByImages( <group>, <images> )
##
## returns the endomorphism of <group> that maps the generators of <group>
## to <images>.
##
InstallGlobalFunction( FreeGroupEndomorphismByImages,
function(g,l)
return GroupHomomorphismByImages(g,g,FreeGeneratorsOfGroup(g),l);
end );
#############################################################################
##
#F FreeGroupAutomorphismsGeneratorO( <group> )
#F FreeGroupAutomorphismsGeneratorP( <group> )
#F FreeGroupAutomorphismsGeneratorU( <group> )
#F FreeGroupAutomorphismsGeneratorS( <group> )
#F FreeGroupAutomorphismsGeneratorT( <group> )
#F FreeGroupAutomorphismsGeneratorQ( <group> )
#F FreeGroupAutomorphismsGeneratorR( <group> )
##
## These functions return the automorphism of <group> which maps the
## generators [<x1>, <x2>, ..., <xn>] to
## O : [<x1>^-1 , <x2>, ..., <xn> ] (n>=1)
## P : [<x2> , <x1>, <x3>, ..., <xn> ] (n>=2)
## U : [<x1><x2>, <x2>, <x3>, ..., <xn> ] (n>=2)
## S : [<x2>^-1, <x3>^-1, ..., <xn>^-1, <x1>^-1 ] (n>=1)
## T : [<x2> , <x1>^-1, <x3>, ..., <xn>] (n>=2)
## Q : [<x2>, <x3>, ..., <xn>, <x1> ] (n>=2)
## R : [<x2>^-1, <x1>, <x3>, <x4>, ...,
## <x{n-2}>, <xn><x{n-1}>^-1, <x{n-1}>^-1] (n>=4)
##
InstallGlobalFunction( FreeGroupAutomorphismsGeneratorO,
function( g )
local imgs;
FGA_CheckRank( g, 1 );
imgs := ShallowCopy( FreeGeneratorsOfGroup( g ) );
imgs[1] := imgs[1]^-1;
return FreeGroupEndomorphismByImages( g, imgs );
end );
InstallGlobalFunction( FreeGroupAutomorphismsGeneratorP,
function( g )
local imgs;
FGA_CheckRank( g, 2 );
imgs := ShallowCopy( FreeGeneratorsOfGroup( g ) );
imgs{[1,2]} := [ imgs[2], imgs[1] ];
return FreeGroupEndomorphismByImages( g, imgs );
end );
InstallGlobalFunction( FreeGroupAutomorphismsGeneratorU,
function( g )
local imgs;
imgs := ShallowCopy( FreeGeneratorsOfGroup( g ) );
FGA_CheckRank( g, 2 );
imgs[1] := imgs[1] * imgs[2];
return FreeGroupEndomorphismByImages( g, imgs );
end );
InstallGlobalFunction( FreeGroupAutomorphismsGeneratorS,
function( g )
local imgs;
FGA_CheckRank( g, 1 );
imgs := FreeGeneratorsOfGroup(g){[2..Rank(g)]};
Add( imgs, FreeGeneratorsOfGroup(g)[1] );
return FreeGroupEndomorphismByImages( g, List(imgs, g -> g^-1) );
end );
InstallGlobalFunction( FreeGroupAutomorphismsGeneratorT,
function( g )
local imgs;
FGA_CheckRank( g, 2 );
imgs := ShallowCopy( FreeGeneratorsOfGroup( g ) );
imgs{[1..2]} := [ imgs[2], imgs[1]^-1 ];
return FreeGroupEndomorphismByImages( g, imgs );
end );
InstallGlobalFunction( FreeGroupAutomorphismsGeneratorQ,
function( g )
local imgs;
FGA_CheckRank( g, 2 ); # we could allow 1
imgs := FreeGeneratorsOfGroup(g){[2..Rank(g)]};
Add( imgs, FreeGeneratorsOfGroup(g)[1] );
return FreeGroupEndomorphismByImages( g, imgs );
end );
InstallGlobalFunction( FreeGroupAutomorphismsGeneratorR,
function( g )
local imgs, n;
FGA_CheckRank( g, 4 );
n := RankOfFreeGroup( g );
imgs := ShallowCopy( FreeGeneratorsOfGroup( g ) );
imgs{[1,2,n-1,n]} := [ imgs[2]^-1, imgs[1],
imgs[n]*imgs[n-1]^-1, imgs[n-1]^-1 ];
return FreeGroupEndomorphismByImages( g, imgs );
end );
#############################################################################
##
#F FGA_CheckRank( <group>, <minrank> )
##
## Checks whether <group> has rank at least <minrank>, and signals an
## error otherwise (helper function for FreeGroupAutomorphismsGenerator*)
##
InstallGlobalFunction( FGA_CheckRank,
function( g, r )
if RankOfFreeGroup( g ) < r then
Error( "the rank of the group should be at least ", r );
fi;
return;
end );
#############################################################################
##
#E