One of the most important tools in group theory is the operation or action of a group on a certain set.
We say that a group G operates on a set D if we have a function that takes each pair (d,g) with d in D and g in G to another element d^g in D, which we call the image of d under g, such that d^{identity} = d and (d^g)^h = d^{gh} for each d in D and g,h in G.
This is equivalent to saying that an operation is a homomorphism of the group G into the full symmetric group on D. We usually call D the domain of the operation and its elements points.
In this section we will demonstrate how you can compute with operations of groups. For an example we will use the alternating group on 8 points.
    gap> a8 := Group( (1,2,3), (2,3,4,5,6,7,8) );;
    gap> a8.name := "a8";;
It is important to note however, that the applicability of the functions from the operation package is not restricted to permutation groups. All the functions mentioned in this section can also be used to compute with the operation of a matrix group on the vectors, etc. We only use a permutation group here because this makes the examples more compact.
The standard  operation in GAP is always  denoted  by the caret (^)
operator.  That means that when no other operation  is specified (we will
see below  how this  can be  done) all the functions from the  operations
package will  compute the image of a point p  under  an  element g as
p^g.  Note  that  this  can  already  denote different operations,
depending on the type of points and the type of elements.  For example if
the  group elements  are  permutations it can  either denote  the  normal
operation when the points are integers or the conjugation when the points
are permutations  themselves  (see  Operations for  Permutations).  For
another  example if the group elements are matrices  it can either denote
the multiplication from  the right  when  the points are vectors or again
the conjugation  when  the  points are  matrices (of the same  dimension)
themselves  (see  Operations  for  Matrices).    Which  operations  are
available through  the caret  operator  for  a particular  type of  group
elements is described in the chapter for this type of group elements.
    gap> 2 ^ (1,2,3);
    3
    gap> 1 ^ a8.2;
    1
    gap> (2,4) ^ (1,2,3);
    (3,4) 
The most  basic  function  of  the  operations  package  is the  function
Orbit, which computes  the  orbit of a point under the operation of the
group.
    gap> Orbit( a8, 2 );
    [ 2, 3, 1, 4, 5, 6, 7, 8 ] 
Note that the orbit is not a set, because it is not sorted. See Orbit for the definition in which order the points appear in an orbit.
We will  try to  find several  subgroups  in  a8 using  the  operations
package.  One subgroup is immediately available, namely the stabilizer of
one  point.  The index  of the stabilizer must of  course be equal to the
length of the orbit, i.e., 8.
    gap> u8 := Stabilizer( a8, 1 );
    Subgroup( a8, [ (2,3,4,5,6,7,8), (3,8,7) ] )
    gap> Index( a8, u8 );
    8 
This gives us a hint how to find further subgroups. Each subgroup is the stabilizer of a point of an appropriate transitive operation (namely the operation on the cosets of that subgroup or another operation that is equivalent to this operation).
So the question is how to find other operations.  The obvious thing is to
operate  on  pairs  of  points.   So  using  the  function Tuples  (see
Tuples) we first generate a list of all pairs.
    gap> pairs := Tuples( [1..8], 2 );
    [ [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ],
      [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ],
      [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 1 ], [ 3, 2 ],
      [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ],
      [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ],
      [ 4, 7 ], [ 4, 8 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ],
      [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 6, 1 ], [ 6, 2 ],
      [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ],
      [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ],
      [ 7, 7 ], [ 7, 8 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ],
      [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ] ] 
Now we would like to have a8 operate on this domain.  But we cannot use
the default operation (denoted by the caret) because list ^  perm
is  not defined.  So we  must  tell the  functions  from  the  operations
package how the group elements operate on the elements of the domain.  In
our example we can do this by simply passing  OnPairs as  optional last
argument.  All functions from  the  operations  package  accept  such  an
optional  argument  that describes the operation.  See Other Operations
for a list of the available nonstandard operations.
Note  that those operations are in  fact simply functions  that  take  an
element of the domain and an element of the group and return the image of
the element of the domain under  the group element.   So  to  compute the
image of the  pair [1,2] under  the permutation (1,4,5) we can simply
write
    gap> OnPairs( [1,2], (1,4,5) );
    [ 4, 2 ] 
As was mentioned above we have to make sure that the operation is transitive. So we check this.
    gap> IsTransitive( a8, pairs, OnPairs );
    false 
The operation is not transitive,  so we want to  find out what the orbits
are.  The function Orbits does that for you.  It returns a list  of all
the orbits.
    gap> orbs := Orbits( a8, pairs, OnPairs );
    [ [ [ 1, 1 ], [ 2, 2 ], [ 3, 3 ], [ 4, 4 ], [ 5, 5 ], [ 6, 6 ],
          [ 7, 7 ], [ 8, 8 ] ],
      [ [ 1, 2 ], [ 2, 3 ], [ 1, 3 ], [ 3, 1 ], [ 3, 4 ], [ 2, 1 ],
          [ 1, 4 ], [ 4, 1 ], [ 4, 5 ], [ 3, 2 ], [ 2, 4 ], [ 1, 5 ],
          [ 4, 2 ], [ 5, 1 ], [ 5, 6 ], [ 4, 3 ], [ 3, 5 ], [ 2, 5 ],
          [ 1, 6 ], [ 5, 3 ], [ 5, 2 ], [ 6, 1 ], [ 6, 7 ], [ 5, 4 ],
          [ 4, 6 ], [ 3, 6 ], [ 2, 6 ], [ 1, 7 ], [ 6, 4 ], [ 6, 3 ],
          [ 6, 2 ], [ 7, 1 ], [ 7, 8 ], [ 6, 5 ], [ 5, 7 ], [ 4, 7 ],
          [ 3, 7 ], [ 2, 7 ], [ 1, 8 ], [ 7, 5 ], [ 7, 4 ], [ 7, 3 ],
          [ 7, 2 ], [ 8, 1 ], [ 8, 2 ], [ 7, 6 ], [ 6, 8 ], [ 5, 8 ],
          [ 4, 8 ], [ 3, 8 ], [ 2, 8 ], [ 8, 6 ], [ 8, 5 ], [ 8, 4 ],
          [ 8, 3 ], [ 8, 7 ] ] ] 
The  operation of a8 on the first orbit is of course equivalent to  the
original operation, so we ignore it and work with the second orbit.
    gap> u56 := Stabilizer( a8, [1,2], OnPairs );
    Subgroup( a8, [ (3,8,7), (3,6)(4,7,5,8), (6,7,8) ] )
    gap> Index( a8, u56 );
    56 
So  now  we  have  found  a  second  subgroup.   To  make  the  following
computations a  little bit easier and more efficient we would now like to
work on the points [1..56] instead of the  list of pairs.  The function
Operation does what we need.  It creates a  new group that  operates on
[1..56] in the same way that a8 operates on the second orbit.
    gap> a8_56 := Operation( a8, orbs[2], OnPairs );
    Group( ( 1, 2, 4)( 3, 6,10)( 5, 7,11)( 8,13,16)(12,18,17)(14,21,20)
    (19,27,26)(22,31,30)(28,38,37)(32,43,42)(39,51,50)(44,45,55),
    ( 1, 3, 7,12,19,28,39)( 2, 5, 9,15,23,33,45)( 4, 8,14,22,32,44, 6)
    (10,16,24,34,46,56,51)(11,17,25,35,47,43,55)(13,20,29,40,52,38,50)
    (18,26,36,48,31,42,54)(21,30,41,53,27,37,49) )
    gap> a8_56.name := "a8_56";;
We would now like to know if the subgroup u56 of index 56 that we found
is  maximal or  not.   Again  we can make  use  of  a function  from  the
operations package.  Namely a subgroup is maximal if the operation on the
cosets of  this subgroup is primitive, i.e., if there is no  partition of
the  set of  cosets into subsets such that  the group operates setwise on
those subsets.
    gap> IsPrimitive( a8_56, [1..56] );
    false 
Note that we must specify  the domain of the operation.  You  might think
that in  the last  example IsPrimitive could  use  [1..56] as default
domain if  no domain was given.  But  this is not so simple,  for example
would the default domain of Group( (2,3,4) )  be [1..4] or  [2..4]?
To avoid  confusion, all  operations  package functions require  that you
specify the domain of operation.
We see that a8_56 is  not  primitive.  This means of course  that  the
operation of  a8  on  orb[2]  is  not  primitive,  because  those two
operations are equivalent.   So the stabilizer u56 is not maximal.  Let
us  try to find its supergroups.  We use the  function Blocks to find a
block  system.   The (optional) third argument  in the following  example
tells Blocks that we  want a  block  system where  1 and 10 lie in  one
block.  There are several other block systems, which we could compute  by
specifying a  different pair, it just  turns out that  [1,10] makes the
following computation more interesting.
    gap> blocks := Blocks( a8_56, [1..56], [1,10] );
    [ [ 1, 10, 13, 21, 31, 43, 45 ], [ 2, 3, 16, 20, 30, 42, 55 ],
      [ 4, 6, 8, 14, 22, 32, 44 ], [ 5, 7, 11, 24, 29, 41, 54 ],
      [ 9, 12, 17, 18, 34, 40, 53 ], [ 15, 19, 25, 26, 27, 46, 52 ],
      [ 23, 28, 35, 36, 37, 38, 56 ], [ 33, 39, 47, 48, 49, 50, 51 ] ] 
The result is a  list of  sets,  i.e., sorted  lists,  such that a8_56
operates on  those  sets.  Now  we  would  like  the  stabilizer of  this
operation on the sets.  Because  we wanted to operate on the sets we have
to pass OnSets as third argument.
    gap> u8_56 := Stabilizer( a8_56, blocks[1], OnSets );
    Subgroup( a8_56,
    [ (15,35,48)(19,28,39)(22,32,44)(23,33,52)(25,36,49)(26,37,50)
        (27,38,51)(29,41,54)(30,42,55)(31,43,45)(34,40,53)(46,56,47),
      ( 9,25)(12,19)(14,22)(15,34)(17,26)(18,27)(20,30)(21,31)(23,48)
        (24,29)(28,39)(32,44)(33,56)(35,47)(36,49)(37,50)(38,51)(40,52)
        (41,54)(42,55)(43,45)(46,53), ( 5,17)( 7,12)( 8,14)( 9,24)(11,18)
        (13,21)(15,25)(16,20)(23,47)(28,39)(29,34)(32,44)(33,56)(35,49)
        (36,48)(37,50)(38,51)(40,54)(41,53)(42,55)(43,45)(46,52),
      ( 2,11)( 3, 7)( 4, 8)( 5,16)( 9,17)(10,13)(20,24)(23,47)(25,26)
        (28,39)(29,30)(32,44)(33,56)(35,48)(36,50)(37,49)(38,51)(40,53)
        (41,55)(42,54)(43,45)(46,52), ( 1,10)( 2, 6)( 3, 4)( 5, 7)( 8,16)
        (12,17)(14,20)(19,26)(22,30)(23,47)(28,50)(32,55)(33,56)(35,48)
        (36,49)(37,39)(38,51)(40,53)(41,54)(42,44)(43,45)(46,52) ] )
    gap> Index( a8_56, u8_56 );
    8 
Now  we have  a problem.   We  have found a  new  subgroup, but not  as a
subgroup of a8, instead  it  is a subgroup of a8_56.   We  know that
a8_56 is isomorphic to a8 (in  general the  result of Operation is
only isomorphic to a factor group of the original group, but in this case
it must be  isomorphic to a8, because a8  is  simple and has only the
full  group as  nontrivial  factor group).   But we  only  know  that  an
isomorphism exists, we do not know it.
Another  function comes  to our rescue.  OperationHomomorphism  returns
the  homomorphism of a  group  onto  the group  that  was  constructed by
Operation.  A later section in this chapter will introduce mappings and
homomorphisms  in  general,  but  for the  moment we  can just regard the
result  of OperationHomomorphism as  a  black box that  we can  use  to
transfer information from a8 to a8_56 and back.
    gap> h56 := OperationHomomorphism( a8, a8_56 );
    OperationHomomorphism( a8, a8_56 )
    gap> u8b := PreImages( h56, u8_56 );
    Subgroup( a8, [ (6,7,8), (5,6)(7,8), (4,5)(7,8), (3,4)(7,8),
      (1,3)(7,8) ] )
    gap> Index( a8, u8b );
    8
    gap> u8 = u8b;
    false 
So we have  in fact found a new subgroup.   However if we  look closer we
note that u8b is not  totally new.  It fixes  the point 2, thus it lies
in  the  stabilizer of  2, and because  it  has the  same  index  as this
stabilizer it must in fact be the stabilizer.  Thus  u8b is  conjugated
to u8.  A nice way to check  this is to check that the operation on the
8 blocks is equivalent to the original operation.
    gap> IsEquivalentOperation( a8, [1..8], a8_56, blocks, OnSets );
    true 
Now the choice of the third  argument [1,10] of Blocks becomes clear.
Had  we not  given that argument  we would have obtained the block system
that  has  [1,3,7,12,19,28,39] as first  block.   The  preimage of  the
stabilizer of this set would have been u8 itself, and we would not have
been able to  introduce IsEquivalentOperation.  Of course we could also
use the  general  function  IsConjugate,  but  we  want  to demonstrate
IsEquivalentOperation.
Actually there  is a  third block system of a8_56 that gives rise to a
third subgroup.
    gap> blocks := Blocks( a8_56, [1..56], [1,6] );
    [ [ 1, 6 ], [ 2, 10 ], [ 3, 4 ], [ 5, 16 ], [ 7, 8 ], [ 9, 24 ],
      [ 11, 13 ], [ 12, 14 ], [ 15, 34 ], [ 17, 20 ], [ 18, 21 ],
      [ 19, 22 ], [ 23, 46 ], [ 25, 29 ], [ 26, 30 ], [ 27, 31 ],
      [ 28, 32 ], [ 33, 56 ], [ 35, 40 ], [ 36, 41 ], [ 37, 42 ],
      [ 38, 43 ], [ 39, 44 ], [ 45, 51 ], [ 47, 52 ], [ 48, 53 ],
      [ 49, 54 ], [ 50, 55 ] ]
    gap> u28_56 := Stabilizer( a8_56, [1,6], OnSets );
    Subgroup( a8_56,
    [ ( 2,38,51)( 3,28,39)( 4,32,44)( 5,41,54)(10,43,45)(16,36,49)
        (17,40,53)(20,35,48)(23,47,30)(26,46,52)(33,55,37)(42,56,50),
      ( 5,17,26,37,50)( 7,12,19,28,39)( 8,14,22,32,44)( 9,15,23,33,54)
        (11,18,27,38,51)(13,21,31,43,45)(16,20,30,42,55)(24,34,46,56,49)
        (25,35,47,41,53)(29,40,52,36,48),
      ( 1, 6)( 2,39,38,19,18, 7)( 3,51,28,27,12,11)( 4,45,32,31,14,13)
        ( 5,55,33,23,15, 9)( 8,10,44,43,22,21)(16,50,56,46,34,24)
        (17,54,42,47,35,25)(20,49,37,52,40,29)(26,53,41,30,48,36) ] )
    gap> u28 := PreImages( h56, u28_56 );
    Subgroup( a8, [ (3,7,8), (4,5,6,7,8), (1,2)(3,8,7,6,5,4) ] )
    gap> Index( a8, u28 );
    28 
We know that the subgroup u28 of  index 28 is  maximal, because we know
that a8 has  no subgroups of  index 2,  4, or  7.  However  we can also
quickly verify this by checking that a8_56 operates primitively on the
28 blocks.
    gap> IsPrimitive( a8_56, blocks, OnSets );
    true 
There is a different way to obtain u28.  Instead of operating on the 56
pairs  [ [1,2], [1,3], ..., [8,7] ] we  could operate on the 28 sets of
two elements from [1..8].  But suppose we make a small mistake.
    gap> OrbitLength( a8, [2,1], OnSets );
    Error, OnSets: <tuple> must be a set 
It is your responsibility to make sure that the  points that you pass to
functions from the operations  package are in normal form.   That  means
that they must be sets if you operate on sets with OnSets, they must be
lists of length 2 if you operate on pairs with OnPairs, etc.  This also
applies to functions that accept a domain of operation, e.g., Operation
and IsPrimitive.  All points in such a domain must be in  normal  form.
It is not guaranteed that a violation of this rule will signal an error,
you may obtain incorrect results.
Note  that Stabilizer  is not only applicable to groups like  a8  but
also  to their  subgroups  like  u56.  So another  method to find a new
subgroup  is  to compute the  stabilizer of another point in u56.  Note
that u56 already leaves 1 and 2 fixed.
    gap> u336 := Stabilizer( u56, 3 );
    Subgroup( a8, [ (4,6,5), (5,6)(7,8), (6,7,8) ] )
    gap> Index( a8, u336 );
    336 
Other  functions are also applicable to subgroups.   In the  following we
show that u336  operates regularly on the  60 triples of [4..8] which
contain no  element  twice, which means that this operation is equivalent
to the operations of u336 on its 60 elements from the right.  Note that
OnTuples is a generalization of OnPairs.
    gap> IsRegular( u336, Orbit( u336, [4,5,6], OnTuples ), OnTuples );
    true 
Just as we did in the case  of  the operation on the pairs above, we  now
construct a new permutation group that operates on [1..336] in the same
way that a8 operates on the cosets of u336.  Note that  the operation
of a group on  the  cosets is by  multiplication from the right, thus  we
have to specify OnRight.
    gap> a8_336 := Operation( a8, Cosets( a8, u336 ), OnRight );;
    gap> a8_336.name := "a8_336";;
To find  subgroups above  u336  we  again  check if  the  operation  is
primitive.
    gap> blocks := Blocks( a8_336, [1..336], [1,43] );
    [ [ 1, 43, 85 ], [ 2, 102, 205 ], [ 3, 95, 165 ], [ 4, 106, 251 ],
      [ 5, 117, 334 ], [ 6, 110, 294 ], [ 7, 122, 127 ], [ 8, 144, 247 ],
      [ 9, 137, 207 ], [ 10, 148, 293 ], [ 11, 45, 159 ],
      [ 12, 152, 336 ], [ 13, 164, 169 ], [ 14, 186, 289 ],
      [ 15, 179, 249 ], [ 16, 190, 335 ], [ 17, 124, 201 ],
      [ 18, 44, 194 ], [ 19, 206, 211 ], [ 20, 228, 331 ],
      [ 21, 221, 291 ], [ 22, 46, 232 ], [ 23, 166, 243 ],
      [ 24, 126, 236 ], [ 25, 248, 253 ], [ 26, 48, 270 ],
      [ 27, 263, 333 ], [ 28, 125, 274 ], [ 29, 208, 285 ],
      [ 30, 168, 278 ], [ 31, 290, 295 ], [ 32, 121, 312 ],
      [ 33, 47, 305 ], [ 34, 167, 316 ], [ 35, 250, 327 ],
      [ 36, 210, 320 ], [ 37, 74, 332 ], [ 38, 49, 163 ], [ 39, 81, 123 ],
      [ 40, 59, 209 ], [ 41, 70, 292 ], [ 42, 66, 252 ], [ 50, 142, 230 ],
      [ 51, 138, 196 ], [ 52, 146, 266 ], [ 53, 87, 131 ],
      [ 54, 153, 302 ], [ 55, 160, 174 ], [ 56, 182, 268 ],
      [ 57, 178, 234 ], [ 58, 189, 304 ], [ 60, 86, 199 ],
      [ 61, 198, 214 ], [ 62, 225, 306 ], [ 63, 218, 269 ],
      [ 64, 88, 235 ], [ 65, 162, 245 ], [ 67, 233, 254 ],
      [ 68, 90, 271 ], [ 69, 261, 301 ], [ 71, 197, 288 ],
      [ 72, 161, 281 ], [ 73, 265, 297 ], [ 75, 89, 307 ],
      [ 76, 157, 317 ], [ 77, 229, 328 ], [ 78, 193, 324 ],
      [ 79, 116, 303 ], [ 80, 91, 158 ], [ 82, 101, 195 ],
      [ 83, 112, 267 ], [ 84, 108, 231 ], [ 92, 143, 237 ],
      [ 93, 133, 200 ], [ 94, 150, 273 ], [ 96, 154, 309 ],
      [ 97, 129, 173 ], [ 98, 184, 272 ], [ 99, 180, 238 ],
      [ 100, 188, 308 ], [ 103, 202, 216 ], [ 104, 224, 310 ],
      [ 105, 220, 276 ], [ 107, 128, 241 ], [ 109, 240, 256 ],
      [ 111, 260, 311 ], [ 113, 204, 287 ], [ 114, 130, 277 ],
      [ 115, 275, 296 ], [ 118, 132, 313 ], [ 119, 239, 330 ],
      [ 120, 203, 323 ], [ 134, 185, 279 ], [ 135, 175, 242 ],
      [ 136, 192, 315 ], [ 139, 171, 215 ], [ 140, 226, 314 ],
      [ 141, 222, 280 ], [ 145, 244, 258 ], [ 147, 262, 318 ],
      [ 149, 170, 283 ], [ 151, 282, 298 ], [ 155, 246, 329 ],
      [ 156, 172, 319 ], [ 176, 227, 321 ], [ 177, 217, 284 ],
      [ 181, 213, 257 ], [ 183, 264, 322 ], [ 187, 286, 300 ],
      [ 191, 212, 325 ], [ 219, 259, 326 ], [ 223, 255, 299 ] ] 
To find the subgroup of index 112 that belongs to this operation we could
use the  same methods  as before, but we actually use  a different trick.
From the  above we see that the subgroup is the union of u336  with its
43rd and its 85th coset.  Thus we simply add a representative of the 43rd
coset to the generators of u336.
    gap> u112 := Closure( u336, Representative( Cosets(a8,u336)[43] ) );
    Subgroup( a8, [ (4,6,5), (5,6)(7,8), (6,7,8), (1,3,2) ] )
    gap> Index( a8, u112 );
    112 
Above this subgroup of index 112 lies a  subgroup  of index 56, which  is
not conjugate to u56.  In fact, unlike u56 it is  maximal.  We obtain
this subgroup in  the same way that we obtained u112, this time forcing
two points, namely 39 and 43 into the first block.
    gap> blocks := Blocks( a8_336, [1..336], [1,39,43] );;
    gap> Length( blocks );
    56
    gap> u56b := Closure( u112, Representative( Cosets(a8,u336)[39] ) );
    Subgroup( a8, [ (4,6,5), (5,6)(7,8), (6,7,8), (1,3,2), (2,3)(7,8) ] )
    gap> Index( a8, u56b );
    56
    gap> IsPrimitive( a8_336, blocks, OnSets );
    true 
We already mentioned  in the beginning  that  there  is another  standard
operation of  permutations, namely  the  conjugation.   E.g., because  no
other operation  is  specified  in the  following  example  OrbitLength
simply  operates  using the caret operator and because perm1^perm2
is defined  as the  conjugation  of perm2  on  perm1  we  effectively
compute the length of the conjugacy class of (1,2)(3,4)(5,6)(7,8).  (In
fact  element1^element2  is  always defined  as the conjugation if
element1 and element2 are group elements of  the  same  type.  So the
length of a conjugacy class  of any  element elm  in an arbitrary group
G can be computed as OrbitLength( G, elm  ).  In general  however
this may not be a good  idea, Size( ConjugacyClass( G,  elm ) )  is
probably more efficient.)
    gap> OrbitLength( a8, (1,2)(3,4)(5,6)(7,8) );
    105
    gap> orb := Orbit( a8, (1,2)(3,4)(5,6)(7,8) );;
    gap> u105 := Stabilizer( a8, (1,2)(3,4)(5,6)(7,8) );
    Subgroup( a8, [ (5,6)(7,8), (1,2)(3,4)(5,6)(7,8), (5,7)(6,8),
      (3,4)(7,8), (3,5)(4,6), (1,3)(2,4) ] )
    gap> Index( a8, u105 );
    105 
Of course the last stabilizer  is in  fact the centralizer of the element
(1,2)(3,4)(5,6)(7,8).   Stabilizer  notices  that  and  computes  the
stabilizer using the centralizer algorithm for permutation groups.
In the usual way we now look for the subgroups that lie above u105.
    gap> blocks := Blocks( a8, orb );;
    gap> Length( blocks );
    15
    gap> blocks[1];
    [ (1,2)(3,4)(5,6)(7,8), (1,3)(2,4)(5,7)(6,8), (1,4)(2,3)(5,8)(6,7),
      (1,5)(2,6)(3,7)(4,8), (1,6)(2,5)(3,8)(4,7), (1,7)(2,8)(3,5)(4,6),
      (1,8)(2,7)(3,6)(4,5) ]
To find the subgroup of index 15 we  again use closure.  Now we must be a
little bit  careful   to avoid  confusion.   u105 is  the stabilizer of
(1,2)(3,4)(5,6)(7,8).  We  know that there is a correspondence  between
the  points  of  the  orbit   and  the  cosets  of   u105.   The  point
(1,2)(3,4)(5,6)(7,8) corresponds  to u105.   To  get  the subgroup of
index 15  we must add to u105 an element of the coset  that corresponds
to the point (1,3)(2,4)(5,7)(6,8)  (or any  other  point in  the  first
block).   That  means that  we must  use  an  element of a8  that  maps
(1,2)(3,4)(5,6)(7,8) to (1,3)(2,4)(5,7)(6,8).  The important thing is
that  (1,3)(2,4)(5,7)(6,8) will not do, in fact  (1,3)(2,4)(5,7)(6,8)
lies in u105.
The  function  RepresentativeOperation  does what we need.  It  takes a
group and  two points and returns an  element  of the group that maps the
first point  to  the  second.  In fact it also allows  you to specify the
operation  as optional fourth argument as usual, but we do  not need this
here.  If no such element exists in the group, i.e., if the two points do
not lie in one orbit  under the group,  RepresentativeOperation returns
false.
    gap> rep := RepresentativeOperation( a8, (1,2)(3,4)(5,6)(7,8),
    >                                         (1,3)(2,4)(5,7)(6,8) );
    (2,3)(6,7)
    gap> u15 := Closure( u105, rep );
    Subgroup( a8, [ (5,6)(7,8), (1,2)(3,4)(5,6)(7,8), (5,7)(6,8),
      (3,4)(7,8), (3,5)(4,6), (1,3)(2,4), (2,3)(6,7) ] )
    gap> Index( a8, u15 );
    15 
u15 is of course a maximal subgroup, because a8  has  no subgroups of
index 3 or 5.
There is in fact another class of subgroups of index 15 above u105 that
we get by adding (2,3)(6,8) to u105.
    gap> u15b := Closure( u105, (2,3)(6,8) );
    Subgroup( a8, [ (5,6)(7,8), (1,2)(3,4)(5,6)(7,8), (5,7)(6,8),
      (3,4)(7,8), (3,5)(4,6), (1,3)(2,4), (2,3)(6,8) ] )
    gap> Index( a8, u15b );
    15 
We now show that u15 and u15b are not conjugate.  We showed that u8
and  u8b  are conjugate by  showing that  the operations on  the cosets
where equivalent.  We could show that u15 and u15b are not  conjugate
by showing  that  the  operations  on their  cosets  are not  equivalent.
Instead we simply call RepresentativeOperation again.
    gap> RepresentativeOperation( a8, u15, u15b );
    false 
RepresentativeOperation tells us that there is no  element g in  a8
such that u15^g = u15b.   Because ^ also  denotes the conjugation
of subgroups this tells us that u15 and u15b are not conjugate.  Note
that this operation should only be used rarely, because it is usually not
very  efficient.  The  test in this case is however reasonable efficient,
and is in fact the one employed by IsConjugate (see IsConjugate).
This  concludes  our  example.   In  this  section  we demonstrated  some
functions  from  the operations  package.   There  is  a  whole class  of
functions that  we  did  not mention, namely  those that  take  a  single
element instead  of a  whole  group  as first argument, e.g., Cycle and
Operations of Groups.
GAP 3.4.4