From 454c0d61ec4113eec91c6f108e59fc781860c811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Sat, 6 Feb 2016 20:27:31 +0100 Subject: [PATCH] Add MinimalNormalSubgroups and Socle for all nilpotent groups For (finite or infinite) nilpotent groups every normal subgroup intersects the center nontrivially, thus minimal normal subgroups are central. As every central subgroup is normal, minimal normal subgroups are cyclic of prime order. Hence every minimal normal subgroup is in fact a minimal normal subgroup of the socle, where socle is the Omega group of the Center for all prime divisors. Thus Socle method for finite nilpotent groups is rewritten for all nilpotent groups (test file contains examples of pcp and fp groups) using AbelianInvariants and IndependentGeneratorsOfGroup. Rank is increased so that this method would trigger before the finite solvable method. Trivial methods for elementary abelian and simple groups are added. New method for MinimalNormalSubgroups goes over the Sylows of the Socle and makes note of all minimal subgroups. Rank is increased to run this method first. Tests are added. --- lib/grp.gi | 162 +++++++++++++++--- .../opers/MinimalNormalSubgroups.tst | 126 ++++++++++++++ tst/testinstall/opers/Socle.tst | 36 ++++ 3 files changed, 299 insertions(+), 25 deletions(-) create mode 100644 tst/testinstall/opers/MinimalNormalSubgroups.tst diff --git a/lib/grp.gi b/lib/grp.gi index fd3315f82a3..54a4b12af2c 100644 --- a/lib/grp.gi +++ b/lib/grp.gi @@ -1626,43 +1626,87 @@ end ); ############################################################################# ## -#M Socle( ) . . . . . . . . . . . . . . . . for finite nilpotent groups +#M Socle( ) . . . . . . . . . . . . . . . . . . . . . for simple groups ## -InstallMethod( Socle, "for finite nilpotent groups", +InstallMethod( Socle, "for simple groups", + [ IsGroup and IsSimpleGroup ], SUM_FLAGS, IdFunc ); + +############################################################################# +## +#M Socle( ) . . . . . . . . . . . . . . . for elementary abelian groups +## +InstallMethod( Socle, "for elementary abelian groups", + [ IsGroup and IsElementaryAbelian ], SUM_FLAGS, IdFunc ); + +############################################################################# +## +#M Socle( ) . . . . . . . . . . . . . . . . . . . . for nilpotent groups +## +InstallMethod( Socle, "for nilpotent groups", [ IsGroup ], - RankFilter( IsGroup and CanComputeSize and IsFinite and - IsNilpotentGroup ) - RankFilter( IsGroup ), + RankFilter( IsGroup and IsNilpotentGroup and IsFinite ) + - RankFilter( IsGroup ), function(G) - local H, prodH; + local P, C, size, gen, abinv, indgen, i, p, q, soc; - if not CanComputeSize(G) or not IsFinite(G) - or not IsNilpotentGroup(G) then + # IsNilpotent check might error for fp-groups + if not IsAbelian(G) and not IsNilpotentGroup(G) then TryNextMethod(); fi; - prodH := TrivialSubgroup(G); - # now socle is the product of Omega of the Sylow subgroups of the center - for H in SylowSystem(Center(G)) do - prodH := ClosureSubgroupNC(prodH, Omega(H, PrimePGroup(H))); - od; + # for finite groups the usual methods are faster + # for SylowSystem and Omega + if ( CanComputeSize(G) or HasIsFinite(G) ) and IsFinite(G) then + soc := TrivialSubgroup(G); + # now socle is the product of Omega of Sylow subgroups of the center + for P in SylowSystem(Center(G)) do + soc := ClosureSubgroupNC(soc, Omega(P, PrimePGroup(P))); + od; + else + # compute generators for the torsion Omega p-subgroups of the center + C := Center(G); + gen := [ ]; + abinv := [ ]; + indgen := [ ]; + size := 1; + for i in [1..Length(AbelianInvariants(C))] do + q := AbelianInvariants(C)[i]; + if q<>0 then + p := SmallestRootInt(q); + if not IsBound(gen[p]) then + gen[p] := [ IndependentGeneratorsOfAbelianGroup(C)[i]^(q/p) ]; + else + Add(gen[p], IndependentGeneratorsOfAbelianGroup(C)[i]^(q/p)); + fi; + size := size * p; + Add(abinv, p); + Add(indgen, IndependentGeneratorsOfAbelianGroup(C)[i]^(q/p)); + fi; + od; + # Socle is the product of the torsion Omega p-groups of the center + soc := Subgroup(G, Concatenation(Compacted(gen))); + SetSize(soc, size); + SetAbelianInvariants(soc, abinv); + SetIndependentGeneratorsOfAbelianGroup(soc, indgen); + fi; # Socle is central in G, set some properties and attributes accordingly - SetIsAbelian(prodH, true); - if not HasParent(prodH) then - SetParent(prodH, G); - SetCentralizerInParent(prodH, G); - SetIsNormalInParent(prodH, true); - elif CanComputeIsSubset(G, Parent(prodH)) - and IsSubgroup(G, Parent(prodH)) then - SetCentralizerInParent(prodH, Parent(prodH)); - SetIsNormalInParent(prodH, true); - elif CanComputeIsSubset(G, Parent(prodH)) - and IsSubgroup(Parent(prodH), G) and IsNormal(Parent(prodH), G) then + SetIsAbelian(soc, true); + if not HasParent(soc) then + SetParent(soc, G); + SetCentralizerInParent(soc, G); + SetIsNormalInParent(soc, true); + elif CanComputeIsSubset(G, Parent(soc)) + and IsSubgroup(G, Parent(soc)) then + SetCentralizerInParent(soc, Parent(soc)); + SetIsNormalInParent(soc, true); + elif CanComputeIsSubset(G, Parent(soc)) + and IsSubgroup(Parent(soc), G) and IsNormal(Parent(soc), G) then # characteristic subgroup of a normal subgroup is normal - SetIsNormalInParent(prodH, true); + SetIsNormalInParent(soc, true); fi; - return prodH; + return soc; end); ############################################################################# @@ -4323,6 +4367,74 @@ InstallMethod (MinimalNormalSubgroups, end); +############################################################################# +## +#M MinimalNormalSubgroups( ) +## +InstallMethod( MinimalNormalSubgroups, "for simple groups", + [ IsGroup and IsSimpleGroup ], SUM_FLAGS, + function(G) return [ G ]; end); + + +############################################################################# +## +#M MinimalNormalSubgroups () +## +InstallMethod( MinimalNormalSubgroups, "for nilpotent groups", + [ IsGroup ], RankFilter( IsGroup and IsFinite and IsNilpotentGroup ) - RankFilter( IsGroup ), + function(G) + local soc, i, p, primes, gen, min, MinimalSubgroupsOfPGroupByGenerators; + + # IsNilpotent check might error for fp-groups + if not IsAbelian(G) and not IsNilpotentGroup(G) then + TryNextMethod(); + fi; + + MinimalSubgroupsOfPGroupByGenerators := function(G, p, gen) + # G is the big group + # p is the prime p + # gens is the generators by which the p-group is given + local min, tuples, g, h, k; + + min := [ ]; + if Length(gen[p])=1 then + Add(min, Subgroup(G, gen[p])); + else + g := Remove(gen[p]); + for tuples in IteratorOfTuples([0..p-1], Length(gen[p])) do + h := g; + for i in [1..Length(tuples)] do + h := h*gen[p][i]^tuples[i]; + od; + Add(min, Subgroup(G, [h])); + od; + Append(min, MinimalSubgroupsOfPGroupByGenerators(G, p, gen)); + fi; + + return min; + end; + + soc := Socle(G); + primes := [ ]; + gen := [ ]; + min := [ ]; + for i in [1..Length(AbelianInvariants(soc))] do + p := AbelianInvariants(soc)[i]; + AddSet(primes, p); + if not IsBound(gen[p]) then + gen[p] := [ IndependentGeneratorsOfAbelianGroup(soc)[i] ]; + else + Add(gen[p], IndependentGeneratorsOfAbelianGroup(soc)[i]); + fi; + od; + + for p in primes do + Append(min, MinimalSubgroupsOfPGroupByGenerators(G, p, gen)); + od; + return min; + end); + + ############################################################################# ## #M SmallGeneratingSet() diff --git a/tst/testinstall/opers/MinimalNormalSubgroups.tst b/tst/testinstall/opers/MinimalNormalSubgroups.tst new file mode 100644 index 00000000000..434c04db759 --- /dev/null +++ b/tst/testinstall/opers/MinimalNormalSubgroups.tst @@ -0,0 +1,126 @@ +gap> START_TEST("Socle.tst"); +gap> MinimalNormalSubgroups(Group(())); +[ ] +gap> G := Group(());; NormalSubgroups(G);; MinimalNormalSubgroups(G); +[ ] +gap> D := DihedralGroup(8);; +gap> MinimalNormalSubgroups(D) = [ Center(D) ]; +true +gap> List(MinimalNormalSubgroups(D), IdGroup); +[ [ 2, 1 ] ] +gap> D := DihedralGroup(IsFpGroup, 8);; +gap> MinimalNormalSubgroups(D) = [ Center(D) ]; +true +gap> List(MinimalNormalSubgroups(D), IdGroup); +[ [ 2, 1 ] ] +gap> D := DihedralGroup(IsPcpGroup, 8);; +gap> MinimalNormalSubgroups(D) = [ Center(D) ]; +true +gap> List(MinimalNormalSubgroups(D), IdGroup); +[ [ 2, 1 ] ] +gap> D := Group((1,3),(1,2,3,4));; +gap> MinimalNormalSubgroups(D) = [ Center(D) ]; +true +gap> List(MinimalNormalSubgroups(D), IdGroup); +[ [ 2, 1 ] ] +gap> DDD := DirectProduct(D, D, D);; +gap> List(MinimalNormalSubgroups(DDD), IdGroup); +[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ] ] +gap> Q := QuaternionGroup(8);; +gap> MinimalNormalSubgroups(Q) = [ Center(Q) ]; +true +gap> List(MinimalNormalSubgroups(Q), IdGroup); +[ [ 2, 1 ] ] +gap> MinimalNormalSubgroups(SymmetricGroup(4)) = [ Group((1,2)(3,4),(1,3)(2,4)) ]; +true +gap> List(MinimalNormalSubgroups(SymmetricGroup(5)), IdGroup); +[ [ 60, 5 ] ] +gap> List(MinimalNormalSubgroups(AlternatingGroup(5)), IdGroup); +[ [ 60, 5 ] ] +gap> G := Group((1,2),(3,4),(5,6),(7,8));; +gap> IsElementaryAbelian(G); +true +gap> Size(MinimalNormalSubgroups(G)); +15 +gap> MinimalNormalSubgroups(PrimitiveGroup(8,3)) = [ Group([ (1,7)(2,8)(3,5)(4,6), (1,3)(2,4)(5,7)(6,8), (1,2)(3,4)(5,6)(7,8) ]) ]; +true +gap> k := 5;; P := SylowSubgroup(SymmetricGroup(4*k), 2);; A := Group((4*k+1, 4*k+2, 4*k+3));; G := ClosureGroup(P, A);; +gap> Set(MinimalNormalSubgroups(G)) = Set([ Group([ (1,2)(3,4)(5,6)(7,8)(9,10)(11,12)(13,14)(15,16) ]), Group([ (17,18)(19,20) ]), Group([ (1,2)(3,4)(5,6)(7,8)(9,10)(11,12)(13,14)(15,16)(17,18)(19,20) ]), Group([ (21,22,23) ]) ]); +true +gap> A := DihedralGroup(16);; +gap> B := SmallGroup(27, 3);; +gap> C := SmallGroup(125, 4);; +gap> D := DirectProduct(A, B, C, SmallGroup(1536, 2));; +gap> List(MinimalNormalSubgroups(D), IdGroup); +[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], + [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], + [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], + [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], + [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 3, 1 ], [ 3, 1 ], [ 3, 1 ], [ 3, 1 ], + [ 5, 1 ] ] +gap> G := Group([ (4,8)(6,10), (4,6,10,8,12), (2,4,12)(6,10,8), (3,9)(4,6,10,8,12)(7,11), (3,5)(4,6,10,8,12)(9,11), (1,3,11,9,5)(4,6,10,8,12) ]);; +gap> MinimalNormalSubgroups(G) = Set([ Group([ (6,12)(8,10), (2,10)(4,12), (2,12)(6,10) ]), Group([ (5,11)(7,9), (3,9)(7,11), (1,9,5,11,7) ]) ]); +true +gap> F := AbelianPcpGroup([0,0,0]);; +gap> G := F / Subgroup(F, [(F.1*F.2)^180, (F.1*F.2^5)^168]);; +gap> MinimalNormalSubgroups(G); +[ Pcp-group with orders [ 2 ], Pcp-group with orders [ 2 ], + Pcp-group with orders [ 2 ], Pcp-group with orders [ 3 ], + Pcp-group with orders [ 3 ], Pcp-group with orders [ 3 ], + Pcp-group with orders [ 3 ], Pcp-group with orders [ 5 ], + Pcp-group with orders [ 7 ] ] +gap> F := FreeGroup("x", "y", "z");; +gap> x := F.1;; y := F.2;; z := F.3;; +gap> F := FreeGroup("x", "y", "z");; +gap> x := F.1;; y := F.2;; z := F.3;; +gap> G := F/[x^(-1)*y^(-1)*x*y, x^(-1)*z^(-1)*x*z, z^(-1)*y^(-1)*z*y, (x*y)^180, (x*y^5)^168];; +gap> Size(MinimalNormalSubgroups(G)); +9 +gap> MinimalNormalSubgroups(HeisenbergPcpGroup(3)); +[ ] +gap> for G in AllGroups(60) do NormalSubgroups(G);; Print(List(MinimalNormalSubgroups(G), IdGroup), "\n"); od; +[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ] +[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ] +[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ] +[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ] +[ [ 60, 5 ] ] +[ [ 3, 1 ], [ 5, 1 ] ] +[ [ 3, 1 ], [ 5, 1 ] ] +[ [ 3, 1 ], [ 5, 1 ] ] +[ [ 4, 2 ], [ 5, 1 ] ] +[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ] +[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ] +[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ] +[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ] +gap> G := SmallGroup(120,5);; List(MinimalNormalSubgroups(G), IdGroup); +[ [ 2, 1 ] ] +gap> G := SmallGroup(120,34);; List(MinimalNormalSubgroups(G), IdGroup); +[ [ 60, 5 ] ] +gap> G := SmallGroup(120,35);; List(MinimalNormalSubgroups(G), IdGroup); +[ [ 2, 1 ], [ 60, 5 ] ] +gap> for G in AllGroups(240) do if not IsSolvable(G) then NormalSubgroups(G);; Print(List(MinimalNormalSubgroups(G), IdGroup), "\n"); fi; od; +[ [ 2, 1 ] ] +[ [ 2, 1 ] ] +[ [ 2, 1 ], [ 60, 5 ] ] +[ [ 2, 1 ], [ 60, 5 ] ] +[ [ 2, 1 ] ] +[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ] ] +[ [ 2, 1 ], [ 60, 5 ] ] +[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 60, 5 ] ] +gap> for G in AllGroups(360) do if not IsSolvable(G) then NormalSubgroups(G);; Print(List(MinimalNormalSubgroups(G), IdGroup), "\n"); fi; od; +[ [ 2, 1 ], [ 3, 1 ] ] +[ [ 360, 118 ] ] +[ [ 3, 1 ], [ 60, 5 ] ] +[ [ 3, 1 ], [ 60, 5 ] ] +[ [ 3, 1 ], [ 60, 5 ] ] +[ [ 2, 1 ], [ 3, 1 ], [ 60, 5 ] ] +gap> G := AbelianGroup([2, 3, 4, 5, 6, 7, 8, 9, 10]);; +gap> Collected(List(Set(MinimalNormalSubgroups(G)), Size)); +[ [ 2, 31 ], [ 3, 13 ], [ 5, 6 ], [ 7, 1 ] ] +gap> G := ElementaryAbelianGroup(2^10);; +gap> Collected(List(Set(MinimalNormalSubgroups(G)), Size)); +[ [ 2, 1023 ] ] +gap> G := ElementaryAbelianGroup(7^4);; +gap> Collected(List(Set(MinimalNormalSubgroups(G)), Size)); +[ [ 7, 400 ] ] +gap> STOP_TEST("Socle.tst", 10000); diff --git a/tst/testinstall/opers/Socle.tst b/tst/testinstall/opers/Socle.tst index 7994ff82cb4..8bbd1f012bb 100644 --- a/tst/testinstall/opers/Socle.tst +++ b/tst/testinstall/opers/Socle.tst @@ -1,4 +1,6 @@ gap> START_TEST("Socle.tst"); +gap> Socle(Group(())); +Group(()) gap> D := DihedralGroup(8);; gap> Socle(D) = ClosureSubgroup(TrivialSubgroup(D), Union(Set(MinimalNormalSubgroups(D), GeneratorsOfGroup))); true @@ -6,6 +8,20 @@ gap> IdGroup(Socle(D)); [ 2, 1 ] gap> Socle(D) = Center(D); true +gap> D := DihedralGroup(IsFpGroup, 8);; +gap> Socle(D) = ClosureSubgroup(TrivialSubgroup(D), Union(Set(MinimalNormalSubgroups(D), GeneratorsOfGroup))); +true +gap> IdGroup(Socle(D)); +[ 2, 1 ] +gap> Socle(D) = Center(D); +true +gap> D := DihedralGroup(IsPcpGroup, 8);; +gap> Socle(D) = ClosureSubgroup(TrivialSubgroup(D), Union(Set(MinimalNormalSubgroups(D), GeneratorsOfGroup))); +true +gap> IdGroup(Socle(D)); +[ 2, 1 ] +gap> Socle(D) = Center(D); +true gap> D := Group((1,3),(1,2,3,4));; gap> Socle(D) = ClosureSubgroup(TrivialSubgroup(D), Union(Set(MinimalNormalSubgroups(D), GeneratorsOfGroup))); true @@ -31,6 +47,13 @@ gap> Socle(SymmetricGroup(4)) = Group((1,2)(3,4),(1,3)(2,4)); true gap> IdGroup(Socle(SymmetricGroup(5))); [ 60, 5 ] +gap> IdGroup(Socle(AlternatingGroup(5))); +[ 60, 5 ] +gap> G := Group((1,2),(3,4),(5,6),(7,8));; +gap> IsElementaryAbelian(G); +true +gap> Socle(G)=G; +true gap> Socle(PrimitiveGroup(8,3)) = Group([ (1,7)(2,8)(3,5)(4,6), (1,3)(2,4)(5,7)(6,8), (1,2)(3,4)(5,6)(7,8) ]); true gap> k := 5;; P := SylowSubgroup(SymmetricGroup(4*k), 2);; A := Group((4*k+1, 4*k+2, 4*k+3));; G := ClosureGroup(P, A);; @@ -44,8 +67,21 @@ gap> IdGroup(Socle(D)); [ 1440, 5958 ] gap> Socle(D) = Center(D); true +gap> Socle(FittingSubgroup(SymmetricGroup(4))); +Group([ (1,4)(2,3), (1,3)(2,4) ]) gap> G := Group([ (4,8)(6,10), (4,6,10,8,12), (2,4,12)(6,10,8), (3,9)(4,6,10,8,12) > (7,11), (3,5)(4,6,10,8,12)(9,11), (1,3,11,9,5)(4,6,10,8,12) ]);; gap> Socle(G) = Group([ (3,7)(5,9), (5,11)(7,9), (1,5,3)(7,11,9), (2,8,10)(4,6,12), (4,6)(10,12) ]); true +gap> F := AbelianPcpGroup([0,0,0]);; +gap> G := F / Subgroup(F, [(F.1*F.2)^180, (F.1*F.2^5)^168]);; +gap> Socle(G); +Pcp-group with orders [ 6, 210 ] +gap> F := FreeGroup("x", "y", "z");; +gap> x := F.1;; y := F.2;; z := F.3;; +gap> G := F/[x^(-1)*y^(-1)*x*y, x^(-1)*z^(-1)*x*z, z^(-1)*y^(-1)*z*y, (x*y)^180, (x*y^5)^168];; +gap> Size(Socle(G)); +1260 +gap> Socle(HeisenbergPcpGroup(3)); +Pcp-group with orders [ ] gap> STOP_TEST("Socle.tst", 10000);