<!-- 

      stabchains.xml            genss package documentation
                                                                Max Neunhoeffer
                                                                   Felix Noeske

         Copyright (C) 2006-2009 by the authors.

This chapter explains how to work with stabiliser chains.

-->

<Chapter Label="StabChains">
<Heading>Stabiliser Chains</Heading>

This chapter describes the core functionality of the package. It mainly
covers how to use <Package>genss</Package> to compute stabiliser chains
for &GAP; groups and use them to do sifting.

<Section Label="StabChainComp">
<Heading>Computing stabiliser chains</Heading>

The main tool to compute a stabiliser chain is the following operation.
It has many options and can be customised in a very flexible way.

<ManSection>
<Oper Name="StabilizerChain" Arg="G [, opt]"/>
<Returns>a stabiliser chain object or <K>fail</K></Returns>
<Description>
This operation computes a stabiliser chain for the group <A>G</A> using a
randomised Schreier-Sims algorithm. The
second argument <A>opt</A> is an optional options record. See Section <Ref
Sect="StabChainOpts"/> below for an
explanation of the possible components. 
<P/>
Note that this is a Monte Carlo algorithm in most cases, so there is a
small error probability. However, the only error possible is that some of
the subgroups in the stabiliser chain are proper subgroups of the actual point
stabilisers. So the resulting group order is always a divisor of the actual
group order and if the two are equal, then the stabiliser chain is proved
to be correct. In particular, if the group object <A>G</A> for some reason
already knows the group order, then this procedure always returns a correct
and proven stabiliser chain for <A>G</A>.
</Description>
</ManSection>

</Section>

<Section Label="StabChainOpts">
<Heading>Options for the computation of stabiliser chains</Heading>

The options record for the <Ref Oper="StabilizerChain"/> can contain the
following components, which are used to control the behaviour of the
computation of a stabiliser chain for the group <A>G</A>.
Note that for most of these components there are default values to be found
in the global <C>GENSS</C> record. You can change these defaults there if
you want but you should know what you are doing. An explicitly given value
in the options record always takes precedence over the default value.

<List>
<Mark><C>Base</C></Mark>
<Item>This component can either be bound to an existing stabilizer chain
object or to a list of points. In both cases this indicates that the
base of the stabilizer chain or the list of points respectively are
known to be a base for the group <A>G</A>. In the first case the
corresponding action functions are taken from the stabiliser chain, in
the second case one should usually bind the component <C>BaseOps</C> to
a list of equal length containing the action functions corresponding to
the base points.
</Item>
<Mark><C>BaseOps</C></Mark>
<Item>If the <C>Base</C> component is bound to a list of points the
<C>BaseOps</C> component must be a list of equal length containing the
corresponding action functions. If the <C>BaseOps</C> component is unbound,
a list with identical entries <C>OnLines</C> is used in projective mode and
<C>OnPoints</C> in non-projective mode (see component <C>Projective</C>
below).
</Item>
<Mark><C>Cand</C></Mark>
<Item>The <C>Cand</C> component can be bound to a record <C>r</C>which contains
candidates for base points in the following way. The <C>r.points</C>
component contains the list of points, the <C>r.ops</C> component contains
a list of equal length with the corresponding action functions. The
points and actions specified in the <C>Cand</C> component are tried as
possible base points for <A>G</A> (and its stabilisers) first before other
points are guessed (see <Ref Oper="FindBasePointCandidates"/>). If a point
is fixed under all generators it is not used, unless the component
<C>Reduced</C> is explicitly set to <K>false</K> (see below). If the component
<C>StrictlyUseCandidates</C> is <K>false</K> (the default, see below), the
algorithm tries to use other points of an already found orbit before
considering the next candidate specified by <C>Cand</C>. This is usually 
sensible because for an already enumerated orbit we have a natural bound
on the length of the suborbits for the point stabiliser in this orbit.
</Item>
<Mark><C>DeterministicVerification</C></Mark>
<Item>
Set this component to <K>true</K> to switch on a deterministic verification
routine after the randomised Schreier-Sims procedure. This is not yet
implemented.
</Item>
<Mark><C>ErrorBound</C></Mark>
<Item>
Set this component to a rational number between 0 and 1. It will be an
upper bound for the error probability. That is, the error probability of
the Monte Carlo verification at the end will be less than this rational
number. This component overrides everything you specify in the
<C>random</C> or <C>VerifyElements</C> components.
</Item>
<Mark><C>FailInsteadOfError</C></Mark>
<Item>
If no short enough orbit is found during the computation, the procedure
stops with an error message. If you would rather like it to return
<K>fail</K> then set this component to <K>true</K>. This option can be used
to try an stabiliser chain computation automatically and give up before you
run out of memory.
</Item>
<Mark><C>ImmediateVerificationElements</C></Mark>
<Item>Whenever the randomised Schreier-Sims procedure has first computed
generators for a stabiliser in the chain and has computed a stabiliser
chain for that stabiliser recursively, 
an immediate verification is done. This is to spot early on that the
group found is in fact a proper subgroup of the stabiliser. This
verification is done by creating a few more random elements of that
stabiliser and sifting them through the newly created stabiliser chain.
Each such element has a chance of at least <M>1/2</M> to spot this. The
number of random elements used is stored in the component
<C>ImmediateVerificationElements</C>.
</Item>
<Mark><C>InitialHashSize</C></Mark>
<Item>
Set this component to the initial tree hash size for orbit computations in the
stabiliser chain.
</Item>
<Mark><C>IsOne</C></Mark>
<Item>
The default for this computation is the <Ref Prop="IsOne" BookName="Ref"/>
operation in the &GAP; library. Whenever in the stabiliser chain
computation it has to be tested whether or not a group element is equal to
the identity, the function stored in the <C>IsOne</C> component is called.
The rationale behind this is that you can compute a stabiliser chain for a
factor group of the group object <A>G</A>. For example, if you set the
<C>IsOne</C> component to <Ref Func="GENSS_IsOneProjective"/> for a matrix
group <A>G</A>, scalar multiples of the identity are considered to be
equal to the identity. You will have to specify the base points
explicitly using the <C>Cand</C> and <C>StrictlyUseCandidates</C>
component (see above and below) to only use actions
having the normal subgroup in its kernel. A shortcut for computing
stabiliser chains of projective groups (matrix group modulo scalars) is
to set the <C>Projective</C> component (see below) and switch to projective
mode.
</Item>
<Mark><C>LimitShortOrbCandidates</C></Mark>
<Item>
The integer value of this component limits the number of candidates
considered for the finding of short orbits. See the <C>TryShortOrbit</C>
and <C>TryBirthdayParadox</C> components.
</Item>
<Mark><C>NrRandElsBirthdayParadox</C></Mark>
<Item>
The method using the birthday paradox to find short orbits uses at most
as many random group elements to estimate the orbit size as this
component says. See the <C>TryBirthdayParadox</C> component.
</Item>
<Mark><C>NumberPrevOrbitPoints</C></Mark>
<Item>
After an orbit for the stabiliser chain has been enumerated, the randomised
Schreier-Sims method first tries <C>NumberPrevOrbitPoints</C> from this
orbit as next base points. Note that this is not done if the
<C>StrictlyUseCandidates</C> component is set to <K>true</K>.
</Item>
<Mark><C>OrbitLengthLimit</C></Mark>
<Item>This component is an absolute upper bound for the length of all
orbits in the stabiliser chain. If an orbit enumeration reaches this limit,
the stabiliser chain computation is aborted.
</Item>
<Mark><C>OrbitLimitBirthdayParadox</C></Mark>
<Item>
During the method to find short orbits using the birthday paradox (see
component <C>TryBirthdayParadox</C>) only orbits whose final estimated
length is less than <C>OrbitLimitBirthdayParadox</C> are used.
</Item>
<Mark><C>OrbitLimitImmediatelyTake</C></Mark>
<Item>
During the method to find short orbits using the birthday paradox (see
component <C>TryBirthdayParadox</C>) an orbit is immediately used
if its currently estimated length is less than
<C>OrbitLimitImmediatelyTake</C>, even if the estimate is not yet very
reliable.
</Item>
<Mark><C>OrbitsWithLog</C></Mark>
<Item>
This component defaults to <K>true</K> in which case the orbit objects
for the stabiliser chain have a log to allow to make the Schreier
trees shallow by adding generators. If you set this to <K>false</K>,
no logs are written and the Schreier trees could potentially be deep.
This will make sifting slower. Usually you should not touch this
option. The only reason for setting it to <K>false</K> could be if you
need that the Schreier trees are not changed after their initial
creation, even if new generators are added to the stabiliser chain.
</Item>
<Mark><C>Projective</C></Mark>
<Item>
Set this component to <K>true</K> if you want to compute a stabiliser chain
for a projective group given as a matrix group. Elements which are scalar
multiples of each other will be considered to be equal. This is achieved by
only considering projective actions. Note that in this case a known size 
of the group object cannot be used, since this size is the order of the
matrix group!
</Item>
<Mark><C>random</C></Mark>
<Item>
The <C>random</C> component is there as a compatibility option. It behaves
exactly as for the stabiliser chain methods in the &GAP; library. It must
be set to a number between <M>0</M> and <M>1000</M> indicating a lower
bound for the probability of a correct answer, where the value <M>a</M> means
<M>a/10</M>&percent;. Note that currently <M>1000</M> is not yet
implemented since there is no working deterministic verification routine.
</Item>
<Mark><C>RandomElmFunc</C></Mark>
<Item>
If this component is bound then it must be bound to a function taking
no arguments and returning uniformly distributed random elements in
the group for which the stabiliser chain is to be computed. All random
elements used for the stabiliser chain will then be created by calling 
this function.
</Item>
<Mark><C>RandomStabGens</C></Mark>
<Item>
This component contains the number of random stabiliser elements that are
generated initially to generate a new stabiliser in the chain.
</Item>
<Mark><C>Reduced</C></Mark>
<Item>
If this component is bound to <K>true</K>, then no orbits of length <M>1</M>
are allowed in the stabiliser chain. That is, no points are taken as base
points that are fixed under all generators of the current stabiliser.
Set this component to <K>false</K> to allow for orbits of length <M>1</M>,
for example if you want the stabiliser chain to run through a prescribed
base.
</Item>
<Mark><C>Report</C></Mark>
<Item>
The number in the <C>Report</C> component is taken as the <C>Report</C>
component in all orbit enumerations. That is, every <C>Report</C> 
newly found elements in the orbit a message is printed saying how 
far the computation has gone.
</Item>
<Mark><C>ShortOrbitsInitialLimit</C></Mark>
<Item>
See the <C>TryShortOrbit</C> component.
</Item>
<Mark><C>ShortOrbitsNrRandoms</C></Mark>
<Item>
See the <C>TryShortOrbit</C> component.
</Item>
<Mark><C>ShortOrbitsOrbLimit</C></Mark>
<Item>
See the <C>TryShortOrbit</C> component.
</Item>
<Mark><C>Size</C></Mark>
<Item>
If the <C>Size</C> component is set to a positive integer it is taken as
the size of the group <A>G</A>. This information allows to verify the
stabiliser chain simply by looking at its size. If the group object
knows its size already (and the <C>Projective</C> component was not set to
<K>true</K>), then the stored size of the group is automatically taken into
account, such that one does not have to use this option.
</Item>
<Mark><C>StabGenAddSlots</C></Mark>
<Item>
The value of the <C>StabGenAddSlots</C> component is directly handed over
to the product replacer object which is used to generate random elements to
find stabiliser generators.
</Item>
<Mark><C>StabGenMaxDepth</C></Mark>
<Item>
The value of the <C>StabGenMaxDepth</C> component is directly handed over
to the product replacer object which is used to generate random elements to
find stabiliser generators.
</Item>
<Mark><C>StabGenScrambleFactor</C></Mark>
<Item>
The value of the <C>StabGenScrambleFactor</C> component is directly handed over
to the product replacer object which is used to generate random elements to
find stabiliser generators.
</Item>
<Mark><C>StabGenScramble</C></Mark>
<Item>
The value of the <C>StabGenScramble</C> component is directly handed over
to the product replacer object which is used to generate random elements to
find stabiliser generators.
</Item>
<Mark><C>StrictlyUseCandidates</C></Mark>
<Item>
If this component is set to <K>true</K> (default is <K>false</K>) then
only the given candidate points are taken as possible base points. In
particular, the procedure does not take additional points of the previous
orbit as candidates for base points (see component
<C>NumberPrevOrbitPoints</C> ). Use this option in combination to
<C>Reduced</C> set to <K>false</K> to enforce a certain known base.
</Item>
<Mark><C>TryBirthdayParadox</C></Mark>
<Item>
The method to try to find short orbits using the birthday paradox is
used up to <C>TryBirthdayParadox</C> times for each new base point. This
method uses the Murray/O'Brien heuristics to find candidates for short
orbits and then uses statistics using the birthday paradox to estimate the
orbit lengths. As soon as a point is found whose orbit is either estimated
to be smaller than <C>OrbitLimitBirthdayParadox</C> with a solid
statistical estimate or is estimated to be smaller than
<C>OrbitLimitImmediatelyTake</C> with a weak statistical estimate, this
point is taken as the next base point.
</Item>
<Mark><C>TryShortOrbit</C></Mark>
<Item>
The method to try to find short orbits using the standard Murray/O'Brien
heuristics is used up to <C>TryShortOrbit</C> times for each new base
point. This method uses the heuristics to find candicates for short orbits
using <C>ShortOrbitsNrRandoms</C> random group elements.
It then enumerates all these orbits up to the limit
<C>ShortOrbitsInitialLimit</C>. If any of them closes the corresponding 
candidate is taken as the next base point. Otherwise half of the points are
thrown away and the limit is doubled. This goes on until either an orbit
closes or the limit grows over <C>ShortOrbitsOrbLimit</C>.
</Item>
<Mark><C>VerifyElements</C></Mark>
<Item>
This component can be used to set it to the number of random elements that
are used in the end to verify the stabiliser chain statistically.
Usually the user specifies the component <C>ErrorBound</C> instead
and <C>VerifyElements</C> is then computed automatically from that. 
However, if no <C>ErrorBound</C> is given, the <C>VerifyElements</C>
component takes precedence over the <C>random</C> component.
</Item>
<Mark><C>VeryShortOrbLimit</C></Mark>
<Item>
The very first method tried to find the next base point is to enumerate the
orbit of the first and the last basis vector and of one random vector
up to the limit <C>VeryShortOrbLimit</C>. If the orbit closes before this
limit is reached, the corresponding vector is immediately taken.
</Item>
</List>

<!-- This is an option for deterministic verification. Not yet active.
<Mark><C>MaxNumberSchreierGens</C></Mark>
<Item></Item>
<Mark><C>NumberSchreierGens</C></Mark>
<Item></Item>
-->

<ManSection>
<Func Name="GENSS_IsOneProjective" Arg="x"/>
<Returns><C>true</C> or <C>false</C></Returns>
<Description>
This function tests whether or not the matrix <A>x</A> is a scalar multiple
of the identity matrix. This function is useful for projective
action.
</Description>
</ManSection>
</Section>

<Section Label="ChooseBasePoints">
<Heading>How base points are chosen</Heading>

This section explains some internal details of how base points are chosen
during a stabiliser chain computations. As a user, you can probably safely
skip this section and ignore it altogether. However, in situations where
thes stabiliser chain computation is more difficult (for example if
it is difficult to find short orbits), then it can be helpful to know
about these details.

<P/>
Whenever the stabiliser chain computation needs to set up a new layer
in the stabiliser chain it needs a new base point. The first method
it tries is to take a point in the previous orbit one layer up, since
for these points we have a natural upper limit for the orbit length,
namely the orbit length in the layer above. If this does not work
(either there is no higher layer or more than the first
<C>NumberPrevOrbitPoints</C>
(see stabiliser chain options in Section <Ref Sect="StabChainOpts"/>)
in that orbit are fixed by the current group or <C>StrictlyUseCandidates</C>
is <K>true</K>), it is checked whether or not there is another
known candidate for a base point.

<P/>
Note that if the user supplies candidates for the base points and
operations (see component <C>Cand</C> in the stabiliser chain options in
Section <Ref Sect="StabChainOpts"/>), then it is entirely possible that
all base points come from these candidates and the mechanisms described
in this sections are not used at all.

<P/>
However, if the procedure runs out of base points, it needs a way to find
new candidates. This is done using the following operation:

<ManSection>
<Oper Name="FindBasePointCandidates" Arg="g, opt, i, S"/>
<Returns>a <C>Cand</C> record</Returns>
<Description>
This operation returns base point candidates in the form of a record
as for the <C>Cand</C> option for stabiliser chain computations
(see Section <Ref Sect="StabChainOpts"/>).
</Description>
</ManSection>

There are various methods installed to this end which all might fail
and call <C>TryNextMethod();</C>. We do not document the details of
these methods here but only give an overview. For permutation groups
the choice of candidates is very straightforward, one simply takes a
few integers with the usual action <C>OnPoints</C>. For matrix group
finding a reasonably short orbit is more difficult. The system first
handles the case of a scalar group which is easy. Then it hopes to
find a <Q>very short orbit</Q> defined by the component 
<C>VeryShortOrbLimit</C> in the stabiliser chain computation options.
If this fails the birthday paradoxon method is used to find an
estimate for a reasonably short orbit amoung candidates coming from
the Murray and O'Brien heuristics. If this fails the same heuristics
are used but various orbits are enumerated up to a certain point
decreasing the number of orbits as the limit goes up. If all fails
some of the candidates from the heuristics are simply tried
with brute force. The whole computation can fail if some upper orbit
length limit is reached (see component <C>OrbitLengthLimit</C> in the
stabiliser chain computation options).

</Section>

<Section Label="UseStabChain">
<Heading>Using stabiliser chains</Heading>

The most important thing one can do with a stabiliser chain is sifting.
This is done with one of the next to operations:

<ManSection>
<Oper Name="SiftGroupElement" Arg="S, el"/>
<Returns>a record</Returns>
<Description>
The first argument <A>S</A> must be a stabiliser chain object and the 
second argument <A>el</A> a group element (not necessarily contained in the
group described by <A>S</A>). The result is a record describing the result
of the sifting process. The component <C>rem</C> contains the remainder of
the sifting process. If <A>el</A> is contained in the group described by
<A>S</A>, then the remainder is equal to the identity. Note that if
the <C>IsOne</C>-component of the options record for the stabiliser chain 
<A>S</A> is different from the <Ref Prop="IsOne" BookName="Ref"/> 
operation then the 
<C>rem</C> component is equal to the identity according to that test.
The result of this test (<K>true</K> or <K>false</K>) is stored in the
component <C>isone</C> of the resulting record. This means, that this
component indicates whether or not the sifting was successful. The
component <C>S</C> is bound to the stabiliser chain
object corresponding to the layer in which the sifting stopped. If it
ran through the whole chain this component is bound to <K>false</K>.
The component <C>preS</C> is always bound to the previous layer, which is
the lowest layer if the sifting was successful.
</Description>
</ManSection>

<ManSection>
<Oper Name="SiftGroupElementSLP" Arg="S, el"/>
<Returns>a record</Returns>
<Description>
This operation behaves exactly as <Ref Oper="SiftGroupElement"/> except that
in the successful case the component <C>slp</C> of the resulting record
is additionally bound to a straight line program which expresses the element
<A>el</A> in terms of the strong generators of the stabiliser chain
(see <Ref Oper="StrongGenerators"/>).
</Description>
</ManSection>

<ManSection>
<Oper Name="StrongGenerators" Arg="S"/>
<Returns>a list of group elements</Returns>
<Description>
This operation returns the strong generators of the stabiliser chain 
<A>S</A>. This means that each stabiliser in the stabiliser chain is
generated by the subset of the set of strong generators which fix
the corresponding points. Note that each layer of the stabiliser chain
uses some subset of these strong generators as generators for the 
orbit object of that layer.
<P/>
Note further that this operation called for the objects describing the
lower layers of the stabiliser chain always returns all strong
generators for the whole stabiliser chain (top layer).
</Description>
</ManSection>

<ManSection>
<Oper Name="NrStrongGenerators" Arg="S"/>
<Returns>a positive integer</Returns>
<Description>
This operation returns the number of strong generators of the stabiliser chain 
<A>S</A> (see <Ref Oper="StrongGenerators"/>).
</Description>
</ManSection>

<ManSection>
<Oper Name="BaseStabilizerChain" Arg="S"/>
<Returns>a record</Returns>
<Description>
This operation returns the base of the stabiliser chain <A>S</A> in form 
of a record, which can be used as the <C>Cand</C> component for a stabiliser 
chain computation. That is, two components are bound, the <C>points</C> 
component is a list of base points and the <C>ops</C> component is a
corresponding list of action functions.
</Description>
</ManSection>

<ManSection>
<Oper Name="Size" Arg="S"/>
<Returns>a positive integer</Returns>
<Description>
This operation returns the size (i.e. order) of the group described by
the stabiliser chain <A>S</A>. This is simply the product of the lengths
of the orbits in the chain.
</Description>
</ManSection>

<ManSection>
<Oper Name="Random" Arg="S"/>
<Returns>a group element</Returns>
<Description>
This operation can be called with a stabiliser chain object <A>S</A>
or with a group object, if this group object has a stored stabiliser
chain (see <Ref Oper="SetStabilizerChain"/>). The method will randomly
choose transversal elements and thus produce a uniformly distributed
random element of the group.
</Description>
</ManSection>

<ManSection>
<Oper Name="\in" Arg="x, S"/>
<Returns><C>true</C> or <C>false</C></Returns>
<Description>
This operation tests whether or not the group element <A>x</A> lies in the
group described by the stabiliser chain <A>S</A> by sifting
(see <Ref Oper="SiftGroupElement"/>). The argument <A>S</A> can also
be a group object with a stored stabiliser chain 
(see <Ref Oper="SetStabilizerChain"/>). Note that this operation can be
called with the <K>in</K> keyword using infix notation.
</Description>
</ManSection>

<ManSection>
<Oper Name="IsProved" Arg="S"/>
<Returns><C>true</C> or <C>false</C></Returns>
<Description>
This operation returns whether or not the stabiliser chain <A>S</A>
is proved to be correct. If it has only been verified by randomised methods,
<C>false</C> is returned. At the time of this writing the only possible
deterministic verification is if the size of the group is known 
before the stabiliser chain computation begins.
</Description>
</ManSection>

<ManSection>
<Oper Name="GroupIteratorByStabilizerChain" Arg="S"/>
<Returns>an iterator</Returns>
<Description>
This operation returns an iterator object which runs through the
elements of the group described by the stabiliser chain object <A>S</A>.
The usual operations <Ref Oper="NextIterator" BookName="Ref"/> and
<Ref Oper="IsDoneIterator" BookName="Ref"/> as well as the <K>for</K>
loop construction can be used with this object. The iterator is
implemented using the stored transversals in the Schreier trees
of the stabiliser chain.
</Description>
</ManSection>

<ManSection>
<Oper Name="SetStabilizerChain" Arg="g, S"/>
<Returns>nothing</Returns>
<Description>
Once the user is convinced that the stabiliser chain <A>S</A> describes
the group <A>g</A> correctly, he can call this operation to store the
stabiliser chain together with the group object. From then on, additional
methods using the stabiliser chain (for example <Ref Oper="Size"/>,
<Ref Oper="Random"/> and
<Ref Oper="\in"/> above) become applicable for the group object.
Note that if a stabiliser chain is known to be correct (for example if
the group knew its size beforehand), then the stabiliser chain is
stored with the group automatically when it is constructed, which 
makes the explicit storing of the stabiliser chain unnecessary.
<P/>
The stored stabiliser chain of a group object can be used using
<Ref Oper="StoredStabilizerChain"/>.
</Description>
</ManSection>

<ManSection>
<Attr Name="StoredStabilizerChain" Arg="g"/>
<Returns>a stabiliser chain</Returns>
<Description>
This attribute for a group object <A>g</A> contains a stored stabiliser
chain for the group. See <Ref Oper="SetStabilizerChain"/> for details.
</Description>
</ManSection>

<ManSection>
<Meth Name="StabChainOp" Arg="p, S"/>
<Returns>a &GAP; stabiliser chain </Returns>
<Description>
This method computes a standard &GAP; library stabiliser chain for
the permutation group <A>p</A> using the fact that <A>S</A> is a known
correct stabiliser chain for <A>p</A>. If all base points in <A>S</A>
are positive integers and all actions are equal to <C>OnPoints</C>,
then the same base points are taken for the new stabiliser chain.
</Description>
</ManSection>

<ManSection>
<Oper Name="SiftBaseImage" Arg="S, l"/>
<Returns><C>true</C> or <C>false</C></Returns>
<Description>
This operation sifts an image <A>l</A> of the base points of the stabiliser
chain <A>S</A>. This means that the elements of the list <A>l</A> must be
images of the base points under the actions in the various layers of
the stabiliser chain. The sifting procedure using the orbits and Schreier
trees in the stabiliser chain decides if this base image is one for a
group element of the group described by <A>S</A> and returns <C>true</C> or
<C>false</C> accordingly.
<P/>
This operation is mostly used internally.
</Description>
</ManSection>

<ManSection>
<Oper Name="SLPChainStabilizerChain" Arg="S, gens"/>
<Returns>a record</Returns>
<Description>
This operation assumes that <A>S</A> is a stabiliser chain that correctly
describes the group generated by the generators <A>gens</A>. It
returns a list of straight line programs expressing successively
the stabilisers in the chain, each in terms of the generators of
the previous, the first in terms of <A>gens</A>. This list is
stored in the component <C>slps</C> of the resulting record. The sizes
of the groups in the chain are stored in the component <C>sizes</C> of
the resulting record.
</Description>
</ManSection>

The operations, functions and methods described below use stabiliser
chains internally:

<ManSection>
<Func Name="GroupHomomorphismByImagesNCStabilizerChain"
      Arg="g, h, images, opt1, opt2"/>
<Returns>a group homomorphism</Returns>
<Description>
This function creates a group homomorphism object from the group <A>g</A> 
into the group object <A>h</A>, mapping the generators of the group <A>g</A>
to the elements <A>images</A> which must lie in <A>h</A>. This mapping must
be a group homomorphism, note that this is not checked!
<P/>
The homomorphism is computed by computing stabiliser chains on both sides
such that elements can be mapped in both directions simply be sifting and
expressing them in terms of the strong generators. This is where the
two arguments <A>opts1</A> and <A>opts2</A> come into play. The former
is used as the options record for the stabiliser computation in <A>g</A> and
the latter for the one in the group generated by <A>images</A>.
</Description>
</ManSection>

<ManSection>
<Meth Name="FindShortGeneratorsOfSubgroup" Arg="g, u"/>
<Returns>a record</Returns>
<Description>
This is an additional method for matrix or permutation groups implementing
the operation <Ref Oper="FindShortGeneratorsOfSubgroup" BookName="orb"/>
from the <Package>orb</Package> package
using stabiliser chains. Both arguments must be groups and
<A>u</A> must be a subgroup of <A>g</A>.
The resulting record contains two components
<C>gens</C> and <C>slp</C>, where the first is a list of generators
for the group <A>u</A> and the second is a straight line program expressing
<C>gens</C> in terms of the generators of <A>g</A>. This operation aims
to find short words in the generators of <A>g</A> to use as generators
for <A>u</A>.
</Description>
</ManSection>

<ManSection>
<Oper Name="Stab" Arg="g, x, op [,opt]"/>
<Returns>a record or <K>fail</K></Returns>
<Description>
This operation aims to compute the point stabiliser of the group <A>g</A> 
acting via the action function <A>op</A> of the point <A>x</A>. The optional
last argument is an options record. The general approach of this procedure
is to go back and forth between enumerating a part of the orbit 
and trying to produce random elements in the stabiliser using the
already enumerated part of the orbit. Random elements in the stabiliser
are produced by using product replacement in <A>g</A> to produce random
elements of <A>g</A> and then using the Schreier tree of the orbit to
map them back into the stabiliser. If this works, the resulting random
elements are distributed uniformly in the point stabiliser.
<P/>
This routine is a Monte Carlo procedure. If sufficiently many random
elements of the stabiliser have been produced and did not increase
its size, the program concludes that the whole stabiliser is found
and returns a record describing it. Otherwise it returns <K>fail</K>
after some time.
<P/>
The resulting record has the stabiliser in the component <C>stab</C>,
its size estimate in the component <C>size</C>, a stabiliser chain
for <C>stab</C> in the component <C>stabilizerchain</C> and a boolean value
in the component <C>proof</C> indicating whether or not the result is
certain.
<P/>
We do not document all possible options in the options record here, since
we want to allow for the possibility to change these in later versions.
The most important component in the options record is the component
<C>ErrorBound</C> which must be bound to a rational number between 0 and
1 and which is an upper bound for the error probability.
<P/>
Please note again that two types of errors can occur in this program: The
first is that the correct point stabiliser is not found but only a proper
subgroup of it. The second is that the stabiliser chain computation to
estimate its size went wrong and returns an incorrect stabiliser chain.
</Description>
</ManSection>

<!--
Later:

VerifyStabilizerChainTC
VerifyStabilizerChainMC

-->

</Section>
<!-- ############################################################ -->

</Chapter>
