Skip to content

Commit

Permalink
Add NormalHallSubgroups
Browse files Browse the repository at this point in the history
This is the second installment in the series of enhancing
StructureDescription. (The first being DirectFactorsOfGroup.)

A new global function NormalHalSubgroupFromSylows is introduced, which
computes normal Hall subgroups by computing normal closures of all Sylows.
An optional second argument "any" is recognized, in which case the function
returns the first nontrivial normal Hall subgroup, if exists, and returns
fail, otherwise. This will be used for computing semidirect decompositions,
because in this situation the Schur-Zassenhaus theorem guarantees a
complement.

NormalHallSubgroups is a new attribute, which consists of a list of all
normal Hall subgroups of a group. This is currently defined only for groups
which can compute size for all their subgroups. This check might not be
needed, e.g. the function works for DihedralGroup(IsFpGroup, 60), as well.

A test file is added.
  • Loading branch information
hungaborhorvath committed Jan 31, 2016
1 parent 7a4df09 commit d59a4db
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 0 deletions.
39 changes: 39 additions & 0 deletions lib/grp.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3287,6 +3287,45 @@ KeyDependentOperation( "SylowComplement", IsGroup, IsPosInt, "prime" );
KeyDependentOperation( "HallSubgroup", IsGroup, IsList, ReturnTrue );


#############################################################################
##
#F NormalHallSubgroupsFromSylows( <G>[, <method>] )
##
## <ManSection>
## <Func Name="NormalHallSubgroupsFromSylows" Arg="G[, method]"/>
##
## <Description>
## Computes all normal Hall subgroups, that is all normal subgroups
## <A>N</A> for which the size of <A>N</A> is relatively prime to the
## index of <A>N</A> in <A>G</A>.
##
## Sometimes it is not desirable to compute all normal Hall subgroups. The
## user can express such a wish by using the <A>method</A> <Q>"any"</Q>.
## Then NormalHallSubgroupsFromSylows returns a nontrivial normal Hall
## subgroup, if there is one, and returns fail, otherwise.
## </Description>
## </ManSection>
##
DeclareGlobalFunction( "NormalHallSubgroupsFromSylows", [ IsGroup ] );


#############################################################################
##
#A NormalHallSubgroups( <G> )
##
## <ManSection>
## <Attr Name="NormalHallSubgroups" Arg="G"/>
##
## <Description>
## Returns a list of all normal Hall subgroups, that is of all normal
## subgroups <A>N</A> for which the size of <A>N</A> is relatively prime
## to the index of <A>N</A> in <A>G</A>.
## </Description>
## </ManSection>
##
DeclareAttribute( "NormalHallSubgroups", IsGroup );


#############################################################################
##
#O NrConjugacyClassesInSupergroup( <U>, <G> )
Expand Down
121 changes: 121 additions & 0 deletions lib/grp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -2813,6 +2813,127 @@ InstallMethod (HallSubgroupOp, "test trivial cases", true,
end);


#############################################################################
##
#M NormalHallSubgroups( <G> )
##
InstallGlobalFunction( NormalHallSubgroupsFromSylows, function( arg )

local G, method, primes, edges, i, j, S, N, UpSets, part, U, NHs;

if Length(arg) = 1 and IsGroup(arg[1]) then
G := arg[1];
method := "all";
elif Length(arg) = 2 and IsGroup(arg[1]) and arg[2] in ["all", "any"] then
G := arg[1];
method := arg[2];
else
Error("usage: NormalHallSubgroupsFromSylows( <G> [, <mthd> ] )");
fi;
if HasNormalHallSubgroups(G) then
if method = "any" then
for N in NormalHallSubgroups(G) do
if not IsTrivial(N) and G<>N then
return N;
fi;
od;
return fail;
else
return NormalHallSubgroups(G);
fi;
elif method ="any" and Length(ComputedHallSubgroups(G))>0 then
i := 0;
while i < Length(ComputedHallSubgroups(G)) do
i := i+2;
N := ComputedHallSubgroups(G)[i];
if N <> fail and IsNormal(G, N) then
return N;
fi;
od;
# no need to factor Size(G) if G is a p-group
elif IsTrivial(G) or IsPGroup(G) then
SetNormalHallSubgroups(G, Set([ TrivialSubgroup(G), G ]));
if method = "any" then
return fail;
else
return Set([ TrivialSubgroup(G), G ]);
fi;
## ? might take a long time to check if G is simple ?
# simple groups have no nontrivial normal subgroups
elif IsSimpleGroup(G) then
SetNormalHallSubgroups(G, Set([ TrivialSubgroup(G), G ]));
if method = "any" then
return fail;
else
return Set([ TrivialSubgroup(G), G ]);
fi;
fi;
primes := PrimeDivisors(Size(G));
edges := [];
S := [];
# create edges of directed graph
for i in [1..Length(primes)] do
# S[i] is the normal closure of the Sylow subgroup for primes[i]
if IsNilpotentGroup(G) then
S[i] := SylowSubgroup(G, primes[i]);
else
S[i] := NormalClosure(G, SylowSubgroup(G, primes[i]));
fi;
if IsNilpotentGroup(G) then
edges[i] := [i];
else
edges[i] := [];
# factoring Size(S[i]) probably takes more time
for j in [1..Length(primes)] do
# i -> j is an edge if Size(S[i]) has prime divisor primes[j]
if Size(S[i]) mod primes[j] = 0 then
AddSet(edges[i], j);
fi;
od;
fi;
if method = "any" and edges[i] = [i] then
return S[i];
fi;
od;
# compute the reachable points from every point of the digraph
# and then collapse same sets
# the relation defined by edges is already reflexive
UpSets := Set(Successors(TransitiveClosureBinaryRelation(
BinaryRelationOnPoints(edges))));
NHs := [ TrivialSubgroup(G), G ];
for part in IteratorOfCombinations(UpSets) do
U := Union(part);
# trivial subgroup and G should not be added again
if U <> [] and U <> [1..Length(primes)] then
N := TrivialSubgroup(G);
for i in Union(part) do
N := ClosureGroup(N, S[i]);
od;
if method = "any" then
return N;
else
AddSet(NHs, N);
fi;
fi;
od;
if method = "any" then
SetNormalHallSubgroups(G, Set([ TrivialSubgroup(G), G ]));
return fail;
else
SetNormalHallSubgroups(G, NHs);
return NHs;
fi;
end);

InstallMethod( NormalHallSubgroups,
"by normal closure of Sylow subgroups", true,
[ IsGroup and CanComputeSizeAnySubgroup and IsFinite ], 0,

function( G )
return NormalHallSubgroupsFromSylows(G, "all");
end );


############################################################################
##
#M SylowComplementOp (<grp>, <p>)
Expand Down
78 changes: 78 additions & 0 deletions tst/testinstall/opers/NormalHallSubgroups.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
gap> START_TEST("NormalHallSubgroups.tst");
gap> for G in AllGroups(60) do Print(List(NormalHallSubgroups(G), IdGroup), "\n"); od;
[ [ 1, 1 ], [ 5, 1 ], [ 3, 1 ], [ 15, 1 ], [ 12, 1 ], [ 60, 1 ] ]
[ [ 1, 1 ], [ 3, 1 ], [ 5, 1 ], [ 15, 1 ], [ 20, 1 ], [ 60, 2 ] ]
[ [ 1, 1 ], [ 3, 1 ], [ 5, 1 ], [ 15, 1 ], [ 60, 3 ] ]
[ [ 1, 1 ], [ 3, 1 ], [ 5, 1 ], [ 15, 1 ], [ 4, 1 ], [ 12, 2 ], [ 20, 2 ],
[ 60, 4 ] ]
[ [ 1, 1 ], [ 60, 5 ] ]
[ [ 1, 1 ], [ 3, 1 ], [ 5, 1 ], [ 15, 1 ], [ 20, 3 ], [ 60, 6 ] ]
[ [ 1, 1 ], [ 3, 1 ], [ 5, 1 ], [ 15, 1 ], [ 60, 7 ] ]
[ [ 1, 1 ], [ 3, 1 ], [ 5, 1 ], [ 15, 1 ], [ 60, 8 ] ]
[ [ 1, 1 ], [ 5, 1 ], [ 4, 2 ], [ 12, 3 ], [ 20, 5 ], [ 60, 9 ] ]
[ [ 1, 1 ], [ 3, 1 ], [ 5, 1 ], [ 20, 4 ], [ 15, 1 ], [ 60, 10 ] ]
[ [ 1, 1 ], [ 5, 1 ], [ 3, 1 ], [ 12, 4 ], [ 15, 1 ], [ 60, 11 ] ]
[ [ 1, 1 ], [ 3, 1 ], [ 5, 1 ], [ 15, 1 ], [ 60, 12 ] ]
[ [ 1, 1 ], [ 4, 2 ], [ 3, 1 ], [ 12, 5 ], [ 5, 1 ], [ 20, 5 ], [ 15, 1 ],
[ 60, 13 ] ]
gap> for G in AllGroups(60) do primes := PrimeDivisors(Size(G)); l := []; for pi in IteratorOfCombinations(primes) do N := HallSubgroup(G, pi); if N<>fail and IsGroup(N) and IsNormal(G, N) then AddSet(l, N); fi; od; if l <> NormalHallSubgroups(G) then Print(IdGroup(G), "\n"); fi; od;
gap> List(AllSmallGroups(168), G -> List(NormalHallSubgroups(G), Size));
[ [ 1, 7, 21, 56, 168 ], [ 1, 8, 7, 21, 56, 168 ], [ 1, 7, 3, 21, 24, 168 ],
[ 1, 3, 7, 21, 56, 168 ], [ 1, 3, 7, 21, 168 ],
[ 1, 3, 7, 21, 8, 24, 56, 168 ], [ 1, 7, 21, 56, 168 ],
[ 1, 7, 21, 56, 168 ], [ 1, 7, 21, 56, 168 ], [ 1, 7, 21, 56, 168 ],
[ 1, 7, 21, 56, 168 ], [ 1, 3, 7, 21, 168 ], [ 1, 3, 7, 21, 168 ],
[ 1, 3, 7, 21, 168 ], [ 1, 3, 7, 21, 168 ], [ 1, 3, 7, 21, 168 ],
[ 1, 3, 7, 21, 168 ], [ 1, 3, 7, 21, 168 ], [ 1, 8, 7, 21, 56, 168 ],
[ 1, 8, 7, 21, 56, 168 ], [ 1, 8, 7, 21, 56, 168 ],
[ 1, 7, 8, 24, 56, 168 ], [ 1, 7, 8, 56, 168 ], [ 1, 3, 7, 21, 56, 168 ],
[ 1, 3, 7, 21, 56, 168 ], [ 1, 3, 7, 21, 56, 168 ],
[ 1, 3, 7, 21, 56, 168 ], [ 1, 3, 7, 21, 56, 168 ],
[ 1, 7, 3, 21, 24, 168 ], [ 1, 7, 3, 21, 24, 168 ],
[ 1, 7, 3, 21, 24, 168 ], [ 1, 7, 3, 21, 24, 168 ],
[ 1, 7, 3, 21, 24, 168 ], [ 1, 3, 7, 21, 168 ], [ 1, 3, 7, 21, 168 ],
[ 1, 3, 7, 21, 168 ], [ 1, 3, 7, 21, 168 ], [ 1, 3, 7, 21, 168 ],
[ 1, 3, 7, 21, 8, 24, 56, 168 ], [ 1, 3, 7, 21, 8, 24, 56, 168 ],
[ 1, 3, 7, 21, 8, 24, 56, 168 ], [ 1, 168 ], [ 1, 8, 56, 168 ],
[ 1, 3, 8, 24, 56, 168 ], [ 1, 7, 24, 168 ], [ 1, 7, 168 ],
[ 1, 7, 56, 21, 168 ], [ 1, 7, 56, 168 ], [ 1, 7, 56, 168 ],
[ 1, 3, 7, 21, 168 ], [ 1, 8, 7, 56, 21, 168 ], [ 1, 7, 8, 24, 56, 168 ],
[ 1, 8, 7, 56, 168 ], [ 1, 3, 7, 56, 21, 168 ], [ 1, 7, 3, 24, 21, 168 ],
[ 1, 3, 7, 21, 168 ], [ 1, 8, 3, 24, 7, 56, 21, 168 ] ]
gap> for G in AllGroups(168) do primes := PrimeDivisors(Size(G)); l := []; for pi in IteratorOfCombinations(primes) do N := HallSubgroup(G, pi); if N<>fail and IsGroup(N) and IsNormal(G, N) then AddSet(l, N); fi; od; if l <> NormalHallSubgroups(G) then Print(IdGroup(G), "\n"); fi; od;
gap> List(AllPrimitiveGroups(DegreeAction, 8), G -> List(NormalHallSubgroups(G), Size));
[ [ 1, 56, 8 ], [ 1, 168, 56, 8 ], [ 1, 1344 ], [ 1, 168 ], [ 1, 336 ],
[ 1, 20160 ], [ 1, 40320 ] ]
gap> List(NormalHallSubgroups(PrimitiveGroup(8,2)), Size);
[ 1, 168, 56, 8 ]
gap> Positions(List(AllTransitiveGroups(DegreeAction, 6), G -> NormalHallSubgroupsFromSylows(G, "any")), fail);
[ 7, 8, 11, 12, 14, 15, 16 ]
gap> N := PSL(2,32);; aut := SylowSubgroup(AutomorphismGroup(N),5);;
gap> G := SemidirectProduct(aut, N);;
gap> Size(NormalHallSubgroupsFromSylows(G, "any"));
32736
gap> A4 := AlternatingGroup(4);;
gap> HallSubgroup(A4, [2])=Group((1,2)(3,4),(1,3)(2,4));
true
gap> HallSubgroup(A4, [3]);; Length(ComputedHallSubgroups(A4));
4
gap> NormalHallSubgroupsFromSylows(A4, "any")=Group((1,2)(3,4),(1,3)(2,4));
true
gap> D := DihedralGroup(8);; NormalHallSubgroupsFromSylows(D, "any");
fail
gap> HasNormalHallSubgroups(D);
true
gap> NormalHallSubgroupsFromSylows(D)=[TrivialSubgroup(D), D];
true
gap> NormalHallSubgroupsFromSylows(D, "any");
fail
gap> D := DihedralGroup(12);;
gap> List(NormalHallSubgroups(D), Size);
[ 1, 3, 12 ]
gap> Size(NormalHallSubgroupsFromSylows(D, "any"));
3
gap> NormalHallSubgroupsFromSylows(Group(()), "any");
fail
gap> Length(NormalHallSubgroups(Group(())));
1
gap> STOP_TEST("NormalHallSubgroups.tst", 10000);

0 comments on commit d59a4db

Please sign in to comment.