<Chapter><Heading>Nilpotent Quotients of L-presented groups</Heading>

Our nilpotent quotient algorithm for finitely L-presented groups
generalizes Nickel's algorithm for finitely presented groups; see
<Cite Key="Nickel96"/>. It determines a nilpotent presentation for the
lower central series quotient of an invariantly L-presented group. A
nilpotent presentation is a polycyclic presentation whose polycyclic
series refines the lower central series of the group (see the
description in the <Package>NQ</Package>-package for further
details). In general, our algorithm determines a polycyclic
presentation for the nilpotent quotient of an arbitrary finitely
L-presented group. For further details on our algorithm we refer to
<Cite Key="BEH08"/> or to the diploma thesis <Cite Key="H08"/>.

<Section><Heading>New methods for L-presented groups</Heading>

<ManSection><Oper Name="NilpotentQuotient" Arg="g [c]"/>
<Description>
returns a polycyclic presentation for the class-<A>c</A> quotient
<M>g/\gamma_{c+1}(g)</M> of the L-presented group <A>g</A> if <A>c</A>
is specified.  If <A>c</A> is not given, this method attempts to
compute the largest nilpotent quotient of <A>g</A> and will terminate
only if <A>g</A> has a largest nilpotent quotient.<P/>

The following example computes the class-5 quotient of the Grigorchuk
group.
<Example><![CDATA[
gap> G := ExamplesOfLPresentations( 1 );;
gap> H := NilpotentQuotient( G, 5 );
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ] 
gap> lcs := LowerCentralSeries( H );
[ Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ], 
  Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2 ], 
  Pcp-group with orders [ 2, 2, 2, 2, 2 ], Pcp-group with orders [ 2, 2, 2 ], 
  Pcp-group with orders [ 2, 2 ], Pcp-group with orders [  ] ]
gap> List( [ 1..5 ], x -> lcs[ x ] / lcs[ x+1 ] ); 
[ Pcp-group with orders [ 2, 2, 2 ], Pcp-group with orders [ 2, 2 ], 
  Pcp-group with orders [ 2, 2 ], Pcp-group with orders [ 2 ], 
  Pcp-group with orders [ 2, 2 ] ]
]]></Example>
</Description>
</ManSection>

<ManSection><Oper Name="LargestNilpotentQuotient" Arg="g"/>
<Description>
returns the largest nilpotent quotient of the L-presented group
<A>g</A> if it exists. It uses the method
<Ref Oper="NilpotentQuotient"/>. If <A>g</A> has no largest nilpotent
quotient, this method will not terminate.
</Description>
</ManSection>

<ManSection><Oper Name="NqEpimorphismNilpotentQuotient" Arg="g [p/c]"/>
<Description>
This method returns an epimorphism from the L-presented group <A>g</A>
onto a nilpotent quotient. If the optional argument is an
integer <A>c</A>, the epimorphism is onto the maximal class-<A>c</A>
quotient <M>g//\gamma_{c+1}(g)</M>. If no second argument is given,
this method attempts to compute an epimorphism onto the largest
nilpotent quotient of <A>g</A>. If <A>g</A> does not have a largest
nilpotent quotient, this method will not terminate.<P/>

If a pcp-group <A>p</A> is given as additional parameter, then
<A>p</A> has to be a nilpotent quotient of <A>g</A>. The method
computes an epimorphism from the L-presented group <A>g</A> onto
<A>p</A>.<P/>

The following example computes an epimorphism from the Grigorchuk
group onto its class-5, class-7, and class-10 quotients.

<Example><![CDATA[
gap> G := ExamplesOfLPresentations( 1 );
<L-presented group on the generators [ a, b, c, d ]>
gap> epi := NqEpimorphismNilpotentQuotient( G, 5 );
[ a, b, c, d ] -> [ g1, g2*g3, g2, g3 ]
gap> H := Image( epi );
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]
gap> NilpotencyClassOfGroup( H );
5
gap> H := NilpotentQuotient( G, 7 );
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]
gap> NilpotentQuotient( G, 10 );
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]
gap> NqEpimorphismNilpotentQuotient( G, H );
[ a, b, c, d ] -> [ g1, g2*g3, g2, g3 ]
gap> Image( last );
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]
]]></Example>
</Description>
</ManSection>

<ManSection><Oper Name="AbelianInvariants" Arg="g"/>
<Description>
computes the abelian invariants of the L-presented group
<A>g</A>. It uses the operation <Ref Oper="NilpotentQuotient"/>.
<Example><![CDATA[
gap> G := ExamplesOfLPresentations( 1 );;
gap> AbelianInvariants( G );
[ 2, 2, 2 ]
]]></Example>
</Description>
</ManSection>

</Section>

<Section><Heading>A brief description of the algorithm</Heading>

In the following we give a brief description of the nilpotent quotient
algorithm for an arbitrary finitely L-presented group. For further
details, we refer to <Cite Key="BEH08"/> and the diploma thesis
<Cite Key="H08"/>.<P/>

Let <M>(S,Q,\Phi,R)</M> be a finite L-presentation defining the
L-presented group <M>G</M> and let <M>(S,Q',\Phi,R)</M> be an
underlying invariant L-presentation. Write <M>\bar G</M> for the
invariantly L-presented group defined by <M>(S,Q',\Phi,R)</M>.<P/>

The first step in computing a polycyclic presentation
for <M>G/\gamma_{c+1}(G)</M> is to determine a nilpotent presentation
for <M>\bar G/\gamma_{c+1}(\bar G)</M>.  This will be done by
induction on <M>c</M>. The induction step of our algorithm generalizes
the induction step of Nickel's algorithm which mainly relies on
Hermite normal form computations. In order to use this rather fast
linear algebra, we must require the group to be invariantly
L-presented.  Therefore, the fixed relators must be handled separately
by reducing to an underlying invariant L-presentation first.<P/>

The induction step of our algorithm then returns a nilpotent presentation
<M>H</M> for the quotient <M>\bar G/\gamma_{c+1}(\bar G)</M> and an
epimorphism
<M>\delta\colon\bar G\to H</M>.  Both are used to determine a
polycyclic presentation for the nilpotent
quotient <M>G/\gamma_{c+1}(G)</M> using an extension <M>\delta'\colon
F_S\to H</M> of the epimorphism <M>\delta</M>. The
quotient <M>G/\gamma_{c+1}(G)</M> is isomorphic to the factor
group <M>H/\langle Q^{\delta'}\rangle^H</M>.  We use the
<Package>Polycyclic</Package>-package to compute a polycyclic
presentation for <M>H/\langle Q^{\delta'}\rangle^H</M>.<P/>

The efficiency of this general approach depends on the underlying
invariant L-presentation <M>(S,Q',\Phi,R)</M>.  The set of fixed
relators
<M>Q'</M> should be as large as possible. Otherwise, the nilpotent
quotient
<M>H</M> can be large even if the nilpotent
quotient <M>G/\gamma_{c+1}(G)</M> is rather small.<P/>

The following example demonstrates the different behavior of our nilpotent
quotient algorithm for the Grigorchuk group with its finite L-presentation
<Display>\Big(\{a,c,b,d\},\{a^2,b^2,c^2,d^2,bcd\},\{\sigma\},\{[d,d^a],[d,d^{acaca}]\} \Big). </Display>
This latter L-presentation is obviously an
invariant L-presentation. Hence, we can either use
the property <Ref Prop="IsInvariantLPresentation"/> or the attribute
<Ref Attr="UnderlyingInvariantLPresentation"/>. First, one has to construct the
group as described in Section <Ref Sect="createlp"/>:
<Example><![CDATA[
gap> F := FreeGroup( "a", "b", "c", "d" );
<free group on the generators [ a, b, c, d ]>
gap> AssignGeneratorVariables( F );
#I  Assigned the global variables [ a, b, c, d ]
gap> rels := [ a^2, b^2, c^2, d^2, b*d*c ];;
gap> endos := [ GroupHomomorphismByImagesNC( F, F, [ a, b, c, d ], [ c^a, d, b, c ]) ];;
gap> itrels := [ Comm( d, d^a ), Comm( d, d^(a*c*a*c*a) ) ];;
gap> G := LPresentedGroup( F, rels, endos, itrels );
<L-presented group on the generators [ a, b, c, d ]>
gap> List( rels, x -> x^endos[1] );
[ a^-1*c^2*a, d^2, b^2, c^2, d*c*b ]
]]></Example>

The property <Ref Prop="IsInvariantLPresentation"/> can be set manually using
<C>SetInvariantLPresentation</C>:
<Example><![CDATA[
gap> SetIsInvariantLPresentation( G, true );
gap> NilpotentQuotient( G, 4 );
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2 ]
gap> StringTime( time );
" 0:00:00.032"
]]></Example>

On the other hand, one can use the attribute
<Ref Attr="UnderlyingInvariantLPresentation"/> as follows:
<Example><![CDATA[
gap> U := LPresentedGroup( F, rels, endos, itrels );
<L-presented group on the generators [ a, b, c, d ]>
gap> SetUnderlyingInvariantLPresentation( G, U );
gap> NilpotentQuotient( G, 4 );
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2 ]
gap> StringTime( time );
" 0:00:00.028"
]]></Example>

For saving memory the first method should be preferred in this case. In
general, the L-presentation is not invariant (or not known to be
invariant) and thus the underlying invariant L-presentation has fewer
fixed relators than the group <M>G</M> itself. In this case, the second method
is the method of choice.<P/>

There is a brute-force method implemented for the operation <Ref
Attr="UnderlyingInvariantLPresentation"/> which works quite well on
the <Ref Func="ExamplesOfLPresentations"/>. However, in the worst
case, this method will return the underlying ascending
L-presentation. The following example shows the influence of this
choice to the runtime of the nilpotent quotient algorithm. After
defining the group <M>G</M> as above, we set the attribute <Ref
Attr="UnderlyingInvariantLPresentation"/> as follows:
<Example><![CDATA[
gap> SetUnderlyingInvariantLPresentation( G, UnderlyingAscendingLPresentation(G) );
gap> NilpotentQuotient( G, 4 );
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2 ]
gap> StringTime( time );
" 0:00:02.700"
]]></Example>

</Section>

<Section><Heading>Nilpotent Quotient Systems for invariant L-presentations</Heading>

For an invariantly L-presented group <M>G</M>, our algorithm computes
a nilpotent presentation for <M>G/\gamma_{c+1}(G)</M> by computing a
<A>weighted nilpotent quotient system</A> for <M>G/G'</M> and
extending it inductively to a weighted nilpotent quotient system for
<M>G/\gamma_{c+1}(G)</M>.<P/>

In the &lpres; package, a weighted nilpotent quotient system is a record
containing the following entries:
<List>
<Mark>Lpres</Mark><Item>the invariantly L-presented group <M>G</M>.</Item>

<Mark>Pccol</Mark><Item><Ref BookName="polycyclic"
Oper="FromTheLeftCollector"/> of the nilpotent quotient represented by
this quotient system.</Item>

<Mark>Imgs</Mark><Item>the images of the generators of the L-presented
group <M>G</M> under the epimorphism onto the nilpotent quotient
<A>Pccol</A>. For each generator of <M>G</M> there is an integer or a
generator exponent list. If the image is an integer <A>int</A>, the
image is a definition of the <A>int</A>-th generator of the nilpotent
presentation <A>Pccol</A>.</Item>

<Mark>Epimorphism</Mark><Item>an epimorphism from the L-presented
group <M>G</M> onto its nilpotent quotient <A>Pccol</A> with the
images of the generators given by <A>Imgs</A>.</Item>

<Mark>Weights</Mark><Item>a list of the weight of each generator of
the nilpotent presentation <A>Pccol</A>.</Item>

<Mark>Definitions</Mark><Item>the definition of each generator of
<A>Pccol</A>. Each generator in the quotient system has a definition
as an image or as a commutator of the form <M>[a_j,a_i]</M> where
<M>a_j</M> and <M>a_i</M> are generators of a certain weight. If the
<A>i</A>-th entry is an integer, the <A>i</A>-th generator of
<A>Pccol</A> has a definition as an image. Otherwise, the <A>i</A>-th
entry is a <M>2</M>-tuple <M>[k,l]</M> and the <A>i</A>-th generator
has a definition as commutator <M>[a_k,a_l]</M>.</Item>
</List>

A weighted nilpotent quotient system of an invariantly L-presented group 
can be computed with the following functions.

<ManSection><Oper Name="InitQuotientSystem" Arg="lpgroup"/>
<Description>
computes a weighted nilpotent quotient system for the abelian quotient
of the L-presented group <A>lpgroup</A>.
</Description>
</ManSection>

<ManSection><Oper Name="ExtendQuotientSystem" Arg="QS"/>
<Description>
extends the weighted nilpotent quotient system <A>QS</A> for a
class-<M>c</M> quotient of an invariantly L-presented group to a
weighted nilpotent quotient system of its class-<M>c+1</M>
quotient.

<Example><![CDATA[
gap> G := ExamplesOfLPresentations( 1 );
<L-presented group on the generators [ a, b, c, d ]>
gap> Q := InitQuotientSystem( G );
rec( Lpres := <L-presented group on the generators [ a, b, c, d ]>, 
  Pccol := <<from the left collector with 3 generators>>, 
  Imgs := [ 1, [ 2, 1, 3, 1 ], 2, 3 ], Epimorphism := [ a, b, c, d ] -> 
    [ g1, g2*g3, g2, g3 ], Weights := [ 1, 1, 1 ], Definitions := [ 1, 3, 4 ] 
 )
gap> ExtendQuotientSystem( Q );
rec( Lpres := <L-presented group on the generators [ a, b, c, d ]>, 
  Pccol := <<from the left collector with 5 generators>>, 
  Imgs := [ 1, [ 2, 1, 3, 1 ], 2, 3 ], 
  Definitions := [ 1, 3, 4, [ 2, 1 ], [ 3, 1 ] ], 
  Weights := [ 1, 1, 1, 2, 2 ], Epimorphism := [ a, b, c, d ] -> 
    [ g1, g2*g3, g2, g3 ] )
]]></Example>
</Description>
</ManSection>
</Section>

<Section><Heading>Attributes of L-presented groups related with the nilpotent quotient algorithm</Heading><P/>

To avoid repeated extensions of a weighted nilpotent quotient system
the largest known quotient system is stored as an attribute of the
invariantly L-presented group. For non-invariantly L-presented groups
(or groups which are not known to be invariantly L-presented) the known
epimorphisms onto the nilpotent quotients are stored as an attribute.

<ManSection><Attr Name="NilpotentQuotientSystem" Arg="lpgroup"/>
<Description>
stores the largest known weighted nilpotent quotient system of an
invariantly L-presented group.

<Example><![CDATA[
gap> G := ExamplesOfLPresentations( 1 );;
gap> NilpotentQuotient( G, 5 );
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]
gap> NilpotentQuotientSystem( G );
rec( Lpres := <L-presented group on the generators [ a, b, c, d ]>, 
  Pccol := <<from the left collector with 10 generators>>, 
  Imgs := [ 1, [ 2, 1, 3, 1 ], 2, 3 ], 
  Definitions := [ 1, 3, 4, [ 2, 1 ], [ 3, 1 ], [ 4, 2 ], [ 4, 3 ], [ 7, 1 ], 
      [ 8, 2 ], [ 8, 3 ] ], Weights := [ 1, 1, 1, 2, 2, 3, 3, 4, 5, 5 ], 
  Epimorphism := [ a, b, c, d ] -> [ g1, g2*g3, g2, g3 ] )
gap> NilpotencyClassOfGroup( PcpGroupByCollectorNC( last.Pccol ) );
5
]]></Example>
</Description>
</ManSection>

<ManSection><Attr Name="NilpotentQuotients" Arg="lpgroup"/>
<Description>
stores all known epimorphisms onto the nilpotent quotients of
<A>lpgroup</A>.  The nilpotent quotients are accessible by the
operation <Ref BookName="ref" Func="Range" Label="of a general mapping"/>.

<Example><![CDATA[
gap> G:=ExamplesOfLPresentations( 3 );;
gap> HasIsInvariantLPresentation( G );
false
gap> NilpotentQuotient( G, 3 );
Pcp-group with orders [ 0, 2, 2, 2 ]
gap> NilpotentQuotients( G );
[ [ a, t, u ] -> [ g2, g1, g2 ], [ a, t, u ] -> [ g2, g1, g2 ],
  [ a, t, u ] -> [ g2, g1, g2 ] ]
gap> Range( last[2] );
Pcp-group with orders [ 0, 2, 2 ]
]]></Example>

The underlying invariant L-presentation has stored its largest
weighted nilpotent quotient system as an attribute.
<Example><![CDATA[
gap> NilpotentQuotientSystem( UnderlyingInvariantLPresentation( G ) );
rec( Lpres := <L-presented group on the generators [ a, t, u ]>,
  Pccol := <<from the left collector with 9 generators>>, Imgs := [ 1, 2, 3 ],
  Definitions := [ 1, 2, 3, [ 2, 1 ], [ 3, 2 ], [ 4, 1 ], [ 4, 2 ], [ 5, 2 ],
      [ 5, 3 ] ], Weights := [ 1, 1, 1, 2, 2, 3, 3, 3, 3 ],
  Epimorphism := [ a, t, u ] -> [ g1, g2, g3 ] )
]]></Example>
</Description>
</ManSection>

</Section>

<Section><Heading>The Info-Class InfoLPRES</Heading><P/>

To get some information about the progress of the algorithm,
one can use the info class <Ref InfoClass="InfoLPRES"/>.

<ManSection><InfoClass Name="InfoLPRES"/>
<Description>
is the info class of the &lpres;-package. If the info-level is <M>1</M>, the
info-class gives further information on the progress of the nilpotent
quotient algorithm for L-presented groups. The info-level <M>2</M> also
includes some information on the runtime of our algorithm while the
info-level <M>3</M> is mainly used for debugging-purposes. An example of such
a session for the Grigorchuk group is shown below:

<Example><![CDATA[
gap> SetInfoLevel( InfoLPRES, 1 );;
gap> G:=ExamplesOfLPresentations( 1 );
#I  The Grigorchuk group on 4 generators
<L-presented group on the generators [ a, b, c, d ]>
gap> NilpotentQuotient( G, 3 );
#I  Class 1: 3 generators with relative orders: [ 2, 2, 2 ]
#I  Class 2: 2 generators with relative orders: [ 2, 2 ]
#I  Class 3: 2 generators with relative orders: [ 2, 2 ]
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2 ]
gap> SetInfoLevel( InfoLPRES, 2 );
gap> NilpotentQuotient( G, 5 );
#I  Time spent for spinning algo:  0:00:00.004
#I  Class 4: 1 generators with relative orders: [ 2 ]
#I  Runtime for this step  0:00:00.028
#I  Time spent for spinning algo:  0:00:00.008
#I  Class 5: 2 generators with relative orders: [ 2, 2 ]
#I  Runtime for this step  0:00:00.036
Pcp-group with orders [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]
]]></Example>
</Description>
</ManSection>

<ManSection><Var Name="InfoLPRES_MAX_GENS"/>
<Description>
this global variable sets the limit of generators whose relative order
will be shown on each step of the nilpotent quotient algorithm, if the
info-level of <Ref InfoClass="InfoLPRES"/> is positive.
</Description>
</ManSection>
</Section>
</Chapter>
