#############################################################################
##
## This file is part of GAP, a system for computational discrete algebra.
## This file's authors include Alexander Hulpke.
##
## 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
##
## This file contains the declarations of operations for cosets.
##
#############################################################################
##
#V InfoCoset
##
## <#GAPDoc Label="InfoCoset">
##
##
##
##
## The information function for coset and double coset operations is
## .
##
##
## <#/GAPDoc>
##
DeclareInfoClass("InfoCoset");
#############################################################################
##
#F AscendingChain( , ) . chain of subgroups G = G_1 > ... > G_n = U
##
## <#GAPDoc Label="AscendingChain">
##
##
##
##
## This function computes an ascending chain of subgroups from U to
## G.
## This chain is given as a list whose first entry is U and the last
## entry is G.
## The function tries to make the links in this chain small.
##
## The option refineIndex can be used to give a bound for refinements
## of steps to avoid &GAP; trying to enforce too small steps.
## The option cheap (if set to true) will overall limit the
## amount of heuristic searches.
##
##
## <#/GAPDoc>
##
DeclareGlobalFunction("AscendingChain");
#############################################################################
##
#O AscendingChainOp(,) chain of subgroups
##
##
##
##
##
## This operation does the actual work of computing ascending chains. It
## gets called from AscendingChain if no chain is found stored in
## ComputedAscendingChains.
##
##
##
DeclareOperation("AscendingChainOp",[IsGroup,IsGroup]);
#############################################################################
##
#A ComputedAscendingChains() list of already computed ascending chains
##
##
##
##
##
## This attribute stores ascending chains. It is a list whose entries are
## of the form [G,chain] where chain is an ascending chain from U up
## to G. This storage is used by AscendingChain to avoid duplicate
## calculations.
##
##
##
DeclareAttribute("ComputedAscendingChains",IsGroup,
"mutable");
#############################################################################
##
#F RefinedChain(,) . . . . . . . . . . . . . . . . refine chain links
##
##
##
##
##
## c is an ascending chain in the Group G. The task of this routine is
## to refine c, i.e., if there is a "link" U>L in c with [U:L] too big,
## this procedure tries to find subgroups G_0,...,G_n of G; such that
## U=G_0>...>G_n=L. This is done by extending L inductively: Since normal
## steps can help in further calculations, the routine first tries to
## extend to the normalizer in U. If the subgroup is self-normalizing,
## the group is extended via a random element. If this results in a step
## too big, it is repeated several times to find hopefully a small
## extension!
##
## The option refineIndex can be used to tell &GAP; that a specified
## step index is good enough. The option refineChainActionLimit can be
## used to give an upper limit up to which index guaranteed refinement
## should be tried.
##
##
##
DeclareGlobalFunction("RefinedChain");
#############################################################################
##
#O CanonicalRightCosetElement( U, g ) canonical representative of U*g
##
## <#GAPDoc Label="CanonicalRightCosetElement">
##
##
##
##
## returns a canonical
representative of the right coset
## U g
## which is independent of the given representative g.
## This can be used to compare cosets by comparing their canonical
## representatives.
##
## The representative chosen to be the canonical
one
## is representation dependent and only guaranteed to remain the same
## within one &GAP; session.
## CanonicalRightCosetElement(u,(2,4,3));
## (3,4)
## ]]>
##
##
## <#/GAPDoc>
##
DeclareOperation("CanonicalRightCosetElement",
[IsGroup,IsObject]);
#############################################################################
##
#C IsDoubleCoset()
##
## <#GAPDoc Label="IsDoubleCoset">
##
##
##
##
## The category of double cosets.
##
##
## <#/GAPDoc>
##
DeclareCategory("IsDoubleCoset",
IsDomain and IsExtLSet and IsExtRSet);
#############################################################################
##
#A LeftActingGroup()
#A RightActingGroup()
##
##
##
##
##
##
## return the two groups that define a double coset dcos.
##
##
##
DeclareAttribute("LeftActingGroup",IsDoubleCoset);
DeclareAttribute("RightActingGroup",IsDoubleCoset);
#############################################################################
##
#O DoubleCoset(,,)
##
## <#GAPDoc Label="DoubleCoset">
##
##
##
##
## The groups U and V must be subgroups of a common supergroup
## G of which g is an element.
## This command constructs the double coset U g V
## which is the set of all elements of the form ugv for any
## u \in U, v \in V.
## For element operations such as in, a double coset behaves
## like a set of group elements. The double coset stores U in the
## attribute LeftActingGroup,
## g as ,
## and V as RightActingGroup.
##
##
## <#/GAPDoc>
##
DeclareOperation("DoubleCoset",[IsGroup,IsObject,IsGroup]);
#############################################################################
##
#O DoubleCosets(,,)
#O DoubleCosetsNC(,,)
##
## <#GAPDoc Label="DoubleCosets">
##
##
##
##
##
## computes a duplicate free list of all double cosets
## U g V for g \in G.
## The groups U and V must be subgroups of the group G.
## The NC version does not check whether U and V are
## subgroups of G.
## dc:=DoubleCosets(g,u,v);
## [ DoubleCoset(Group( [ (1,2,3), (1,2) ] ),(),Group( [ (3,4) ] )),
## DoubleCoset(Group( [ (1,2,3), (1,2) ] ),(1,3)(2,4),Group(
## [ (3,4) ] )), DoubleCoset(Group( [ (1,2,3), (1,2) ] ),(1,4)
## (2,3),Group( [ (3,4) ] )) ]
## gap> List(dc,Representative);
## [ (), (1,3)(2,4), (1,4)(2,3) ]
## ]]>
##
##
## <#/GAPDoc>
##
DeclareGlobalFunction("DoubleCosets");
DeclareOperation("DoubleCosetsNC",[IsGroup,IsGroup,IsGroup]);
#############################################################################
##
#O DoubleCosetRepsAndSizes(,,)
##
## <#GAPDoc Label="DoubleCosetRepsAndSizes">
##
##
##
##
## returns a list of double coset representatives and their sizes,
## the entries are lists of the form [ r, n ]
## where r and n are an element of the double coset and the
## size of the coset, respectively.
## This operation is faster than because no
## double coset objects have to be created.
## dc:=DoubleCosetRepsAndSizes(g,u,v);
## [ [ (), 12 ], [ (1,3)(2,4), 6 ], [ (1,4)(2,3), 6 ] ]
## ]]>
##
##
## <#/GAPDoc>
##
DeclareOperation("DoubleCosetRepsAndSizes",[IsGroup,IsGroup,IsGroup]);
#############################################################################
##
#A RepresentativesContainedRightCosets()
##
## <#GAPDoc Label="RepresentativesContainedRightCosets">
##
##
##
##
## A double coset D = U g V can be considered as a union of
## right cosets U h_i.
## (It is the union of the orbit of U g under right multiplication by
## V.)
## For a double coset D this function returns a set
## of representatives h_i such that
## D = \bigcup_{{h_i}} U h_i.
## The representatives returned are canonical for U (see
## ) and form a set.
## u:=Subgroup(g,[(1,2,3),(1,2)]);;v:=Subgroup(g,[(3,4)]);;
## gap> c:=DoubleCoset(u,(2,4),v);
## DoubleCoset(Group( [ (1,2,3), (1,2) ] ),(2,4),Group( [ (3,4) ] ))
## gap> (1,2,3) in c;
## false
## gap> (2,3,4) in c;
## true
## gap> LeftActingGroup(c);
## Group([ (1,2,3), (1,2) ])
## gap> RightActingGroup(c);
## Group([ (3,4) ])
## gap> RepresentativesContainedRightCosets(c);
## [ (2,3,4) ]
## ]]>
##
##
## <#/GAPDoc>
##
DeclareAttribute( "RepresentativesContainedRightCosets", IsDoubleCoset );
#############################################################################
##
#C IsRightCoset()
##
## <#GAPDoc Label="IsRightCoset">
##
##
##
##
## The category of right cosets.
##
## left cosets
## &GAP; does not provide left cosets as a separate data type, but as the
## left coset gU consists of exactly the inverses of the elements of
## the right coset Ug^{{-1}} calculations with left cosets can be
## emulated using right cosets by inverting the representatives.
##
##
## <#/GAPDoc>
##
DeclareCategory("IsRightCoset", IsDomain and IsExternalOrbit and
IsMultiplicativeElementWithInverse);
#############################################################################
##
#P IsBiCoset( )
##
## <#GAPDoc Label="IsBiCoset">
##
##
##
##
## bicoset
## A (right) coset Ug is considered a bicoset if its set of
## elements simultaneously forms a left coset for the same subgroup. This is
## the case if and only if the coset representative g normalizes the
## subgroup U.
##
##
## <#/GAPDoc>
##
DeclareProperty( "IsBiCoset", IsRightCoset );
#############################################################################
##
#O RightCoset( , )
##
## <#GAPDoc Label="RightCoset">
##
##
##
##
## returns the right coset of U with representative g,
## which is the set of all elements of the form ug for all
## u \in U. g must be an
## element of a larger group G which contains U.
## For element operations such as in a right coset behaves like a set of
## group elements.
##
## Right cosets are
## external orbits for the action of U which acts via
## .
## Of course the action of a larger group G on right cosets is via
## .
## u:=Group((1,2,3), (1,2));;
## gap> c:=RightCoset(u,(2,3,4));
## RightCoset(Group( [ (1,2,3), (1,2) ] ),(2,3,4))
## gap> ActingDomain(c);
## Group([ (1,2,3), (1,2) ])
## gap> Representative(c);
## (2,3,4)
## gap> Size(c);
## 6
## gap> AsList(c);
## [ (2,3,4), (1,4,2), (1,3,4,2), (1,3)(2,4), (2,4), (1,4,2,3) ]
## gap> IsBiCoset(c);
## false
## ]]>
##
##
## <#/GAPDoc>
##
DeclareOperation("RightCoset",[IsGroup,IsObject]);
#############################################################################
##
#F RightCosets(,)
#O RightCosetsNC(,)
##
## <#GAPDoc Label="RightCosets">
##
##
##
##
##
## computes a duplicate free list of right cosets U g for
## g \in G.
## A set of representatives for the elements in this list forms a right
## transversal of U in G.
## (By inverting the representatives one obtains
## a list of representatives of the left cosets of U.)
## The NC version does not check whether U is a subgroup of
## G.
## RightCosets(g,u);
## [ RightCoset(Group( [ (1,2,3), (1,2) ] ),()),
## RightCoset(Group( [ (1,2,3), (1,2) ] ),(1,3)(2,4)),
## RightCoset(Group( [ (1,2,3), (1,2) ] ),(1,4)(2,3)),
## RightCoset(Group( [ (1,2,3), (1,2) ] ),(1,2)(3,4)) ]
## ]]>
##
##
## <#/GAPDoc>
##
DeclareGlobalFunction("RightCosets");
DeclareOperation("RightCosetsNC",[IsGroup,IsGroup]);
#############################################################################
##
#F IntermediateGroup(,) . . . . . . . . . subgroup of G containing U
##
## <#GAPDoc Label="IntermediateGroup">
##
##
##
##
## This routine tries to find a subgroup E of G,
## such that G > E > U holds.
## If U is maximal in G, the function returns fail.
## This is done by finding minimal blocks for
## the operation of G on the right cosets of U.
##
##
## <#/GAPDoc>
##
DeclareGlobalFunction("IntermediateGroup");
# forward declaration for recursive call.
DeclareGlobalFunction("DoConjugateInto");