From 439160318d80d86604909e1e806010d16454d8cf Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 5 Aug 2026 10:00:18 +0200 Subject: [PATCH] Document `IsFrattiniFree` and add methods for computing it The property IsFrattiniFree was declared in grppcaut.gd but undocumented and without any methods, so it could only ever be used after something had set it explicitly. Move the declaration next to FrattiniSubgroup in grp.gd, document it, and install methods for finite groups. For a finite nilpotent group the property holds if and only if all Sylow subgroups are elementary abelian, which needs no subgroup computations at all. The generic method first checks whether the group order is squarefree, and otherwise uses that Phi(N) <= Phi(G) for N normal in G: applied to the Fitting subgroup this rules out most groups without ever looking at maximal subgroups, and for nilpotent groups it decides the question outright. Only then is Phi(G) computed. Conversely, a known Frattini subgroup decides the property, and a group known to be Frattini-free has a trivial one. The new implication that a finite nilpotent Frattini-free group is abelian also shows up in the documented example output of ShowImpliedFilters, which is adjusted accordingly. Note that morpheus.gi and grppcext.gi still guard their use of the property with HasIsFrattiniFree. Now that it is computable, dropping that guard in morpheus.gi would let solvable groups use the faster AutomorphismGroupFrattFreeGroup path, but that affects every solvable automorphism group computation and is left for a separate change. Prepared with the help of Claude Code (Opus 5), which wrote the implementation, documentation and tests, and ran the test suites. Co-Authored-By: Claude Opus 5 --- doc/ref/groups.xml | 1 + lib/grp.gd | 55 ++++++++++++ lib/grp.gi | 52 ++++++++++++ lib/grppcaut.gd | 7 +- lib/methwhy.g | 8 ++ tst/testinstall/opers/IsFrattiniFree.tst | 104 +++++++++++++++++++++++ 6 files changed, 221 insertions(+), 6 deletions(-) create mode 100644 tst/testinstall/opers/IsFrattiniFree.tst diff --git a/doc/ref/groups.xml b/doc/ref/groups.xml index e44399d007..116c02838f 100644 --- a/doc/ref/groups.xml +++ b/doc/ref/groups.xml @@ -332,6 +332,7 @@ as they depend on a parameter. <#Include Label="IsCyclic"> <#Include Label="IsElementaryAbelian"> +<#Include Label="IsFrattiniFree"> <#Include Label="IsNilpotentGroup"> <#Include Label="NilpotencyClassOfGroup"> <#Include Label="IsPerfectGroup"> diff --git a/lib/grp.gd b/lib/grp.gd index a0e4a8afa0..1919a8a6c3 100644 --- a/lib/grp.gd +++ b/lib/grp.gd @@ -1834,6 +1834,7 @@ DeclareAttribute( "PrefrattiniSubgroup", IsGroup ); ## ## The Frattini subgroup of a group G is the intersection of all ## maximal subgroups of G. +## See also . ## FrattiniSubgroup(g); ## Group(()) @@ -1845,6 +1846,60 @@ DeclareAttribute( "PrefrattiniSubgroup", IsGroup ); DeclareAttribute( "FrattiniSubgroup", IsGroup ); +############################################################################# +## +#P IsFrattiniFree( ) +## +## <#GAPDoc Label="IsFrattiniFree"> +## +## +## +## +## A group is called Frattini-free if its Frattini subgroup +## (see ) is trivial. +##

+## Methods for this property are only installed for finite groups. +## Note that a finite nilpotent group is Frattini-free if and only if all +## of its Sylow subgroups are elementary abelian, and that a finite group +## of squarefree order is always Frattini-free. +## IsFrattiniFree( SymmetricGroup( 4 ) ); +## true +## gap> IsFrattiniFree( CyclicGroup( 6 ) ); +## true +## gap> IsFrattiniFree( CyclicGroup( 4 ) ); +## false +## gap> IsFrattiniFree( QuaternionGroup( 8 ) ); +## false +## ]]> +## +## +## <#/GAPDoc> +## +DeclareProperty( "IsFrattiniFree", IsGroup ); + +InstallIsomorphismMaintenance( IsFrattiniFree, IsGroup, IsGroup ); + +InstallTrueMethod( IsFrattiniFree, IsGroup and IsTrivial ); + +# In an (infinite dimensional) vector space over a field with p elements the +# hyperplanes intersect trivially. +InstallTrueMethod( IsFrattiniFree, IsGroup and IsElementaryAbelian ); + +# A nontrivial finite group has a maximal subgroup, hence its Frattini +# subgroup is a proper normal subgroup and thus trivial if the group +# is simple. +InstallTrueMethod( IsFrattiniFree, IsGroup and IsFinite and IsSimpleGroup ); + +# For a finite p-group P we have Phi(P) = P'P^p, hence P is Frattini-free +# if and only if it is elementary abelian; a finite nilpotent group is the +# direct product of its Sylow subgroups. +InstallTrueMethod( IsElementaryAbelian, + IsGroup and IsFinite and IsPGroup and IsFrattiniFree ); +InstallTrueMethod( IsCommutative, + IsGroup and IsFinite and IsNilpotentGroup and IsFrattiniFree ); + + ############################################################################# ## #A InvariantForm( ) diff --git a/lib/grp.gi b/lib/grp.gi index cadc69b9f4..d60036c0d7 100644 --- a/lib/grp.gi +++ b/lib/grp.gi @@ -1641,6 +1641,58 @@ local m; return m; end); +InstallMethod( FrattiniSubgroup, "for Frattini-free groups", + [ IsGroup and IsFrattiniFree ], SUM_FLAGS, + TrivialSubgroup ); + + +############################################################################# +## +#M IsFrattiniFree( ) . . . . . . . is the Frattini subgroup trivial ? +## +InstallMethod( IsFrattiniFree, "for groups with known Frattini subgroup", + [ IsGroup and HasFrattiniSubgroup ], SUM_FLAGS, + G -> IsTrivial( FrattiniSubgroup( G ) ) ); + +InstallMethod( IsFrattiniFree, "for finite nilpotent groups", + [ IsGroup and IsFinite and IsNilpotentGroup ], +function(G) + # A finite nilpotent group is the direct product of its Sylow subgroups, + # and for a finite p-group P we have Phi(P) = P'P^p. Hence Phi(G) is + # trivial if and only if all Sylow subgroups of G are elementary abelian, + # i.e., if and only if G is abelian of squarefree exponent. + return IsAbelian(G) and IsDuplicateFree(FactorsInt(Exponent(G))); +end); + +InstallMethod( IsFrattiniFree, "generic method for finite groups", + [ IsGroup and IsFinite ], +function(G) +local n, F; + # A group of squarefree order is Frattini-free. + n := Size(G); + if IsDuplicateFree(FactorsInt(n)) then + return true; + fi; + + # If N is normal in G then Phi(N) <= Phi(G). Applied to the nilpotent + # normal subgroup F = F(G) this shows that G can only be Frattini-free if + # F is abelian of squarefree exponent. Deciding this usually is much + # cheaper than computing Phi(G). + F := FittingSubgroup(G); + if not (IsAbelian(F) and IsDuplicateFree(FactorsInt(Exponent(F)))) then + return false; + fi; + + # if G = F(G), i.e., if G is nilpotent, this criterion is also sufficient + if Size(F) = n then + return true; + fi; + + return IsTrivial(FrattiniSubgroup(G)); +end); + +RedispatchOnCondition( IsFrattiniFree, true, [IsGroup], [IsFinite], 0); + ############################################################################# ## diff --git a/lib/grppcaut.gd b/lib/grppcaut.gd index 968e6597b9..38c880535c 100644 --- a/lib/grppcaut.gd +++ b/lib/grppcaut.gd @@ -11,12 +11,7 @@ DeclareGlobalFunction("SpaceAndOrbitStabilizer"); -############################################################################# -## -#P IsFrattiniFree -## -DeclareProperty( "IsFrattiniFree", IsGroup ); - +# for IsFrattiniFree see grp.gd DeclareGlobalFunction("AutomorphismGroupNilpotentGroup"); DeclareGlobalFunction("AutomorphismGroupSolvableGroup"); diff --git a/lib/methwhy.g b/lib/methwhy.g index 633c5da75a..78fdfcd9cb 100644 --- a/lib/methwhy.g +++ b/lib/methwhy.g @@ -318,6 +318,14 @@ end); ## +IsFinitelyGeneratedGroup ## IsPolycyclicGroup ## +## +IsFinite +## +IsMagmaWithInverses +## +IsAssociative +## +IsFrattiniFree +## IsCommutative +## IsMonomialGroup +## IsPolycyclicGroup +## ## ]]> ## ## diff --git a/tst/testinstall/opers/IsFrattiniFree.tst b/tst/testinstall/opers/IsFrattiniFree.tst new file mode 100644 index 0000000000..027fd4faf8 --- /dev/null +++ b/tst/testinstall/opers/IsFrattiniFree.tst @@ -0,0 +1,104 @@ +gap> START_TEST("IsFrattiniFree.tst"); + +# +gap> IsFrattiniFree(TrivialGroup()); +true +gap> IsFrattiniFree(Group(())); +true + +# abelian groups: Frattini-free iff the exponent is squarefree +gap> List([1..12], n -> IsFrattiniFree(CyclicGroup(n))); +[ true, true, true, false, true, true, true, false, false, true, true, false ] +gap> IsFrattiniFree(AbelianGroup([2,2,3,5])); +true +gap> IsFrattiniFree(AbelianGroup([2,2,3,9])); +false + +# p-groups: Frattini-free iff elementary abelian +gap> IsFrattiniFree(ElementaryAbelianGroup(27)); +true +gap> IsFrattiniFree(DihedralGroup(8)); +false +gap> IsFrattiniFree(QuaternionGroup(8)); +false +gap> IsFrattiniFree(ExtraspecialGroup(27,3)); +false + +# nilpotent groups: Frattini-free iff all Sylow subgroups are elementary abelian +gap> G := DirectProduct(ElementaryAbelianGroup(4), ElementaryAbelianGroup(9));; +gap> IsNilpotentGroup(G); +true +gap> IsFrattiniFree(G); +true +gap> G := DirectProduct(ElementaryAbelianGroup(4), CyclicGroup(9));; +gap> IsNilpotentGroup(G); +true +gap> IsFrattiniFree(G); +false + +# groups of squarefree order are Frattini-free +gap> IsFrattiniFree(SymmetricGroup(3)); +true +gap> IsFrattiniFree(AlternatingGroup(4)); +true +gap> IsFrattiniFree(Group((1,2,3,4,5),(2,3,5,4))); # Frobenius group of order 20 +true + +# simple groups are Frattini-free +gap> IsFrattiniFree(AlternatingGroup(5)); +true +gap> IsFrattiniFree(PSL(3,2)); +true +gap> IsFrattiniFree(SL(2,5)); +false + +# +gap> IsFrattiniFree(SymmetricGroup(4)); +true +gap> IsFrattiniFree(SymmetricGroup(IsPcGroup, 4)); +true +gap> IsFrattiniFree(GL(2,3)); +false +gap> IsFrattiniFree(DirectProduct(AlternatingGroup(5), CyclicGroup(4))); +false + +# the property agrees with the definition +#@if IsPackageMarkedForLoading( "smallgrp", "" ) +gap> ForAll([1..100], n -> ForAll([1..NrSmallGroups(n)], +> i -> IsFrattiniFree(SmallGroup(n,i)) +> = IsTrivial(FrattiniSubgroup(SmallGroup(n,i))))); +true +#@fi + +# knowing the property makes computing the Frattini subgroup trivial +gap> G := SymmetricGroup(5);; +gap> SetIsFrattiniFree(G, true); +gap> FrattiniSubgroup(G); +Group(()) + +# conversely, a known Frattini subgroup decides the property, also for +# groups which are not known to be finite +gap> G := FreeGroup(2);; +gap> SetFrattiniSubgroup(G, TrivialSubgroup(G)); +gap> IsFrattiniFree(G); +true + +# implied properties +gap> G := Group((1,2,3,4,5,6,7),(2,3,5)(4,7,6));; +gap> IsFrattiniFree(G); +true +gap> HasIsElementaryAbelian(G); +false +gap> G := AbelianGroup(IsPermGroup, [7,7]);; +gap> IsPGroup(G) and IsFrattiniFree(G); +true +gap> HasIsElementaryAbelian(G) and IsElementaryAbelian(G); +true +gap> G := AbelianGroup(IsPermGroup, [6,6]);; +gap> IsNilpotentGroup(G) and IsFrattiniFree(G); +true +gap> HasIsCommutative(G) and IsCommutative(G); +true + +# +gap> STOP_TEST("IsFrattiniFree.tst");