Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/ref/pcgs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ series. See also Section <Ref Sect="Special Pcgs"/> for a more explicit possibil
<#Include Label="ChiefNormalSeriesByPcgs">
<#Include Label="IndicesNormalSteps">
<#Include Label="NormalSeriesByPcgs">
<#Include Label="PcgsSeriesInfo">
<#Include Label="IndicesNormalStepsBounded">

</Section>

Expand Down
24 changes: 16 additions & 8 deletions lib/claspcgs.gi
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ local G, home, # the group and the home pcgs
step, # counter looping over <eas>
K, L, # members of <eas>
indstep, # indice normal steps
info, # pcgs and indices of the series used
Ldep, # depth of L in pcgs
Kp,mK,Lp,mL, # induced and modulo pcgs's
LcapH,KcapH, # intersections
Expand Down Expand Up @@ -627,17 +628,22 @@ local G, home, # the group and the home pcgs
# we prescribed a series
home:=opt.pcgs;
eas:=EANormalSeriesByPcgs(home);
indstep:=IndicesEANormalSteps(home);

cent:=false;

elif IsPGroup(G) then
home:=PcgsPCentralSeriesPGroup(G);
info:=PcgsPCentralSeriesPGroupInfo(G);
home:=info.pcgs;
eas:=PCentralNormalSeriesByPcgsPGroup(home);
indstep:=info.indices;

cent:=ReturnTrue;
else
home:=PcgsElementaryAbelianSeries(G);
info:=PcgsElementaryAbelianSeriesInfo(G);
home:=info.pcgs;
eas:=EANormalSeriesByPcgs(home);
indstep:=info.indices;

cent:=function(cl, N, L)
return ForAll(N, k -> ForAll
Expand All @@ -657,10 +663,9 @@ local G, home, # the group and the home pcgs
if cent=false then
cent:=PcClassFactorCentralityTest;
fi;
indstep:=IndicesEANormalSteps(home);

# is the series large (but can be rectified)?
step:=IndicesEANormalStepsBounded(home,2^15);
step:=IndicesNormalStepsBounded(home,indstep,2^15);
if indstep<>step then
indstep:=step;
eas:=List(indstep,x->SubgroupByPcgs(GroupOfPcgs(home),
Expand Down Expand Up @@ -990,6 +995,7 @@ local G,home, # the group and the home pcgs
step, # counter looping over <eas>
K, L, # members of <eas>
indstep, # indice normal steps
info, # pcgs and indices of the series used
Ldep, # depth of L in pcgs
Kp,Lp,mL, # induced and modulo pcgs's
N, cent, # elementary abelian factor, for affine action
Expand Down Expand Up @@ -1024,21 +1030,23 @@ local G,home, # the group and the home pcgs
# w.r.t. <homepcgs>.

if IsPGroup(G) then
home:=PcgsPCentralSeriesPGroup(G);
info:=PcgsPCentralSeriesPGroupInfo(G);
home:=info.pcgs;
eas:=PCentralNormalSeriesByPcgsPGroup(home);

cent:=ReturnTrue;
else
home:=PcgsElementaryAbelianSeries(G);
info:=PcgsElementaryAbelianSeriesInfo(G);
home:=info.pcgs;
eas:=EANormalSeriesByPcgs(home);

cent:=PcClassFactorCentralityTest;
fi;

indstep:=IndicesEANormalSteps(home);
indstep:=info.indices;

# is the series large (but can be rectified)?
step:=IndicesEANormalStepsBounded(home,2^15);
step:=IndicesNormalStepsBounded(home,indstep,2^15);
if indstep<>step then
indstep:=step;
eas:=List(indstep,x->SubgroupByPcgs(GroupOfPcgs(home),
Expand Down
18 changes: 11 additions & 7 deletions lib/grppc.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,7 @@ local G, home, # the supergroup (of <H> and <U>), the home pcgs
N, cent, # elementary abelian factor, for affine action
cls, # classes in range/source of homomorphism
opr, # (elm^opr)=cls.representative
nexpo,indstep,Ldep,allcent;
nexpo,indstep,info,Ldep,allcent;

# Treat the case of a trivial group.
if IsTrivial( U ) then
Expand All @@ -1294,16 +1294,18 @@ local G, home, # the supergroup (of <H> and <U>), the home pcgs
# w.r.t. <home>.

if IsPGroup( G ) then
home:=PcgsCentralSeries(G);
info:=PcgsCentralSeriesInfo(G);
home:=info.pcgs;
eas:=CentralNormalSeriesByPcgs(home);
cent:=ReturnTrue;
else
home:=PcgsElementaryAbelianSeries(G);
info:=PcgsElementaryAbelianSeriesInfo(G);
home:=info.pcgs;
eas:=EANormalSeriesByPcgs(home);
cent:=PcClassFactorCentralityTest;

fi;
indstep:=IndicesEANormalSteps(home);
indstep:=info.indices;

Hp:=InducedPcgs(home,H);

Expand Down Expand Up @@ -1451,7 +1453,7 @@ local G, # common parent
KcapH,LcapH, # pcgs's of intersections with <H>
N, cent, # elementary abelian factor, for affine action
tra, # transversal for candidates
nexpo,indstep,Ldep,allcent,
nexpo,indstep,info,Ldep,allcent,
cl, i; # loop variables

# Treat trivial cases.
Expand Down Expand Up @@ -1479,10 +1481,12 @@ local G, # common parent

eas:=fail;
if IsPGroup( G ) then
home:=PcgsPCentralSeriesPGroup(G);
info:=PcgsPCentralSeriesPGroupInfo(G);
home:=info.pcgs;
eas:=PCentralNormalSeriesByPcgsPGroup(home);
if NT in eas then
cent := ReturnTrue;
indstep:=info.indices;
else
eas:=fail; # useless
fi;
Expand All @@ -1492,8 +1496,8 @@ local G, # common parent
home:=PcgsElementaryAbelianSeries([G,NT]);
eas:=EANormalSeriesByPcgs(home);
cent:=PcClassFactorCentralityTest;
indstep:=IndicesEANormalSteps(home);
fi;
indstep:=IndicesEANormalSteps(home);

# series to NT
ea2:=List(eas,i->ClosureGroup(NT,i));
Expand Down
82 changes: 82 additions & 0 deletions lib/pcgs.gd
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,88 @@ DeclareAttribute( "IndicesNormalSteps", IsPcgs );
##
DeclareAttribute( "NormalSeriesByPcgs", IsPcgs);


#############################################################################
##
#A PcgsElementaryAbelianSeriesInfo( <G> )
#A PcgsCentralSeriesInfo( <G> )
#A PcgsPCentralSeriesPGroupInfo( <G> )
#A PcgsChiefSeriesInfo( <G> )
#O PcgsSeriesInfo( <filt>, <G> )
##
## <#GAPDoc Label="PcgsSeriesInfo">
## <ManSection>
## <Heading>Pcgs together with the indices of its series</Heading>
## <Attr Name="PcgsElementaryAbelianSeriesInfo" Arg='G'/>
## <Attr Name="PcgsCentralSeriesInfo" Arg='G'/>
## <Attr Name="PcgsPCentralSeriesPGroupInfo" Arg='G'/>
## <Attr Name="PcgsChiefSeriesInfo" Arg='G'/>
## <Oper Name="PcgsSeriesInfo" Arg='filt, G'/>
##
## <Description>
## These attributes return a record with the components <C>pcgs</C>, a pcgs
## for <A>G</A> refining a normal series of the kind in question, and
## <C>indices</C>, the list of indices in this pcgs at which the steps of
## that series start, as described for
## <Ref Attr="IndicesEANormalSteps"/>.
## <P/>
## Obtaining both from one call is preferable to obtaining the pcgs and
## then asking it for its indices: a pcgs can belong to several series, and
## the indices stored on it need not be the ones of the series that was
## asked for.
## <P/>
## <Ref Oper="PcgsSeriesInfo"/> dispatches on <A>filt</A>, which must be one
## of the properties <Ref Prop="IsPcgsElementaryAbelianSeries"/>,
## <Ref Prop="IsPcgsCentralSeries"/>,
## <Ref Prop="IsPcgsPCentralSeriesPGroup"/> or
## <Ref Prop="IsPcgsChiefSeries"/>, and returns what the corresponding
## attribute returns. It is a tag based operation
## (see <Ref Func="DeclareTagBasedOperation"/>), so a package can support
## further kinds of series by installing a method for its own property.
## <P/>
## <Example><![CDATA[
## gap> G := DihedralGroup( 16 );;
## gap> info := PcgsSeriesInfo( IsPcgsCentralSeries, G );;
## gap> info.indices = PcgsCentralSeriesInfo( G ).indices;
## true
## gap> info.indices = IndicesCentralNormalSteps( info.pcgs );
## true
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareAttribute( "PcgsElementaryAbelianSeriesInfo", IsGroup );
DeclareAttribute( "PcgsCentralSeriesInfo", IsGroup );
DeclareAttribute( "PcgsPCentralSeriesPGroupInfo", IsGroup );
DeclareAttribute( "PcgsChiefSeriesInfo", IsGroup );

DeclareTagBasedOperation( "PcgsSeriesInfo", [ IsOperation, IsGroup ] );


#############################################################################
##
#F IndicesNormalStepsBounded( <pcgs>, <indices>, <bound> )
##
## <#GAPDoc Label="IndicesNormalStepsBounded">
## <ManSection>
## <Func Name="IndicesNormalStepsBounded" Arg='pcgs, indices, bound'/>
##
## <Description>
## Let <A>indices</A> be the indices of the steps of a normal series
## refined by <A>pcgs</A>. This function returns a refinement of
## <A>indices</A>, aiming to ensure that no factor of the series is larger
## than <A>bound</A>, without changing <A>pcgs</A>.
## <P/>
## <Ref Func="IndicesEANormalStepsBounded"/> is the special case in which
## the indices are taken from <Ref Attr="IndicesEANormalSteps"/>.
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction( "IndicesNormalStepsBounded" );


#############################################################################
##
#P IsPrimeOrdersPcgs( <pcgs> )
Expand Down
51 changes: 48 additions & 3 deletions lib/pcgs.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1488,12 +1488,57 @@ InstallPcgsSeriesFromIndices(PCentralNormalSeriesByPcgsPGroup,

#############################################################################
##
#M IndicesEANormalStepsBounded( <pcgs>,<bound> )
#M PcgsElementaryAbelianSeriesInfo( <G> ) . . . . pcgs and its own indices
#M PcgsCentralSeriesInfo( <G> )
#M PcgsPCentralSeriesPGroupInfo( <G> )
#M PcgsChiefSeriesInfo( <G> )
#M PcgsSeriesInfo( <filt>, <G> )
##
## Each kind asks for the indices belonging to *its own* series, rather
## than for `IndicesEANormalSteps' which a pcgs may carry for a different
## series it also belongs to.
##
BindGlobal( "InstallPcgsSeriesInfo", function( info, pcgsattr, indices, filt )

InstallMethod( info, "from pcgs and its indices", [ IsGroup ],
function( G )
local pcgs;
pcgs:= pcgsattr( G );
return rec( pcgs:= pcgs, indices:= indices( pcgs ) );
end );

InstallTagBasedMethod( PcgsSeriesInfo, filt, { f, G } -> info( G ) );

end );

InstallPcgsSeriesInfo( PcgsElementaryAbelianSeriesInfo,
PcgsElementaryAbelianSeries, IndicesEANormalSteps,
IsPcgsElementaryAbelianSeries );
InstallPcgsSeriesInfo( PcgsCentralSeriesInfo,
PcgsCentralSeries, IndicesCentralNormalSteps, IsPcgsCentralSeries );
InstallPcgsSeriesInfo( PcgsPCentralSeriesPGroupInfo,
PcgsPCentralSeriesPGroup, IndicesPCentralNormalStepsPGroup,
IsPcgsPCentralSeriesPGroup );
InstallPcgsSeriesInfo( PcgsChiefSeriesInfo,
PcgsChiefSeries, IndicesChiefNormalSteps, IsPcgsChiefSeries );

InstallTagBasedMethod( PcgsSeriesInfo, function( filt, G )
Error( "no method for series kind ", NameFunction( filt ),
" installed for `PcgsSeriesInfo'" );
end );

#############################################################################
##
#F IndicesNormalStepsBounded( <pcgs>,<ind>,<bound> )
#F IndicesEANormalStepsBounded( <pcgs>,<bound> )
##
InstallGlobalFunction(IndicesEANormalStepsBounded,function(pcgs,bound)
local rel,ind,gp,i,j,try;
return IndicesNormalStepsBounded(pcgs,IndicesEANormalSteps(pcgs),bound);
end);

InstallGlobalFunction(IndicesNormalStepsBounded,function(pcgs,ind,bound)
local rel,gp,i,j,try;
rel:=RelativeOrders(pcgs);
ind:=IndicesEANormalSteps(pcgs);
gp:=GroupOfPcgs(pcgs);
i:=2;
while i<=Length(ind) do
Expand Down
79 changes: 79 additions & 0 deletions tst/testinstall/pcgsseriesinfo.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#@local G, P, ind, kinds, info, series, checkinfo, isEA, isCentral
gap> START_TEST("pcgsseriesinfo.tst");

# the indices returned must describe a normal series refined by the pcgs
# returned, and that series must be of the kind that was asked for
gap> series := info -> List( info.indices,
> i -> SubgroupByPcgs( GroupOfPcgs( info.pcgs ),
> InducedPcgsByPcSequence( info.pcgs,
> info.pcgs{[ i .. Length( info.pcgs ) ]} ) ) );;
gap> isEA := ser -> ForAll( [ 2 .. Length( ser ) ],
> i -> HasElementaryAbelianFactorGroup( ser[i-1], ser[i] ) );;
gap> isCentral := ser -> ForAll( [ 2 .. Length( ser ) ],
> i -> IsSubset( ser[i], CommutatorSubgroup( ser[1], ser[i-1] ) ) );;
gap> checkinfo := function( info, prop )
> local ser;
> if info.indices[1] <> 1 or
> Last( info.indices ) <> Length( info.pcgs ) + 1 then
> return "indices do not start with 1 or do not end with n+1";
> fi;
> ser := series( info );
> if not ForAll( ser, N -> IsNormal( ser[1], N ) ) then
> return "series is not normal";
> elif not prop( ser ) then
> return "series is not of the kind that was asked for";
> fi;
> return true;
> end;;

# pc groups, permutation groups, direct products; the codes are those of
# SmallGroup( 96, 3 ) and SmallGroup( 64, 10 ), spelled out so that this test
# does not need the small groups library
gap> for G in [ DihedralGroup( 16 ), PcGroupCode( 55306968584587147680, 96 ),
> SylowSubgroup( SymmetricGroup( 8 ), 2 ),
> DirectProduct( DihedralGroup( 8 ), CyclicGroup( 4 ) ) ] do
> info := PcgsElementaryAbelianSeriesInfo( G );
> if checkinfo( info, isEA ) <> true then
> Error( checkinfo( info, isEA ), " for ", G );
> elif info.indices <>
> PcgsSeriesInfo( IsPcgsElementaryAbelianSeries, G ).indices then
> Error( "tag based dispatch disagrees for ", G );
> fi;
> od;

# the central kinds need a nilpotent group; their indices must be the ones of
# the central series, not the ones of some elementary abelian series which
# the same pcgs may also belong to
gap> for G in [ DihedralGroup( 16 ), PcGroupCode( 217336074077211757, 64 ),
> SylowSubgroup( SymmetricGroup( 8 ), 2 ) ] do
> for kinds in [ [ PcgsCentralSeriesInfo, IsPcgsCentralSeries,
> IndicesCentralNormalSteps ],
> [ PcgsPCentralSeriesPGroupInfo,
> IsPcgsPCentralSeriesPGroup,
> IndicesPCentralNormalStepsPGroup ] ] do
> info := kinds[1]( G );
> if checkinfo( info, isCentral ) <> true then
> Error( checkinfo( info, isCentral ), " for ", G );
> elif info.indices <> kinds[3]( info.pcgs ) then
> Error( "indices are not the ones of this kind, for ", G );
> elif info.indices <> PcgsSeriesInfo( kinds[2], G ).indices then
> Error( "tag based dispatch disagrees for ", G );
> fi;
> od;
> od;

# an unknown kind is reported as such
gap> PcgsSeriesInfo( IsFinite, DihedralGroup( 8 ) );
Error, no method for series kind IsFinite installed for `PcgsSeriesInfo'

# refining indices, without taking them off the pcgs
gap> P := SylowSubgroup( SymmetricGroup( 8 ), 2 );;
gap> info := PcgsPCentralSeriesPGroupInfo( P );;
gap> IndicesNormalStepsBounded( info.pcgs, info.indices, 2^15 ) = info.indices;
true
gap> ind := IndicesNormalStepsBounded( info.pcgs, info.indices, 2 );;
gap> IsSubset( ind, info.indices ) and Length( ind ) >= Length( info.indices );
true

# that's all, folks
gap> STOP_TEST( "pcgsseriesinfo.tst" );
Loading