  
  [1X87 [33X[0;0YMore about Stabilizer Chains[133X[101X
  
  [33X[0;0YThis  chapter  contains  some  rather  technical complements to the material
  handled in the chapters [14X42[114X and [14X43[114X.[133X
  
  
  [1X87.1 [33X[0;0YGeneralized Conjugation Technique[133X[101X
  
  [33X[0;0YThe  command  [10XConjugateGroup(  [3XG[103X[10X,  [3Xp[103X[10X  )[110X  (see [2XConjugateGroup[102X ([14X39.2-6[114X)) for a
  permutation  group  [3XG[103X  with  stabilizer  chain equips its result also with a
  stabilizer  chain,  namely with the chain of [3XG[103X conjugate by [3Xp[103X. Conjugating a
  stabilizer  chain  by  a  permutation [3Xp[103X means replacing all the points which
  appear  in  the [10Xorbit[110X components by their images under [3Xp[103X and replacing every
  permutation  [3Xg[103X  which  appears  in  a [10Xlabels[110X or [10Xtransversal[110X component by its
  conjugate  [22Xg^p[122X. The conjugate [22Xg^p[122X acts on the mapped points exactly as [3Xg[103X did
  on the original points, i.e., [22X(pnt.p). g^p = (pnt.g).p[122X. Since the entries in
  the  [10Xtranslabels[110X components are integers pointing to positions of the [10Xlabels[110X
  list, the [10Xtranslabels[110X lists just have to be permuted by [3Xp[103X for the conjugated
  stabilizer.  Then  [10Xgenerators[110X  is  reconstructed  as [10Xlabels{ genlabels }[110X and
  [10Xtransversal{ orbit }[110X as [10Xlabels{ translabels{ orbit } }[110X.[133X
  
  [33X[0;0YThis conjugation technique can be generalized. Instead of mapping points and
  permutations  under the same permutation [3Xp[103X, it is sometimes desirable (e.g.,
  in the context of permutation group homomorphisms) to map the points with an
  arbitrary mapping [22Xmap[122X and the permutations with a homomorphism [22Xhom[122X such that
  the   compatibility  of  the  actions  is  still  valid:  [22Xmap(pnt).hom(g)  =
  map(pnt.g)[122X.  (Of  course the ordinary conjugation is a special case of this,
  with [22Xmap(pnt) = pnt.p[122X and [22Xhom(g) = g^p[122X.)[133X
  
  [33X[0;0YIn the generalized case, the [21Xconjugated[121X chain need not be a stabilizer chain
  for  the image of [22Xhom[122X, since the [21Xpreimage[121X of the stabilizer of [22Xmap(b)[122X (where
  [22Xb[122X  is  a  base  point) need not fix [22Xb[122X, but only fixes the preimage [22Xmap^{-1}(
  map(b)  )[122X setwise. Therefore the method can be applied only to one level and
  the next stabilizer must be computed explicitly. But if [22Xmap[122X is injective, we
  have  [22Xmap(b).hom(g) = map(b)[122X if and only if [22Xb.g = b[122X, and if this holds, then
  [22Xg  =  w(g_1,  ...,  g_n)[122X  is  a  word in the generators [22Xg_1, ..., g_n[122X of the
  stabilizer  of [22Xb[122X  and  [22Xhom(g)  =^*  w(  hom(g_1),  ..., hom(g_n) )[122X is in the
  [21Xconjugated[121X  stabilizer.  If,  more  generally,  [22Xhom[122X  is a right inverse to a
  homomorphism  [22Xφ[122X (i.e., [22Xφ(hom(g)) = g[122X for all [22Xg[122X), equality [22X*[122X holds modulo the
  kernel  of  [22Xφ[122X;  in  this  case  the [21Xconjugated[121X chain can be made into a real
  stabilizer  chain  by extending each level with the generators of the kernel
  and  appending  a  proper  stabilizer  chain of the kernel at the end. These
  special   cases   will   occur  in  the  algorithms  for  permutation  group
  homomorphisms (see [14X40[114X).[133X
  
  [33X[0;0YTo [21Xconjugate[121X the points (i.e., [10Xorbit[110X) and permutations (i.e., [10Xlabels[110X) of the
  Schreier  tree,  a loop is set up over the [10Xorbit[110X list constructed during the
  orbit  algorithm,  and for each vertex [22Xb[122X with unique edge [22Xa(l)b[122X ending at [22Xb[122X,
  the label [22Xl[122X is mapped with [22Xhom[122X and [22Xb[122X with [22Xmap[122X. We assume that the [10Xorbit[110X list
  was built w.r.t. a certain ordering [22X<[122X of the labels, where [22Xl' < l[122X means that
  every  point  in  the  orbit was mapped with [22Xl'[122X before it was mapped with [22Xl[122X.
  This  shape of the [10Xorbit[110X list is guaranteed if the Schreier tree is extended
  only  by  [2XAddGeneratorsExtendSchreierTree[102X  ([14X43.11-10[114X),  and  it is then also
  guaranteed  for  the  [21Xconjugated[121X  Schreier tree. (The ordering of the labels
  cannot be read from the Schreier tree, however.)[133X
  
  [33X[0;0YIn  the  generalized case, it can happen that the edge [22Xa(l)b[122X bears a label [22Xl[122X
  whose  image  is  [21Xold[121X,  i.e., equal to the image of an earlier label [22Xl' < l[122X.
  Because  of  the  compatibility  of  the  actions  we  then  have  [22Xmap(b)  =
  map(a).hom(l)^{-1}  =  map(a).hom(l')^{-1}  =  map(a{l'}^{-1})[122X, so [22Xmap(b)[122X is
  already  equal  to the image of the vertex [22Xa{l'}^{-1}[122X. This vertex must have
  been  encountered  before  [22Xb  = al^{-1}[122X because [22Xl' < l[122X. We conclude that the
  image  of  a  label  can  be  [21Xold[121X  only  if  the  vertex  at  the end of the
  corresponding edge has an [21Xold[121X image, too, but then it need not be [21Xconjugated[121X
  at  all.  A  similar  remark  applies  to  labels which map under [22Xhom[122X to the
  identity.[133X
  
  
  [1X87.2 [33X[0;0YThe General Backtrack Algorithm with Ordered Partitions[133X[101X
  
  [33X[0;0YSection  [14X43.12[114X  describes  the  basic  functions for a backtrack search. The
  purpose  of  this section is to document how the general backtrack algorithm
  is  implemented  in  [5XGAP[105X  and  which parts you have to modify if you want to
  write your own backtrack routines.[133X
  
  
  [1X87.2-1 [33X[0;0YInternal representation of ordered partitions[133X[101X
  
  [33X[0;0Y[5XGAP[105X  represents  an  ordered  partition  as  a  record  with  the  following
  components.[133X
  
  [8X[10Xpoints[110X[8X[108X
        [33X[0;6Ya  list of all points contained in the partition, such that the points
        of each cell from lie consecutively,[133X
  
  [8X[10Xcellno[110X[8X[108X
        [33X[0;6Ya  list  whose  [3Xi[103Xth entry is the number of the cell which contains the
        point [3Xi[103X,[133X
  
  [8X[10Xfirsts[110X[8X[108X
        [33X[0;6Ya  list such that [10Xpoints[firsts[[3Xj[103X[10X]][110X is the first point in [10Xpoints[110X which
        is in cell [3Xj[103X,[133X
  
  [8X[10Xlengths[110X[8X[108X
        [33X[0;6Ya list of the cell lengths.[133X
  
  [33X[0;0YSome  of  the information is redundant, e.g., the [10Xlengths[110X could also be read
  off the [10Xfirsts[110X list, but since this need not be increasing, it would require
  some  searching. Similar for [10Xcellno[110X, which could be replaced by a systematic
  search  of  [10Xpoints[110X, keeping track of what cell is currently being traversed.
  With  the  above  components,  the [3Xm[103Xth cell of a partition [3XP[103X is expressed as
  [10X[3XP[103X[10X.points{  [  [3XP[103X[10X.firsts[[3Xm[103X[10X]  ..  [3XP[103X[10X.firsts[[3Xm[103X[10X]  + [3XP[103X[10X.lengths[[3Xm[103X[10X] - 1 ] }[110X. The most
  important operations, however, to be performed upon [3XP[103X are the splitting of a
  cell  and the reuniting of the two parts. Following the strategy of J. Leon,
  this is done as follows:[133X
  
  [8X(1)[108X
        [33X[0;6YThe  points  which  make up the cell that is to be split are sorted so
        that  the  ones  that  remain inside occupy positions [10X[ [3XP[103X[10X.firsts[[3Xm[103X[10X] ..
        [3Xlast[103X[10X ][110X in the list [10X[3XP[103X[10X.points[110X (for a suitable value of [3Xlast[103X).[133X
  
  [8X(2)[108X
        [33X[0;6YThe points at positions [10X[ [3Xlast[103X[10X + 1 .. [3XP[103X[10X.firsts[[3Xm[103X[10X] + [3XP[103X[10X.lengths[[3Xm[103X[10X] - 1 ][110X
        will  form  the additional cell. For this new cell requires additional
        entries are added to the lists [10X[3XP[103X[10X.firsts[110X (namely, [10X[3Xlast[103X[10X+1[110X) and [10X[3XP[103X[10X.lengths[110X
        (namely, [10X[3XP[103X[10X.firsts[[3Xm[103X[10X] + [3XP[103X[10X.lengths[[3Xm[103X[10X] - [3Xlast[103X[10X - 1[110X).[133X
  
  [8X(3)[108X
        [33X[0;6YThe  entries  of  the  sublist  [10X[3XP[103X[10X.cellno{  [  [3Xlast[103X[10X+1  .. [3XP[103X[10X.firsts[[3Xm[103X[10X] +
        P.lengths[[3Xm[103X[10X]-1 ] }[110X must be set to the number of the new cell.[133X
  
  [8X(4)[108X
        [33X[0;6YThe entry [10X[3XP[103X[10X.lengths[[3Xm[103X[10X][110X must be reduced to [10X[3Xlast[103X[10X - [3XP[103X[10X.firsts[[3Xm[103X[10X] + 1[110X.[133X
  
  [33X[0;0YThen  reuniting  the  two  cells  requires only the reversal of steps 2 to 4
  above. The list [10X[3XP[103X[10X.points[110X need not be rearranged.[133X
  
  
  [1X87.2-2 [33X[0;0YFunctions for setting up an R-base[133X[101X
  
  [33X[0;0YThis  subsection  explains some [5XGAP[105X functions which are local to the library
  file [11Xlib/stbcbckt.gi[111X which contains the code for backtracking in permutation
  groups. They are mentioned here because you might find them helpful when you
  want  to  implement  you  own  backtracking  function based on the partition
  concept.  An  important  argument  to most of the functions is the R-base [22XR[122X,
  which  you  should regard as a black box. We will tell you how to set it up,
  how to maintain it and where to pass it as argument, but it is not necessary
  for you to know its internal representation. However, if you insist to learn
  the whole story: Here are the record components from which an R-base is made
  up:[133X
  
  [8X[10Xdomain[110X[8X[108X
        [33X[0;6Ythe set [22XΩ[122X on which the group [22XG[122X operates[133X
  
  [8X[10Xbase[110X[8X[108X
        [33X[0;6Ythe sequence [22X(a_1, ..., a_r)[122X of base points[133X
  
  [8X[10Xpartition[110X[8X[108X
        [33X[0;6Yan ordered partition, initially [22XΠ_0[122X, this will be refined to [22XΠ_1, ...,
        Π_r[122X during the backtrack algorithm[133X
  
  [8X[10Xwhere[110X[8X[108X
        [33X[0;6Ya list such that [22Xa_i[122X lies in cell number [10Xwhere[110X[22X[i][122X of [22XΠ_i[122X[133X
  
  [8X[10Xrfm[110X[8X[108X
        [33X[0;6Ya  list  whose  [22Xi[122Xth  entry  is a list of refinements which take [22XΣ_i[122X to
        [22XΣ_{i+1}[122X; the structure of a refinement is described below[133X
  
  [8X[10Xchain[110X[8X[108X
        [33X[0;6Ya (copy of a) stabilizer chain for [22XG[122X (not if [22XG[122X is a symmetric group)[133X
  
  [8X[10Xfix[110X[8X[108X
        [33X[0;6Yonly  if  [22XG[122X  is  a  symmetric  group:  a  list  whose [22Xi[122X entry contains
        [10XFixcells( [110X[22XΠ_i[122X[10X )[110X[133X
  
  [8X[10Xlevel[110X[8X[108X
        [33X[0;6Yinitially  equal  to  [10Xchain[110X,  this  will  be changed to chains for the
        stabilizers  [22XG_{a_1  ...  a_i}[122X  for [22Xi = 1, ..., r[122X during the backtrack
        algorithm;  if [22XG[122X is a symmetric group, only the number of moved points
        is stored for each stabilizer[133X
  
  [8X[10Xlev[110X[8X[108X
        [33X[0;6Ya  list  whose  [22Xi[122Xth  entry  remembers  the  [10Xlevel[110X entry for [22XG_{a_1 ...
        a_{i-1}}[122X[133X
  
  [8X[10Xlevel2[110X[8X, [10Xlev2[110X[8X[108X
        [33X[0;6Ya  similar  construction  for  a  second  group  (used in intersection
        calculations),  [9Xfalse[109X  otherwise. This second group [22XH[122X activated if the
        R-base is constructed as [10XEmptyRBase( [110X[22X[ G, H ], Ω, Π_0[122X[10X )[110X (if [22XG = H[122X, [5XGAP[105X
        sets [10Xlevel2 = [110X[9Xtrue[109X instead).[133X
  
  [8X[10XnextLevel[110X[8X[108X
        [33X[0;6Ythis is described below[133X
  
  [33X[0;0YAs  our  guiding  example,  we  present  code  for  the function [2XCentralizer[102X
  ([14X35.4-4[114X)  which  calculates  the centralizer of an element [22Xg[122X in the group [22XG[122X.
  (The real code is more general and has a few more subtleties.)[133X
  
  [4X[32X[104X
    [4XPi_0 := TrivialPartition( omega );[104X
    [4XR := EmptyRBase( G, omega, Pi_0 );[104X
    [4XR.nextLevel := function( Pi, rbase )[104X
    [4Xlocal  fix, p, q, where;[104X
    [4XNextRBasePoint( Pi, rbase );[104X
    [4Xfix := Fixcells( Pi );[104X
    [4Xfor p  in fix  do[104X
    [4X  q := p ^ g;[104X
    [4X  where := IsolatePoint( Pi, q );[104X
    [4X  if where <> false  then[104X
    [4X    Add( fix, q );[104X
    [4X    ProcessFixpoint( R, q );[104X
    [4X    AddRefinement( R, "Centralizer", [ Pi.cellno[ p ], q, where ] );[104X
    [4X    if Pi.lengths[ where ] = 1  then[104X
    [4X      p := FixpointCellNo( Pi, where );[104X
    [4X      ProcessFixpoint( R, p );[104X
    [4X      AddRefinement( R, "ProcessFixpoint", [ p, where ] );[104X
    [4X    fi;[104X
    [4X  fi;[104X
    [4Xod;[104X
    [4Xend;[104X
    [4X[104X
    [4Xreturn PartitionBacktrack([104X
    [4X  G,[104X
    [4X  c -> g ^ c = g,[104X
    [4X  false,[104X
    [4X  R,[104X
    [4X  [ Pi_0, g ],[104X
    [4X  L, R );[104X
  [4X[32X[104X
  
  [33X[0;0YThe list numbers below refer to the line numbers of the code above.[133X
  
  [8X1.[108X
        [33X[0;6Y[10Xomega[110X  is  the set on which [10XG[110X acts and [10XPi_0[110X is the first member of the
        decreasing  sequence  of  partitions mentioned in [14X43.12[114X. We set [10XPi_0 =
        omega[110X, which is constructed as [10XTrivialPartition( omega )[110X, but we could
        have  started with a finer partition, e.g., into unions of [10Xg[110X-cycles of
        the same length.[133X
  
  [8X2.[108X
        [33X[0;6YThis statement sets up the R-base in the variable [10XR[110X.[133X
  
  [8X3.-21.[108X
        [33X[0;6YThese  lines define a function [10XR.nextLevel[110X which is called whenever an
        additional  member  in  the sequence [10XPi_0 [110X[22X≥ Π_1 ≥ ...[122X of partitions is
        needed.  If  [22XΠ_i[122X  does not yet contain enough base points in one-point
        cells,  [5XGAP[105X  will  call  [10XR.nextLevel( [110X[22XΠ_i,[122X[10X R )[110X, and this function will
        choose  a  new  base  point  [22Xa_{i+1}[122X,  refine  [22XΠ_i[122X to [22XΠ_{i+1}[122X (thereby
        [13Xchanging[113X the first argument) and store all necessary information in [10XR[110X.[133X
  
  [8X5.[108X
        [33X[0;6YThis statement selects a new base point [22Xa_{i+1}[122X, which is not yet in a
        one-point  cell of [22XΠ[122X and still moved by the stabilizer [22XG_{a_1 ... a_i}[122X
        of  the  earlier  base  points.  If  certain points of [10Xomega[110X should be
        preferred  as  base point (e.g., because they belong to long cycles of
        [10Xg[110X),  a list of points starting with the most wanted ones, can be given
        as  an  optional  third  argument to [10XNextRBasePoint[110X (actually, this is
        done in the real code for [2XCentralizer[102X ([14X35.4-4[114X)).[133X
  
  [8X6.[108X
        [33X[0;6Y[10XFixcells(  [110X[22XΠ[122X[10X  )[110X  returns  the  list  of points in one-point cells of [22XΠ[122X
        (ordered as the cells are ordered in [22XΠ[122X).[133X
  
  [8X7.[108X
        [33X[0;6YFor every point [22Xp ∈ fix[122X, if we know the image [22Xp[122X[10X^[110X[22Xg[122X under [22Xc ∈ C_G(e)[122X, we
        also  know  [22X(  p[122X[10X^[110X[22Xg )[122X[10X^[110X[22Xc = ( p[122X[10X^[110X[22Xc )[122X[10X^[110X[22Xg[122X. We therefore want to isolate these
        extra points in [22XΠ[122X.[133X
  
  [8X9.[108X
        [33X[0;6YThis  statement  puts point [22Xq[122X in a cell of its own, returning in [10Xwhere[110X
        the  number  of the cell of [22XΠ[122X from which [22Xq[122X was taken. If [22Xq[122X was already
        the only point in its cell, [10Xwhere = [110X[9Xfalse[109X instead.[133X
  
  [8X12.[108X
        [33X[0;6YThis  command  does the necessary bookkeeping for the extra base point
        [22Xq[122X: It prescribes [22Xq[122X as next base in the stabilizer chain for [22XG[122X (needed,
        e.g.,  in  line 5)  and  returns  [9Xfalse[109X  if  [22Xq[122X  was  already fixed the
        stabilizer of the earlier base points (and [9Xtrue[109X otherwise; this is not
        used  here).  Another call to [10XProcessFixpoint[110X like this was implicitly
        made by the function [10XNextRBasePoint[110X to register the chosen base point.
        By  contrast,  the point [22Xq[122X was not chosen this way, so [10XProcessFixpoint[110X
        must be called explicitly for [22Xq[122X.[133X
  
  [8X13.[108X
        [33X[0;6YThis  statement  registers  the function which will be used during the
        backtrack search to perform the corresponding refinements on the [21Ximage
        partition[121X  [22XΣ_i[122X (to yield the refined [22XΣ_{i+1}[122X). After choosing an image
        [22Xb_{i+1}[122X  for the base point [22Xa_{i+1}[122X, [5XGAP[105X will compute [22XΣ_i ∧ ({ b_{i+1}
        },  Ω  ∖ { b_{i+1} })[122X and store this partition in [22XI[122X[10X.partition[110X, where [22XI[122X
        is  a  black  box similar to [22XR[122X, but corresponding to the current [21Ximage
        partition[121X  (hence it is an [21XR-image[121X in analogy to the R-base). Then [5XGAP[105X
        will  call the function [10XRefinements.Centralizer( R, I, Pi.cellno[ p ],
        p,  where  )[110X,  with  the  then  current  values  of [22XR[122X and [22XI[122X, but where
        [22XΠ[122X[10X.cellno[110X[22X[ p ][122X, [22Xp[122X, [10Xwhere[110X still have the values they have at the time of
        this  [10XAddRefinement[110X  command.  This  function call will further refine
        [22XI[122X[10X.partition[110X  to  yield  [22XΣ_{i+1}[122X  as  it  is programmed in the function
        [10XRefinements.Centralizer[110X,   which   is  described  below.  (The  global
        variable  [10XRefinements[110X  is  a  record  which  contains  all  refinement
        functions for all backtracking procedures.)[133X
  
  [8X14.-19.[108X
        [33X[0;6YIf  the  cell  from  which [22Xq[122X was taken out had only two points, we now
        have  an  additional  one-point  cell.  This  condition  is checked in
        line 13  and  if it is true, this extra fixpoint [22Xp[122X is taken (line 15),
        processed  like  [22Xq[122X  before  (line 16)  and is then (line 17) passed to
        another  refinement  function  [10XRefinements.ProcessFixpoint(  R,  I, p,
        where )[110X, which is also described below.[133X
  
  [8X23.-29.[108X
        [33X[0;6YThis  command  starts  the  backtrack  search.  Its result will be the
        centralizer as a subgroup of [22XG[122X. Its arguments are[133X
  
  [8X24.[108X
        [33X[0;6Ythe group we want to run through,[133X
  
  [8X25.[108X
        [33X[0;6Ythe property we want to test, as a [5XGAP[105X function,[133X
  
  [8X26.[108X
        [33X[0;6Y[9Xfalse[109X  if  we  are  looking  for  a  subgroup,  [9Xtrue[109X  in the case of a
        representative search (when the result would be one representative),[133X
  
  [8X27.[108X
        [33X[0;6Ythe R-base,[133X
  
  [8X28.[108X
        [33X[0;6Ya  list  of  data, to be stored in [22XI[122X[10X.data[110X, which has in position 1 the
        first  member  [22XΣ_0[122X  of  the  decreasing  sequence  of [21Ximage partitions[121X
        mentioned  in  [14X43.12[114X.  In the centralizer example, position 2 contains
        the element that is to be centralized. In the case of a representative
        search,  i.e., a conjugacy test [22Xg[122X[10X^[110X[22Xc[122X[10X ?= [110X[22Xh[122X, we would have [22Xh[122X instead of [22Xg[122X
        here,  and  possibly  a [22XΣ_0[122X different from [22XΠ_0[122X (e.g., a partition into
        unions of [22Xh[122X-cycles of same length).[133X
  
  [8X29.[108X
        [33X[0;6Ytwo  subgroups [22XL ≤ C_G(g)[122X and [22XR ≤ C_G(h)[122X known in advance (we have [22XL =
        R[122X in the centralizer case).[133X
  
  
  [1X87.2-3 [33X[0;0YRefinement functions for the backtrack search[133X[101X
  
  [33X[0;0YThe  last  subsection  showed how the refinement process leading from [22XΠ_i[122X to
  [22XΠ_{i+1}[122X  is  coded in the function [22XR[122X[10X.nextLevel[110X, this has to be executed once
  the  base  point  [22Xa_{i+1}[122X. The analogous refinement step from [22XΣ_i[122X to [22XΣ_{i+1}[122X
  must  be  performed  for each choice of an image [22Xb_{i+1}[122X for [22Xa_{i+1}[122X, and it
  will  depend on the corresponding value of [22XΣ_i ∧ ({b_{i+1}}, Ω ∖ {b_{i+1}})[122X.
  But  before  we  can  continue  our  centralizer  example,  we must, for the
  interested  reader, document the record components of the other black box [22XI[122X,
  as we did above for the R-base black box [22XR[122X. Most of the components change as
  [5XGAP[105X walks up and down the levels of the search tree.[133X
  
  [8X[10Xdata[110X[8X[108X
        [33X[0;6Ythis will be mentioned below[133X
  
  [8X[10Xdepth[110X[8X[108X
        [33X[0;6Ythe level [22Xi[122X in the search tree of the current node [22XΣ_i[122X[133X
  
  [8X[10Xbimg[110X[8X[108X
        [33X[0;6Ya list of images of the points in [22XR[122X[10X.base[110X[133X
  
  [8X[10Xpartition[110X[8X[108X
        [33X[0;6Ythe partition [22XΣ_i[122X of the current node[133X
  
  [8X[10Xlevel[110X[8X[108X
        [33X[0;6Ythe stabilizer chain [22XR[122X[10X.lev[110X[22X[i][122X at the current level[133X
  
  [8X[10Xperm[110X[8X[108X
        [33X[0;6Ya permutation mapping [10XFixcells[110X[22X( Π_i )[122X to [10XFixcells[110X[22X( Σ_i )[122X; this implies
        mapping [22X(a_1, ..., a_i)[122X to [22X(b_1, ..., b_i)[122X[133X
  
  [8X[10Xlevel2[110X[8X, [10Xperm2[110X[8X[108X
        [33X[0;6Ya   similar  construction  for  the  second  stabilizer  chain,  [9Xfalse[109X
        otherwise (and [9Xtrue[109X if [22XR[122X[10X.level2 = [110X[9Xtrue[109X)[133X
  
  [33X[0;0YAs  declared  in  the above code for [2XCentralizer[102X ([14X35.4-4[114X), the refinement is
  performed  by  the  function  [10XRefinement.Centralizer[110X[22X(  R, I, Π[122X[10X.cellno[110X[22X[p], p,
  where  )[122X.  The functions in the record [10XRefinement[110X always take two additional
  arguments  before  the  ones specified in the [10XAddRefinement[110X call (in line 13
  above),  namely  the R-base [22XR[122X and the current value [22XI[122X of the [21XR-image[121X. In our
  example,  [22Xp[122X  is  a fixpoint of [22XΠ = Π_i ∧ ({ a_{i+1} }, Ω ∖ { a_{i+1} })[122X such
  that  [22Xwhere = Π[122X[10X.cellno[110X[22X[ p^g ][122X. The [10XRefinement[110X functions must return [9Xfalse[109X if
  the  refinement  is  unsuccessful  (e.g., because it leads to [22XΣ_{i+1}[122X having
  different  cell  sizes  from  [22XΠ_{i+1}[122X)  and  [9Xtrue[109X  otherwise. Our particular
  function looks like this.[133X
  
  [4X[32X[104X
    [4XRefinements.Centralizer := function( R, I, cellno, p, where )[104X
    [4Xlocal  Sigma, q;[104X
    [4XSigma := I.partition;[104X
    [4Xq := FixpointCellNo( Sigma, cellno ) ^ I.data[ 2 ];[104X
    [4Xreturn IsolatePoint( Sigma, q ) = where and ProcessFixpoint( I, p, q );[104X
    [4Xend;[104X
  [4X[32X[104X
  
  [33X[0;0YThe  list  numbers  below  refer to the line numbers of the code immediately
  above.[133X
  
  [8X3.[108X
        [33X[0;6YThe  current  value  of [22XΣ_i ∧ ({ b_{i+1} }, Ω ∖ { b_{i+1} })[122X is always
        found in [22XI[122X[10X.partition[110X.[133X
  
  [8X4.[108X
        [33X[0;6YThe image of the only point in cell number [22Xcellno = Π_i[122X[10X.cellno[110X[22X[ p ][122X in
        [22XΣ[122X under [22Xg = I[122X[10X.data[110X[22X[ 2 ][122X is calculated.[133X
  
  [8X5.[108X
        [33X[0;6YThe function returns [9Xtrue[109X only if the image [22Xq[122X has the same cell number
        in  [22XΣ[122X  as  [22Xp[122X  had  in [22XΠ[122X (i.e., [22Xwhere[122X) and if [22Xq[122X can be prescribed as an
        image  for  [22Xp[122X  under the coset of the stabilizer [22XG_{a_1 ... a_{i+1}}.c[122X
        where  [22Xc  ∈  G[122X is an (already constructed) element mapping the earlier
        base  points  [22Xa_1, ..., a_{i+1}[122X to the already chosen images [22Xb_1, ...,
        b_{i+1}[122X. This latter condition is tested by [10XProcessFixpoint[110X[22X( I, p, q )[122X
        which,  if  successful,  also  does the necessary bookkeeping in [22XI[122X. In
        analogy  to  the remark about line 12 in the program above, the chosen
        image  [22Xb_{i+1}[122X  for  the base point [22Xa_{i+1}[122X has already been processed
        implicitly  by  the  function  [10XPartitionBacktrack[110X, and this processing
        includes the construction of an element [22Xc ∈ G[122X which maps [10XFixcells[110X[22X( Π_i
        )[122X  to  [10XFixcells[110X[22X(  Σ_i )[122X and [22Xa_{i+1}[122X to [22Xb_{i+1}[122X. By contrast, the extra
        fixpoints   [22Xp[122X   and   [22Xq[122X   in  [22XΠ_{i+1}[122X  and  [22XΣ_{i+1}[122X  were  not  chosen
        automatically,  so  they  require an explicit call of [10XProcessFixpoint[110X,
        which  replaces  the  element  [22Xc[122X  by  some  [22Xc'.c[122X (with [22Xc' ∈ G_{a_1 ...
        a_{i+1}}[122X)  which  in addition maps [22Xp[122X to [22Xq[122X, or returns [9Xfalse[109X if this is
        impossible.[133X
  
  [33X[0;0YYou  should  now be able to guess what [10XRefinements.ProcessFixpoint[110X[22X( R, I, p,
  where  )[122X  does:  it  simply  returns  [10XProcessFixpoint[110X[22X(  I, p,[122X[10XFixpointCellNo[110X[22X(
  I[122X[10X.partition[110X[22X, where ) )[122X.[133X
  
  [33X[0;0Y[13XSummary.[113X[133X
  
  [33X[0;0YWhen  you  write your own backtrack functions using the partition technique,
  you  have  to  supply  an  R-base,  including a component [10XnextLevel[110X, and the
  functions  in  the [10XRefinements[110X record which you need. Then you can start the
  backtrack  by  passing  the  R-base  and  the  additional data (for the [10Xdata[110X
  component of the [21XR-image[121X) to [10XPartitionBacktrack[110X.[133X
  
  
  [1X87.2-4 [33X[0;0YFunctions for meeting ordered partitions[133X[101X
  
  [33X[0;0YA kind of refinement that occurs in particular in the normalizer calculation
  involves  computing  the  meet of [22XΠ[122X (cf. lines 6ff. above) with an arbitrary
  other partition [22XΛ[122X, not just with one point. To do this efficiently, [5XGAP[105X uses
  the following two functions.[133X
  
  [33X[0;0Y[10XStratMeetPartition( [110X[22XR[122X, [22XΠ[122X, [22XΛ[122X [10X[[110X, [22Xg[122X [10X] )[110X[133X
  
  [33X[0;0Y[10XMeetPartitionStrat( [110X[22XR[122X, [22XI[122X[10X{, [110X[22XΛ'[122X[10X}[, {[110X[22Xg'[122X[10X}][110X, [22Xstrat[122X [10X)[110X[133X
  
  [33X[0;0YSuch  a  [10XStratMeetPartition[110X  command  would typically appear in the function
  call  [22XR[122X[10X.nextLevel[110X[22X(  Π,  R  )[122X (during the refinement of [22XΠ_i[122X to [22XΠ_{i+1}[122X). This
  command  replaces  [22XΠ[122X  by  [22XΠ  ∧  Λ[122X (thereby [13Xchanging[113X the second argument) and
  returns a [21Xmeet strategy[121X [22Xstrat[122X. This is (for us) a black box which serves two
  purposes:  First, it allows [5XGAP[105X to calculate faster the corresponding meet [22XΣ
  ∧  Λ'[122X,  which  must  then  appear  in  a  [10XRefinements[110X  function  (during the
  refinement  of [22XΣ_i[122X to [22XΣ_{i+1}[122X). It is faster to compute [22XΣ ∧ Λ'[122X with the [21Xmeet
  strategy[121X  of  [22XΠ ∧ Λ[122X because if the refinement of [22XΣ[122X is successful at all, the
  intersection  of  a  cell  from the left hand side of the [22X∧[122X sign with a cell
  from  the  right  hand side must have the same size in both cases (and [22Xstrat[122X
  records these sizes, so that only non-empty intersections must be calculated
  for  [22XΣ  ∧  Λ'[122X).  Second,  if  there  is  a discrepancy between the behaviour
  prescribed  by  [22Xstrat[122X  and  the  behaviour  observed  when  refining  [22XΣ[122X, the
  refinement can immediately be abandoned.[133X
  
  [33X[0;0YOn  the  other  hand,  if  you  only want to meet a partition [22XΠ[122X with [22XΛ[122X for a
  one-time   use,   without   recording   a  strategy,  you  can  simply  type
  [10XStratMeetPartition[110X[22X(  Π,  Λ  )[122X  as  in  the  following  example,  which  also
  demonstrates some other partition-related commands.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XP := Partition( [[1,2],[3,4,5],[6]] );;  Cells( P );[127X[104X
    [4X[28X[ [ 1, 2 ], [ 3, 4, 5 ], [ 6 ] ][128X[104X
    [4X[25Xgap>[125X [27XQ := Partition( OnTuplesTuples( last, (1,3,6) ) );;  Cells( Q );[127X[104X
    [4X[28X[ [ 3, 2 ], [ 6, 4, 5 ], [ 1 ] ][128X[104X
    [4X[25Xgap>[125X [27XStratMeetPartition( P, Q );[127X[104X
    [4X[28X[  ][128X[104X
    [4X[25Xgap>[125X [27X# The ``meet strategy'' was not recorded, ignore this result.[127X[104X
    [4X[25Xgap>[125X [27XCells( P );[127X[104X
    [4X[28X[ [ 1 ], [ 5, 4 ], [ 6 ], [ 2 ], [ 3 ] ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YYou can even say [10XStratMeetPartition[110X[22X( Π, ∆ )[122X where [22X∆[122X is simply a subset of [22XΩ[122X,
  it will then be interpreted as the partition [22X(∆, Ω ∖ ∆)[122X.[133X
  
  [33X[0;0Y[5XGAP[105X  makes  use  of  the  advantages  of  a  [21Xmeet strategy[121X if the refinement
  function in [10XRefinements[110X contains a [10XMeetPartitionStrat[110X command where [22Xstrat[122X is
  the  [21Xmeet  strategy[121X  calculated by [10XStratMeetPartition[110X before. Such a command
  replaces [22XI[122X[10X.partition[110X by its meet with [22XΛ'[122X, again changing the argument [22XI[122X. The
  necessary  reversal  of  these  changes  when  backtracking from a node (and
  prescribing  the next possible image for a base point) is automatically done
  by the function [10XPartitionBacktrack[110X.[133X
  
  [33X[0;0YIn  all  cases,  an additional argument [22Xg[122X means that the meet is to be taken
  not  with  [22XΛ[122X,  but  instead  with  [22XΛ.{g^{-1}}[122X,  where  operation  on ordered
  partitions  is  meant  cellwise (and setwise on each cell). (Analogously for
  the primed arguments.)[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XP := Partition( [[1,2],[3,4,5],[6]] );;[127X[104X
    [4X[25Xgap>[125X [27XStratMeetPartition( P, P, (1,6,3) );;  Cells( P );[127X[104X
    [4X[28X[ [ 1 ], [ 5, 4 ], [ 6 ], [ 2 ], [ 3 ] ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YNote that [22XP.(1,3,6) = Q[122X.[133X
  
  
  [1X87.3 [33X[0;0YStabilizer Chains for Automorphisms Acting on Enumerators[133X[101X
  
  [33X[0;0YThis  section  describes  a  way of representing the automorphism group of a
  group  as  permutation group, following [Sim97]. The code however is not yet
  included in the [5XGAP[105X library.[133X
  
  [33X[0;0YIn  this  section  we  present  an  example in which objects we already know
  (namely,   automorphisms   of   solvable   groups)  are  equipped  with  the
  permutation-like  operations  [10X^[110X  and  [10X/[110X  for action on positive integers. To
  achieve  this,  we  must  define  a  new  type  of objects which behave like
  permutations  but  are represented as automorphisms acting on an enumerator.
  Our  goal is to generalize the Schreier-Sims algorithm for construction of a
  stabilizer chain to groups of such new automorphisms.[133X
  
  
  [1X87.3-1 [33X[0;0YAn operation domain for automorphisms[133X[101X
  
  [33X[0;0YThe  idea  we  describe  here  is  due  to C. Sims. We consider a group [22XA[122X of
  automorphisms  of  a group [22XG[122X, given by generators, and we would like to know
  its  order.  Of  course  we  could  follow the strategy of the Schreier-Sims
  algorithm  (described  in [14X43.6[114X) for [22XA[122X acting on [22XG[122X. This would involve a call
  of  [10XStabChainStrong(  EmptyStabChain( [], One( [3XA[103X[10X ) ), GroupGenerators( [3XA[103X[10X ) )[110X
  where  [10XStabChainStrong[110X is a function as the one described in the pseudo-code
  below:[133X
  
  [4X[32X[104X
    [4XStabChainStrong := function( S, newgens )[104X
    [4X  Extend the Schreier tree of S with newgens.[104X
    [4X  for sch  in  Schreier generators  do[104X
    [4X    if not sch in S.stabilizer  then[104X
    [4X      StabChainStrong( S.stabilizer, [ sch ] );[104X
    [4X    fi;[104X
    [4X  od;[104X
    [4Xend;[104X
  [4X[32X[104X
  
  [33X[0;0YThe  membership  test  [22Xsch  ∉  S[122X[10X.stabilizer[110X  can  be  performed  because the
  stabilizer  chain of [22XS[122X[10X.stabilizer[110X is already correct at that moment. We even
  know  a  base  in  advance,  namely  any  generating  set  for [22XG[122X. Fix such a
  generating  set [22X(g_1, ..., g_d)[122X and observe that this base is generally very
  short  compared  to  the  degree  [22X|G|[122X of the operation. The problem with the
  Schreier-Sims algorithm, however, is then that the length of the first basic
  orbit [22Xg_1.A[122X would already have the magnitude of [22X|G|[122X, and the basic orbits at
  deeper  levels  would not be much shorter. For the advantage of a short base
  we  pay  the high price of long basic orbits, since the product of the (few)
  basic  orbit lengths must equal [22X|A|[122X. Such long orbits make the Schreier-Sims
  algorithm  infeasible,  so  we  have  to look for a longer base with shorter
  basic orbits.[133X
  
  [33X[0;0YAssume that [22XG[122X is solvable and choose a characteristic series with elementary
  abelian  factors.  For  the  sake  of  simplicity we assume that [22XN < G[122X is an
  elementary  abelian  characteristic  subgroup with elementary abelian factor
  group   [22XG/N[122X.  Since  [22XN[122X  is  characteristic,  [22XA[122X  also  acts  as  a  group  of
  automorphisms  on  the  factor  group  [22XG/N[122X,  but  of  course not necessarily
  faithfully.  To retain a faithful action, we let [22XA[122X act on the disjoint union
  [22XG/N[122X  with  [22XG[122X, and choose as base [22X(g_1 N, ..., g_d N, g_1, ..., g_d)[122X. Now the
  first [22Xd[122X basic orbits lie inside [22XG/N[122X and can have length at most [22X[G:N][122X. Since
  the  base  points  [22Xg_1  N,  ...,  g_d N[122X form a generating set for [22XG/N[122X, their
  iterated stabilizer [22XA^(d+1)[122X acts trivially on the factor group [22XG/N[122X, i.e., it
  leaves  the cosets [22Xg_i N[122X invariant. Accordingly, the next [22Xd[122X basic orbits lie
  inside [22Xg_i N[122X (for [22Xi = 1, ..., d[122X) and can have length at most [22X|N|[122X.[133X
  
  [33X[0;0YGeneralizing  this  method  to a characteristic series [22XG = N_0 > N_1 > ... >
  N_l  =  {  1 }[122X of length [22Xl > 2[122X, we can always find a base of length [22Xl.d[122X such
  that  each  basic  orbit is contained in a coset of a characteristic factor,
  i.e.  in  a  set  of  the  form  [22Xg_i  N_{j-1} / N_j[122X (where [22Xg_i[122X is one of the
  generators  of  [22XG[122X  and  [22X1  ≤  j ≤ l[122X). In particular, the length of the basic
  orbits  is  bounded by the size of the corresponding characteristic factors.
  To  implement  a Schreier-Sims algorithm for such a base, we must be able to
  let automorphisms act on cosets of characteristic factors [22Xg_i N_{j-1} / N_j[122X,
  for  varying  [22Xi[122X  and  [22Xj[122X. We would like to translate each such action into an
  action on [22X{ 1, ..., [ N_{j-1}:N_j] }[122X, because then we need not enumerate the
  operation  domain,  which  is the disjoint union of [22XG / N_1[122X, [22XG / N_2 ... G /
  N_l[122X, as a whole. Enumerating it as a whole would result in basic orbits like
  [10Xorbit[110X[22X⊆  { 1001, ..., 1100 }[122X with a [10Xtransversal[110X list whose first 1000 entries
  would be unbound, but still require 4 bytes of memory each (see [14X43.9[114X).[133X
  
  [33X[0;0YIdentifying  each  coset [22Xg_i N_{j-1} / N_j[122X into [22X{ 1, ..., [N_{j-1}:N_j] }[122X of
  course means that we have to change the action of the automorphisms on every
  level  of  the  stabilizer  chain.  Such  flexibility  is  not possible with
  permutations  because  their  effect  on positive integers is [21Xhardwired[121X into
  them, but we can install new operations for automorphisms.[133X
  
  
  [1X87.3-2 [33X[0;0YEnumerators for cosets of characteristic factors[133X[101X
  
  [33X[0;0YSo  far  we  have  not  used  the  fact  that the characteristic factors are
  elementary  abelian,  but  we  will do so from here on. Our first task is to
  implement  an  enumerator  (see  [2XAsList[102X ([14X30.3-8[114X) and [14X21.23[114X) for a coset of a
  characteristic  factor  in a solvable group [22XG[122X. We assume that such a coset [22Xg
  N/M[122X is given by[133X
  
  [8X(1)[108X
        [33X[0;6Ya pcgs for the group [22XG[122X (see [2XPcgs[102X ([14X45.2-1[114X)), let [22Xn =[122X[10XLength( [110X[22Xpcgs[122X[10X )[110X;[133X
  
  [8X(2)[108X
        [33X[0;6Ya  range [22Xrange = [ start .. stop ][122X indicating that [22XN = ⟨ pcgs{ [ start
        ..  n ] } ⟩[122X and [22XM = ⟨ pcgs{ [ stop + 1 .. n ] } ⟩[122X, i.e., the cosets of
        [22Xpcgs{ range }[122X form a base for the vector space [22XN/M[122X;[133X
  
  [8X(3)[108X
        [33X[0;6Ythe representative [22Xg[122X.[133X
  
  [33X[0;0YWe first define a new representation for such enumerators and then construct
  them  by simply putting these three pieces of data into a record object. The
  enumerator  should  behave  as a list of group elements (representing cosets
  modulo [22XM[122X), consequently, its family will be the family of the [22Xpcgs[122X itself.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XDeclareRepresentation( "IsCosetSolvableFactorEnumeratorRep", IsEnumerator,[128X[104X
    [4X[28X    [ "pcgs", "range", "representative" ] );[128X[104X
    [4X[28X[128X[104X
    [4X[28XEnumeratorCosetSolvableFactor := function( pcgs, range, g )[128X[104X
    [4X[28X    return Objectify( NewType( FamilyObj( pcgs ),[128X[104X
    [4X[28X                   IsCosetSolvableFactorEnumeratorRep ),[128X[104X
    [4X[28X                   rec( pcgs := pcgs,[128X[104X
    [4X[28X                       range := range,[128X[104X
    [4X[28X              representative := g ) );[128X[104X
    [4X[28Xend;[128X[104X
  [4X[32X[104X
  
  [33X[0;0YThe  definition  of  the  operations  [2XLength[102X  ([14X21.17-5[114X),  [2X\[\][102X  ([14X21.2-1[114X) and
  [2XPosition[102X  ([14X21.16-1[114X)  is  now  straightforward.  The  code has sometimes been
  abbreviated and is meant [21Xcum grano salis[121X, e.g., the declaration of the local
  variables has been left out.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XInstallMethod( Length, [ IsCosetSolvableFactorEnumeratorRep ],[128X[104X
    [4X[28X    enum -> Product( RelativeOrdersPcgs( enum!.pcgs ){ enum!.range } ) );[128X[104X
    [4X[28X[128X[104X
    [4X[28XInstallMethod( \[\], [ IsCosetSolvableFactorEnumeratorRep,[128X[104X
    [4X[28X        IsPosRat and IsInt ],[128X[104X
    [4X[28X    function( enum, pos )[128X[104X
    [4X[28X    elm := ();[128X[104X
    [4X[28X    pos := pos - 1;[128X[104X
    [4X[28X    for i  in Reversed( enum!.range )  do[128X[104X
    [4X[28X        p := RelativeOrderOfPcElement( enum!.pcgs, i );[128X[104X
    [4X[28X        elm := enum!.pcgs[ i ] ^ ( pos mod p ) * elm;[128X[104X
    [4X[28X        pos := QuoInt( pos, p );[128X[104X
    [4X[28X    od;[128X[104X
    [4X[28X    return enum!.representative * elm;[128X[104X
    [4X[28Xend );[128X[104X
    [4X[28X[128X[104X
    [4X[28XInstallMethod( Position, [ IsCosetSolvableFactorEnumeratorRep,[128X[104X
    [4X[28X        IsObject, IsZeroCyc ],[128X[104X
    [4X[28X    function( enum, elm, zero )[128X[104X
    [4X[28X    exp := ExponentsOfPcElement( enum!.pcgs,[128X[104X
    [4X[28X                   LeftQuotient( enum!.representative, elm ) );[128X[104X
    [4X[28X    pos := 0;[128X[104X
    [4X[28X    for i  in enum!.range  do[128X[104X
    [4X[28X        pos := pos * RelativeOrderOfPcElement( pcgs, i ) + exp[ i ];[128X[104X
    [4X[28X    od;[128X[104X
    [4X[28X    return pos + 1;[128X[104X
    [4X[28Xend );[128X[104X
  [4X[32X[104X
  
  
  [1X87.3-3 [33X[0;0YMaking automorphisms act on such enumerators[133X[101X
  
  [33X[0;0YOur next task is to make automorphisms of the solvable group [22Xpcgs[122X[10X!.group[110X act
  on  [22X[  1  ..[122X[10XLength[110X[22X( enum ) ][122X for such an enumerator [22Xenum[122X. We achieve this by
  introducing  a  new  representation  of  automorphisms on enumerators and by
  putting  the  enumerator together with the automorphism into an object which
  behaves  like  a  permutation.  Turning an ordinary automorphism into such a
  special  automorphism  requires  then the construction of a new object which
  has  the  new  type.  We provide an operation [10XPermOnEnumerator( [3Xmodel[103X[10X, [3Xaut[103X[10X )[110X
  which  constructs  such  a  new  object  having  the same type as [3Xmodel[103X, but
  representing  the  automorphism  [3Xaut[103X.  So  [3Xaut[103X  can  be  either  an ordinary
  automorphism or one which already has an enumerator in its type, but perhaps
  different from the one we want (i.e. from the one in [3Xmodel[103X).[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XDeclareCategory( "IsPermOnEnumerator",[128X[104X
    [4X[28X    IsMultiplicativeElementWithInverse and IsPerm );[128X[104X
    [4X[28X[128X[104X
    [4X[28XDeclareRepresentation( "IsPermOnEnumeratorDefaultRep",[128X[104X
    [4X[28X    IsPermOnEnumerator and IsAttributeStoringRep,[128X[104X
    [4X[28X    [ "perm" ] );[128X[104X
    [4X[28X[128X[104X
    [4X[28XDeclareOperation( "PermOnEnumerator",[128X[104X
    [4X[28X    [ IsEnumerator, IsObject ] );[128X[104X
    [4X[28X[128X[104X
    [4X[28XInstallMethod( PermOnEnumerator,[128X[104X
    [4X[28X    [ IsEnumerator, IsObject ],[128X[104X
    [4X[28X    function( enum, a )[128X[104X
    [4X[28X    SetFilterObj( a, IsMultiplicativeElementWithInverse );[128X[104X
    [4X[28X    a := Objectify( NewKind( PermutationsOnEnumeratorsFamily,[128X[104X
    [4X[28X                 IsPermOnEnumeratorDefaultRep ),[128X[104X
    [4X[28X                 rec( perm := a ) );[128X[104X
    [4X[28X    SetEnumerator( a, enum );[128X[104X
    [4X[28X    return a;[128X[104X
    [4X[28Xend );[128X[104X
    [4X[28X[128X[104X
    [4X[28XInstallMethod( PermOnEnumerator,[128X[104X
    [4X[28X    [ IsEnumerator, IsPermOnEnumeratorDefaultRep ],[128X[104X
    [4X[28X    function( enum, a )[128X[104X
    [4X[28X    a := Objectify( TypeObj( a ), rec( perm := a!.perm ) );[128X[104X
    [4X[28X    SetEnumerator( a, enum );[128X[104X
    [4X[28X    return a;[128X[104X
    [4X[28Xend );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YNext  we  have to install new methods for the operations which calculate the
  product of two automorphisms, because this product must again have the right
  type.  We  also have to write a function which uses the enumerators to apply
  such an automorphism to positive integers.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28XInstallMethod( \*, IsIdenticalObj,[128X[104X
    [4X[28X    [ IsPermOnEnumeratorDefaultRep, IsPermOnEnumeratorDefaultRep ],[128X[104X
    [4X[28X    function( a, b )[128X[104X
    [4X[28X    perm := a!.perm * b!.perm;[128X[104X
    [4X[28X    SetIsBijective( perm, true );[128X[104X
    [4X[28X    return PermOnEnumerator( Enumerator( a ), perm );[128X[104X
    [4X[28Xend );[128X[104X
    [4X[28X[128X[104X
    [4X[28XInstallMethod( \^,[128X[104X
    [4X[28X    [ IsPosRat and IsInt, IsPermOnEnumeratorDefaultRep ],[128X[104X
    [4X[28X    function( p, a )[128X[104X
    [4X[28X    return PositionCanonical( Enumerator( a ),[128X[104X
    [4X[28X                   Enumerator( a )[ p ] ^ a!.perm );[128X[104X
    [4X[28Xend );[128X[104X
  [4X[32X[104X
  
  [33X[0;0YHow the corresponding methods for [10X[3Xp[103X[10X / [3Xaut[103X[10X[110X and [10X[3Xaut[103X[10X ^ [3Xn[103X[10X[110X look like is obvious.[133X
  
  [33X[0;0YNow  we  can formulate the recursive procedure [10XStabChainStrong[110X which extends
  the  stabilizer  chain  by  adding  in  new  generators  [22Xnewgens[122X. We content
  ourselves  again  with pseudo-code, emphasizing only the lines which set the
  [10XEnumeratorDomainPermutation[110X.  We  assume  that  initially  [22XS[122X is a stabilizer
  chain  for  the  trivial  subgroup  with  a  level  for  each pair [22X(range,g)[122X
  characterizing  an  enumerator (as described above). We also assume that the
  [10Xidentity[110X  element  at  each level already has the type corresponding to that
  level.[133X
  
  [4X[32X[104X
    [4XStabChainStrong := function( S, newgens )[104X
    [4X  for i  in [ 1 .. Length( newgens ) ]  do[104X
    [4X    newgens[ i ] := AutomorphismOnEnumerator( S.identity, newgens[ i ] );[104X
    [4X  od;[104X
    [4X  Extend the Schreier tree of S with newgens.[104X
    [4X  for sch  in  Schreier generators  do[104X
    [4X    if not sch in S.stabilizer  then[104X
    [4X      StabChainStrong( S.stabilizer, [ sch ] );[104X
    [4X    fi;[104X
    [4X  od;[104X
    [4Xend;[104X
  [4X[32X[104X
  
