############################################################################# ## ## This file is part of GAP, a system for computational discrete algebra. ## This file's authors include Heiko Theißen. ## ## Copyright of GAP belongs to its developers, whose names are too numerous ## to list here. Please refer to the COPYRIGHT file for details. ## ## SPDX-License-Identifier: GPL-2.0-or-later ##
############################################################################# ## #M DirectProductOp( <grps>, <G> ) . . . . . . direct product of perm groups ##
InstallMethod( DirectProductOp, "for a list of permutation groups, and a permutation group",
IsCollsElms,
[ IsList and IsPermCollColl, IsPermGroup ], 0, function( grps, G )
# Check the arguments. if not ForAll( grps, IsGroup ) then
TryNextMethod(); fi;
return DirectProductOfPermGroupsWithMovedPoints(grps, List(grps, MovedPoints)); end );
############################################################################# ## #M Size( <D> ) . . . . . . . . . . . . . . . . . . . . . . of direct product ##
InstallMethod( Size, "for a permutation group that knows to be a direct product",
true,
[ IsPermGroup and HasDirectProductInfo ], 0,
D -> Product( List( DirectProductInfo( D ).groups, Size ) ) );
############################################################################# ## #R IsEmbeddingDirectProductPermGroup( <hom> ) . embedding of direct factor ##
DeclareRepresentation( "IsEmbeddingDirectProductPermGroup",
IsAttributeStoringRep and
IsGroupHomomorphism and IsInjective and
IsSPGeneralMapping, [ "component" ] );
############################################################################# ## #R IsEmbeddingWreathProductPermGroup( <hom> ) . embedding of wreath factor ##
DeclareRepresentation( "IsEmbeddingWreathProductPermGroup",
IsAttributeStoringRep and
IsGroupHomomorphism and IsInjective and
IsSPGeneralMapping, [ "component" ] );
############################################################################# ## #R IsEmbeddingImprimitiveWreathProductPermGroup( <hom> ) ## ## special for case of imprimitive wreath product
DeclareRepresentation( "IsEmbeddingImprimitiveWreathProductPermGroup",
IsEmbeddingWreathProductPermGroup, [ "component" ] );
############################################################################# ## #R IsEmbeddingProductActionWreathProductPermGroup( <hom> ) ## ## special for case of product action wreath product
DeclareRepresentation( "IsEmbeddingProductActionWreathProductPermGroup",
IsEmbeddingWreathProductPermGroup
and IsGroupGeneralMappingByAsGroupGeneralMappingByImages,["component"]);
############################################################################# ## #M Embedding( <D>, <i> ) . . . . . . . . . . . . . . . . . . make embedding ##
InstallMethod( Embedding,"perm direct product", true,
[ IsPermGroup and HasDirectProductInfo,
IsPosInt ], 0, function( D, i )
local emb, info;
info := DirectProductInfo( D ); if IsBound( info.embeddings[i] ) then return info.embeddings[i]; fi;
emb := Objectify( NewType( GeneralMappingsFamily( PermutationsFamily,
PermutationsFamily ),
IsEmbeddingDirectProductPermGroup ),
rec( component := i ) );
SetRange( emb, D );
############################################################################# ## #M ImagesRepresentative( <emb>, <g> ) . . . . . . . . . . . . of embedding ##
InstallMethod( ImagesRepresentative,"perm direct product embedding",
FamSourceEqFamElm, [ IsEmbeddingDirectProductPermGroup,
IsMultiplicativeElementWithInverse ], 0, function( emb, g )
return g ^ DirectProductInfo( Range( emb ) ).perms[ emb!.component ]; end );
############################################################################# ## #M PreImagesRepresentative( <emb>, <g> ) . . . . . . . . . . . of embedding ##
InstallMethod( PreImagesRepresentative, "perm direct product embedding",
FamRangeEqFamElm,
[ IsEmbeddingDirectProductPermGroup,
IsMultiplicativeElementWithInverse ], function( emb, g )
local info;
info := DirectProductInfo( Range( emb ) ); #T Make this more efficient: #T Creating the restricted permutation could be avoided #T if there would be an efficient (kernel) function that tests whether #T a permutation moves points outside a given set. #T Inverting the mapping permutation in each call could be avoided #T by storing also the inverse, and the conjugation could be improved. if g = RestrictedPermNC( g, info.news[ emb!.component ] ) then
return g ^ (info.perms[ emb!.component ] ^ -1); else
return fail; fi; end );
############################################################################# ## #M PreImagesRepresentative( <prj>, <g> ) . . . . . . . . . . . of projection ##
InstallMethod( PreImagesRepresentative,"perm direct product projection",
FamRangeEqFamElm,
[ IsProjectionDirectProductPermGroup,
IsMultiplicativeElementWithInverse ], 0, function( prj, g )
return g ^ DirectProductInfo( Source( prj ) ).perms[ prj!.component ]; end );
############################################################################# ## #M KernelOfMultiplicativeGeneralMapping( <prj> ) . . . . . . . of projection ##
InstallMethod( KernelOfMultiplicativeGeneralMapping, "perm direct product projection",
true, [ IsProjectionDirectProductPermGroup ], 0, function( prj )
local D, gens, i, K, info;
D := Source( prj );
info := DirectProductInfo( D );
gens := [ ]; for i in [ 1 .. Length( info.groups ) ] do if i <> prj!.component then
Append( gens, OnTuples( GeneratorsOfGroup( info.groups[ i ] ),
info.perms[ i ] ) ); fi;
od;
K := SubgroupNC( D, gens );
SetIsNormalInParent( K, true );
return K; end );
InstallGlobalFunction(SubdirectDiagonalPerms,function(l,m)
local n,o,p;
n:=LargestMovedPoint(l);
o:=LargestMovedPoint(m);
p:=MappingPermListList([1..o],[n+1..n+o]);
return List([1..Length(l)],i->l[i]*m[i]^p); end);
############################################################################# ## #M SubdirectProduct( <G1>, <G2>, <phi1>, <phi2> ) . . . . . . . constructor ##
InstallMethod( SubdirectProductOp,"permgroup", true,
[ IsPermGroup, IsPermGroup, IsGroupHomomorphism, IsGroupHomomorphism ], 0, function( G1, G2, phi1, phi2 )
local S, # subdirect product of <G1> and <G2>, result
gens, # generators of <S>
D, # direct product of <G1> and <G2>
emb1, emb2, # embeddings of <G1> and <G2> into <D>
info, Dinfo,# info records
gen; # one generator of <G1> or kernel of <phi2>
# make the direct product and the embeddings
D := DirectProduct( G1, G2 );
emb1 := Embedding( D, 1 );
emb2 := Embedding( D, 2 );
# the subdirect product is generated by $(g_1,x_{g_1})$ where $g_1$ loops # over the generators of $G_1$ and $x_{g_1} \in G_2$ is arbitrary such # that $g_1^{phi_1} = x_{g_1}^{phi_2}$ and by $(1,k_2)$ where $k_2$ loops # over the generators of the kernel of $phi_2$.
gens := []; for gen in GeneratorsOfGroup( G1 ) do
Add( gens, gen^emb1 * PreImagesRepresentative(phi2,gen^phi1)^emb2 );
od; for gen in GeneratorsOfGroup(
KernelOfMultiplicativeGeneralMapping( phi2 ) ) do
Add( gens, gen ^ emb2 );
od;
# and make the subdirect product
S := GroupByGenerators( gens );
SetParent( S, D );
Dinfo := DirectProductInfo( D );
info := rec( groups := [G1, G2],
homomorphisms := [phi1, phi2],
olds := Dinfo.olds,
news := Dinfo.news,
perms := Dinfo.perms,
projections := [] );
SetSubdirectProductInfo( S, info );
return S; end );
############################################################################# ## #R IsProjectionSubdirectProductPermGroup( <hom> ) . projection onto factor ##
DeclareRepresentation( "IsProjectionSubdirectProductPermGroup",
IsAttributeStoringRep and
IsGroupHomomorphism and IsSurjective and
IsSPGeneralMapping, [ "component" ] );
############################################################################# ## #M Projection( <S>, <i> ) . . . . . . . . . . . . . . . . . make projection ##
InstallMethod( Projection,"perm subdirect product",true,
[ IsPermGroup and HasSubdirectProductInfo,
IsPosInt ], 0, function( S, i )
local prj, info;
info := SubdirectProductInfo( S ); if IsBound( info.projections[i] ) then return info.projections[i]; fi;
prj := Objectify( NewType( GeneralMappingsFamily( PermutationsFamily,
PermutationsFamily ),
IsProjectionSubdirectProductPermGroup ),
rec( component := i ) );
SetSource( prj, S );
info.projections[i] := prj;
SetSubdirectProductInfo( S, info );
return prj; end );
D := Source( prj );
info := SubdirectProductInfo( D );
i := 3 - prj!.component;
return SubgroupNC( D, OnTuples
( GeneratorsOfGroup( KernelOfMultiplicativeGeneralMapping(
info.homomorphisms[ i ] ) ),
info.perms[ i ] ) ); end );
############################################################################# ## #M WreathProductImprimitiveAction( <G>, <H> [,<hom>] ) ##
InstallGlobalFunction(WreathProductImprimitiveAction,function( arg )
local G,H, # factors
GP, # preimage of <G> (if homomorphism)
Ggens,Igens,# permutation images of generators
alpha, # action homomorphism for <H>
permimpr, # product is pure permutation groups imprimitive
I, # image of <alpha>
grp, # wreath product of <G> and <H>, result
gens, # generators of the wreath product
gens1, # generators of first base part
gen, # one generator
domG, # domain of operation of <G>
degG, # degree of <G>
domI, # domain of operation of <I>
degI, # degree of <I>
shift, # permutation permuting the blocks
perms, # component permutating permutations
basegens, # generators of base subgroup
hgens, # complement generators
components, # components (points) of base group
rans, # list of arguments that have '.sCO.random'
info, # info record
i, k, l; # loop variables
G:=arg[1];
H:=arg[2]; # get the domain of operation of <G> and <H> if IsPermGroup( G ) then
permimpr:=true;
domG := MovedPoints( G );
GP:=G;
Ggens:=GeneratorsOfGroup(G); elif IsGroupHomomorphism( G ) and IsPermGroup( Range( G ) ) then
permimpr:=false;
GP:=Source(G);
domG := MovedPoints( Range( G ) );
Ggens:=List(GeneratorsOfGroup(GP),i->ImageElm(G,i));
G := Image( G ); else
Error( "WreathProduct: <G> must be perm group or homomorphism" ); fi;
degG := Length( domG );
if Length(arg)=2then
domI := MovedPoints( H );
I := H;
alpha := IdentityMapping( H );
Igens:=GeneratorsOfGroup(H); elif IsGroupHomomorphism(arg[3]) and IsPermGroup(Range(arg[3])) then
permimpr:=false; # also will fail the permutation imprimitive case
alpha := arg[3];
I := Image( alpha );
domI := MovedPoints( Range( alpha) );
Igens:=List(GeneratorsOfGroup(H),i->ImageElm(alpha,i)); else
Error( "WreathProduct: <H> must be perm group or homomorphism" ); fi;
if IsEmpty( domI ) then
domI := [ 1 ]; fi;
domI := MakeImmutable(Set(domI));
degI := Length( domI );
# make the generators of the direct product of <deg> copies of <G>
components:=[];
gens := [];
perms:= [];
# force trivial group to act on 1 point if degG = 0then domG := [1]; degG := 1; fi;
for i in [1..degI] do
components[i]:=[(i-1)*degG+1..i*degG];
shift := MappingPermListList( domG, components[i] );
Add(perms,shift); for gen in Ggens do
Add( gens, gen ^ shift );
od; if i=1then gens1:=ShallowCopy(gens);fi;
od;
basegens:=gens;
gens:=Filtered(gens, g -> not IsOne(g));
# reduce generator number if it becomes too large -- only first base # part if Length(basegens)>10 and Length(domI)>1 and IsTransitive(I,domI) then
gens:=gens1; fi;
# add the generators of <I>
hgens:=[]; for gen in Igens do
shift := []; for i in [1..degI] do
k := Position( domI, domI[i]^gen ); for l in [1..degG] do
shift[(i-1)*degG+l] := (k-1)*degG+l;
od;
od;
shift:=PermList(shift); if not IsOne(shift) then
Add( gens, shift ); fi;
Add(hgens, shift );
od;
# make the group generated by those generators
grp := GroupWithGenerators( gens, () ); # `gens' arose from `PermList'
# enter the size
SetSize( grp, Size( G ) ^ degI * Size( I ) );
# note random method
rans := Filtered( [ G, I ], i ->
IsBound( StabChainOptions( i ).random ) ); if Length( rans ) > 0then
SetStabChainOptions( grp, rec( random :=
Minimum( List( rans, i -> StabChainOptions( i ).random ) ) ) ); fi;
info := rec(
groups := [GP,H],
alpha := alpha,
perms := perms,
base := SubgroupNC(grp,basegens),
basegens:=basegens,
I := I,
degI := degI,
domI := domI,
hgens := hgens,
components := components,
embeddingType := NewType(
GeneralMappingsFamily(PermutationsFamily,PermutationsFamily),
IsEmbeddingImprimitiveWreathProductPermGroup),
embeddings := [],
permimpr:=permimpr);
############################################################################# ## #M Embedding( <W>, <i> ) . . . . . . . . . . . . . . . . . . make embedding ##
InstallMethod( Embedding,"perm wreath product", true,
[ IsPermGroup and HasWreathProductInfo,
IsPosInt ], 0, function( W, i )
local emb, info;
info := WreathProductInfo( W ); if IsBound( info.embeddings[i] ) then return info.embeddings[i]; fi;
if i<=info.degI then
emb := Objectify( info.embeddingType , rec( component := i ) ); if IsBound(info.productType) and info.productType=true then
SetAsGroupGeneralMappingByImages(emb,GroupHomomorphismByImagesNC(
info.groups[1],W,GeneratorsOfGroup(info.groups[1]),
info.basegens[i])); fi; elif i=info.degI+1then if IsBound(info.productType) and info.productType=true then
emb:= GroupHomomorphismByImagesNC(info.I,W,GeneratorsOfGroup(info.I),
info.hgens);
emb:= GroupHomomorphismByImagesNC(info.groups[2],W,
GeneratorsOfGroup(info.groups[2]),
List(GeneratorsOfGroup(info.groups[2]),
i->ImageElm(emb,ImageElm(info.alpha,i))));
SetIsInjective(emb,true); else
emb := Objectify( info.embeddingType , rec( component := i ) ); fi; else
Error("no embedding <i> defined"); fi;
SetRange( emb, W );
info.embeddings[i] := emb;
return emb; end );
############################################################################# ## #M Source( <emb> ) . . . . . . . . . . . . . . . . . . . . . . of embedding ##
InstallMethod( Source,"perm wreath product embedding",
true, [ IsEmbeddingWreathProductPermGroup ], 0, function(emb)
local info;
info := WreathProductInfo( Range( emb ) ); # Embedding into top group if emb!.component = info.degI + 1then
return info.groups[2]; # Embedding into a component of the base group else
return info.groups[1]; fi; end);
############################################################################# ## #M ImagesRepresentative( <emb>, <g> ) . . . . . . . . . . . . of embedding ##
InstallMethod( ImagesRepresentative, "imprim perm wreath product embedding",FamSourceEqFamElm,
[ IsEmbeddingImprimitiveWreathProductPermGroup,
IsMultiplicativeElementWithInverse ], 0, function( emb, g )
local info, degI, x, shift, domI, degG, i, k, l;
info := WreathProductInfo(Range(emb));
degI := info.degI; # Embedding into a component of the base group if emb!.component <> degI + 1then
return g ^ info.perms[emb!.component]; fi; # Embedding into top group
x := g ^ info.alpha;
domI := info.domI;
degG := NrMovedPoints(info.groups[1]); # force trivial group to act on 1 point if degG = 0then
degG := 1; fi;
shift := []; for i in [1 .. degI] do
k := Position(domI, domI[i] ^ x); if k = fail then
return fail; fi; for l in [1 .. degG] do
shift[(i - 1) * degG + l] := (k - 1) * degG + l;
od;
od;
return PermList(shift); end );
############################################################################# ## #M PreImagesRepresentative( <emb>, <g> ) . . . . . . . . . . . of embedding ##
InstallMethod( PreImagesRepresentative, "imprim perm wreath product embedding", FamRangeEqFamElm,
[ IsEmbeddingImprimitiveWreathProductPermGroup,
IsMultiplicativeElementWithInverse ], 0, function( emb, g )
local info;
info := WreathProductInfo( Range( emb ) ); # Embedding into top group if emb!.component = info.degI + 1then
return g ^ Projection(Range(emb)); fi; # Embedding into component of base group if not g in info.base then
return fail; fi;
return RestrictedPermNC( g, info.components[ emb!.component ] )
^ (info.perms[ emb!.component ] ^ -1); end );
############################################################################# ## #M Projection( <W> ) . . . . . . . . . . . . . . projection of wreath on top ##
InstallOtherMethod( Projection,"perm wreath product", true,
[ IsPermGroup and HasWreathProductInfo ],0, function( W )
local info, proj, H, degI, degK, constPoints, projFunc;
info := WreathProductInfo( W ); if IsBound( info.projection ) then return info.projection; fi;
# Imprimitive Action, tuple (i, j) corresponds # to point i + degK * (j - 1) if IsBound(info.permimpr) and info.permimpr=true then
proj:=ActionHomomorphism(W,info.components,OnSets,"surjective"); # Primitive Action, tuple (t_1, ..., t_degI) corresponds # to point Sum_{i=1}^degI t_i * degK ^ (i - 1) elif IsBound(info.productType) and info.productType=true then
degI := info.degI;
degK := NrMovedPoints(info.groups[1]); # constPoints correspond to [1, 1, ...] and the one-vectors with a 2 in each position, # i.e. [2, 1, 1, ...], [1, 2, 1, ...], [1, 1, 2, ...], ...
constPoints := Concatenation([0], List([0 .. degI - 1], i -> degK ^ i)) + 1;
projFunc := function(x)
local imageComponents, i, comp, topImages; # Let x = (f_1, ..., f_m; h). # imageComponents = [ [1 ^ f_1, 1 ^ f_2, 1 ^ f_3, ...] ^ (1, h) # [2 ^ f_1, 1 ^ f_2, 1 ^ f_3, ...] ^ (1, h), # [1 ^ f_1, 2 ^ f_2, 1 ^ f_3, ...] ^ (1, h), ... ] # So we just need to check where the bit differs from the first point # in order to compute the action of the top element h.
imageComponents := List(OnTuples(constPoints, x) - 1,
p -> CoefficientsQadic(p, degK) + 1); # The qadic expansion has no "trailing" zeros. Thus we need to append them. # For example if (1, ..., 1) ^ (f_1, ..., f_m) = (1, ..., 1), # we have imageComponents[1] = CoefficientsQadic(0, degK) + 1 = []. # Note that we append 1's instead of 0's, # since we already transformed the result of the qadic expansion # from [{0, ..., degK - 1}, ...] to [{1, ..., degK}, ...]. for i in [1 .. degI + 1] do
comp := imageComponents[i];
Append(comp, ListWithIdenticalEntries(degI - Length(comp), 1));
od; # For some reason, the action of the top component is in reverse order, # i.e. [ p[m], ..., p[1] ] ^ (1, h) = [ p[m ^ (h ^ -1)], ..., p[1 ^ (h ^ -1)] ]
topImages := List([0 .. degI - 1], i -> PositionProperty([0 .. degI - 1],
j -> imageComponents[1, degI - j] <>
imageComponents[degI - i + 1, degI - j]));
return PermList(topImages); end;
proj := GroupHomomorphismByFunction(W, info.groups[2], projFunc); else# weird cases where we use `hom` for the construction of the wreath product
H:=info.groups[2];
proj:=List(info.basegens,i->One(H));
proj:=GroupHomomorphismByImagesNC(W,H,
Concatenation(info.basegens,info.hgens),
Concatenation(proj,GeneratorsOfGroup(H))); fi;
SetKernelOfMultiplicativeGeneralMapping(proj,info.base);
info := WreathProductInfo(G); # The top group element
h := x ^ Projection(G); if h = fail then
return fail; fi;
hIm := ImageElm(Embedding(G, info.degI + 1), h); if hIm = fail then
return fail; fi; # The product of the base group elements
f := x * hIm ^ (-1);
list := EmptyPlist(info!.degI + 1);
list[info.degI + 1] := h; # Imprimitive Action, tuple (i, j) corresponds # to point i + degK * (j - 1) if IsBound(info.permimpr) and info.permimpr then for i in [1 .. info.degI] do
restPerm := RESTRICTED_PERM(f, info.components[i], testDecomposition); if restPerm = fail then
return fail; fi;
list[i] := restPerm ^ info.perms[i];
od; # Primitive Action, tuple (t_1, ..., t_degI) corresponds # to point Sum_{i=1}^degI t_i * degK ^ (i - 1) elif IsBound(info.productType) and info.productType then
degK := NrMovedPoints(info.groups[1]); # constPoints correspond to [1, 1, 1, ...], [2, 2, 2, ...], ...
constPoints := List([0 .. degK - 1], i -> Sum([0 .. info.degI - 1],
j -> i * degK ^ j)) + 1; # imageComponents = [ [1 ^ f_1, 1 ^ f_2, 1 ^ f_3, ...], # [2 ^ f_1, 2 ^ f_2, 2 ^ f_3, ...], ... ]
imageComponents := List(OnTuples(constPoints, f) - 1,
p -> CoefficientsQadic(p, degK) + 1); # The qadic expansion has no "trailing" zeros. Thus we need to append them. # For example if (1, ..., 1) ^ (f_1, ..., f_m) = (1, ..., 1), # we have imageComponents[1] = CoefficientsQadic(0, degK) + 1 = []. # Note that we append 1's instead of 0's, # since we already transformed the result of the qadic expansion # from [{0, ..., degK - 1}, ...] to [{1, ..., degK}, ...]. for i in [1 .. degK] do
comp := imageComponents[i];
Append(comp, ListWithIdenticalEntries(info.degI - Length(comp), 1));
od; for j in [1 .. info.degI] do
list[j] := PermList(List([1 .. degK], i -> imageComponents[i,j])); if list[j] = fail then
return fail; fi;
od; else
ErrorNoReturn("Error: cannot determine which action ", "was used for wreath product"); fi;
return list; end);
info := WreathProductInfo(G);
return Product(List([1 .. info.degI + 1], i -> list[i] ^ Embedding(G, i))); end);
############################################################################# ## #F WreathProductProductAction( <G>, <H> ) wreath product in product action ##
InstallGlobalFunction( WreathProductProductAction, function( G, H )
local W, domG, domI, map, I, deg, n, N, gens, gen, i, list,
p, adic, q, Val, val, rans,basegens,hgens,info,degI;
# get the domain of operation of <G> and <H> if IsPermGroup( G ) then
domG := MovedPoints( G ); elif IsGroupHomomorphism( G ) and IsPermGroup( Range( G ) ) then
domG := MovedPoints( Range( G ) );
G := Image( G ); else
Error( "WreathProductProductAction: <G> must be perm group or homomorphism" ); fi;
deg := Length( domG ); if IsPermGroup( H ) then
domI := MovedPoints( H );
map := IdentityMapping( H ); elif IsGroupHomomorphism( H ) and IsPermGroup( Range( H ) ) then
map := H;
domI := MovedPoints( Range( H ) );
H := Source( H ); else
Error( "WreathProductProductAction: <H> must be perm group or homomorphism" ); fi;
I := Image( map ); if IsEmpty( domI ) then
domI := [ 1 ]; fi;
degI := Length( domI );
n := Length( domI );
N := deg ^ n;
gens := [ ];
basegens:=List([1..n],i->[]); for gen in GeneratorsOfGroup( G ) do
val := 1; for i in [ 1 .. n ] do
Val := val * deg;
list := [ ]; for p in [ 0 .. N - 1 ] do
q := QuoInt( p mod Val, val ) + 1;
Add( list, p +
( Position( domG, domG[ q ] ^ gen ) - q ) * val );
od;
q:=PermList( list + 1 ); if not IsOne(q) then
Add(gens,q); fi;
Add(basegens[i],q);
val := Val;
od;
od;
hgens:=[]; for gen in GeneratorsOfGroup( I ) do
list := [ ]; for p in [ 0 .. N - 1 ] do
adic := [ ]; for i in [ 0 .. n - 1 ] do
adic[ Position( domI, domI[ n - i ] ^ gen ) ] := p mod deg;
p := QuoInt( p, deg );
od;
q := 0; for i in adic do
q := q * deg + i;
od;
Add( list, q );
od;
q:=PermList( list + 1 ); if not IsOne(q) then
Add(gens,q); fi;
Add(hgens,q);
od;
W := GroupByGenerators( gens, () ); # `gens' arose from `PermList'
SetSize( W, Size( G ) ^ n * Size( I ) );
# note random method
rans := Filtered( [ G, H ], i ->
IsBound( StabChainOptions( i ).random ) ); if Length( rans ) > 0then
SetStabChainOptions( W, rec( random :=
Minimum( List( rans, i -> StabChainOptions( i ).random ) ) ) ); fi;
info := rec(
groups := [G,H],
alpha := map,
I := I,
degI := degI,
productType:=true,
basegens := basegens,
base := SubgroupNC(W,Flat(basegens)),
hgens := hgens,
embeddingType := NewType(
GeneralMappingsFamily(PermutationsFamily,PermutationsFamily),
IsEmbeddingProductActionWreathProductPermGroup),
embeddings := []);
SetWreathProductInfo( W, info );
return W; end );
############################################################################## ## #M SemidirectProduct for permutation groups
## ## Use regular action ## Original version by Derek Holt, 6/9/96, in first GAP3 version of xmod ##
InstallMethod( SemidirectProduct, "generic method for permutation groups",
[ IsPermGroup, IsGroupHomomorphism, IsPermGroup ], function( R, map, S )
# Take the action of R on S by conjugation.
LS := AsSSortedList( S );
genP := [ ];
genR := GeneratorsOfGroup( R );
genS := GeneratorsOfGroup( S ); for r in genR do
aut:= Image( map, r );
L3 := List( LS, x -> Position( LS, Image( aut, x ) ) );
Add( genP, PermList( L3 ) );
od; # Check order of group at this stage, to see if the action is faithful. # If not, adjoin the action of R as a permutation group.
P := Group( genP, () ); # `genP' arose from `PermList' if ( Size( P ) <> Size( R ) ) then
ordS := Size( S );
genno := 0; for r in genR do
genno := genno + 1;
genP[ genno ] := genP[ genno ]
* PermList( Concatenation( [1..ordS], ListPerm( r ) + ordS ) );
od; fi; # Take the action of S on S by right multiplication. for s in genS do
L3 := List( LS, x -> Position( LS, x*s ) );
Add( genP, PermList( L3 ) );
od;
P := Group( genP, () ); # `genP' arose from `PermList'
info := rec( groups := [ R, S ],
lenlist := [ 0, Length( genR ), Length( genP ) ],
embeddings := [ ],
projections := true );
SetSemidirectProductInfo( P, info );
return P; end );
InstallMethod( SemidirectProduct, "Induced permutation automorphisms",
[ IsPermGroup, IsGroupHomomorphism, IsPermGroup ], function( U, map, N )
local Ugens,imgs,conj,auc,d,embn,embs,l,u,P,info;
Ugens:=GeneratorsOfGroup(U);
imgs:=List(Ugens,x->Image(map,x)); if ForAll(imgs,IsConjugatorIsomorphism) then
conj:=List(imgs,ConjugatorOfConjugatorIsomorphism);
auc:=ClosureGroup(N,conj);
d:=DirectProduct(U,auc);
embn:=Embedding(d,2);
embs:=Embedding(d,1); # images of generators of U
l:=List([1..Length(imgs)],x->Image(embn,conj[x])*Image(embs,Ugens[x]));
u:=SubgroupNC(d,l); if Size(u)=Size(U) then# so the conjugating elements don't generate # something extra # (i.e. the map U->S_N, u->conj.perm. of auto is # a hom.)
P:=ClosureGroup(Image(embn,N),l);
embs:=GroupHomomorphismByImagesNC(U,P,Ugens,l);
info := rec( groups := [ U, N ],
embeddings := [embs,RestrictedMapping(embn,N) ],
projections := RestrictedMapping(Projection(d,1),P));
SetSemidirectProductInfo( P, info );
return P; fi; fi;
TryNextMethod(); end);
############################################################################## ## #M Embedding for permutation semidirect products ##
InstallMethod( Embedding, "generic method for perm semidirect products",
true, [ IsPermGroup and HasSemidirectProductInfo, IsPosInt ], 0, function( D, i )
local info, G, genG, imgs, hom;
info := SemidirectProductInfo( D ); if IsBound( info.embeddings[i] ) then
return info.embeddings[i]; fi;
G := info.groups[i];
genG := GeneratorsOfGroup( G );
imgs := GeneratorsOfGroup( D ){[info.lenlist[i]+1 .. info.lenlist[i+1]]};
hom := GroupHomomorphismByImagesNC( G, D, genG, imgs );
SetIsInjective( hom, true );
info.embeddings[i] := hom;
return hom; end );
############################################################################## ## #M Projection for permutation semidirect products ##
InstallOtherMethod( Projection, "generic method for perm semidirect products",
true, [ IsPermGroup and HasSemidirectProductInfo ], 0, function( D )
local info, genD, G, genG, imgs, hom, ker, list;
info := SemidirectProductInfo( D ); if not IsBool( info.projections ) then
return info.projections; fi;
G := info.groups[1];
genG := GeneratorsOfGroup( G );
genD := GeneratorsOfGroup( D );
list := [ info.lenlist[2]+1 .. info.lenlist[3] ];
imgs := Concatenation( genG, List( list, j -> One( G ) ) );
hom := GroupHomomorphismByImagesNC( D, G, genD, imgs );
SetIsSurjective( hom, true );
ker := Subgroup( D, genD{ list } );
SetKernelOfMultiplicativeGeneralMapping( hom, ker );
info.projections := hom;
return hom; end );
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.