In this  section  we will show some  easy computations with  groups.  The
example uses permutation groups,  but this  is visible  for the user only
because the output  contains  permutations.  The functions, like Group,
Size   or  SylowSubgroup  (for  detailed  information,  see  chapters
Domains, Groups), are the same for all kinds of groups, although  the
algorithms which  compute the  information of course will be different in
most cases.
It is not even necessary to know more about permutations than the two facts that they are elements of permutation groups and that they are written in disjoint cycle notation (see chapter Permutations). So let's construct a permutation group:
    gap> s8:= Group( (1,2), (1,2,3,4,5,6,7,8) );
    Group( (1,2), (1,2,3,4,5,6,7,8) )
We   formed  the  group  generated  by   the  permutations  (1,2)   and
(1,2,3,4,5,6,7,8),  which is well known as the symmetric group on eight
points,  and  assigned  it  to the  identifier s8.   s8 contains  the
alternating group on eight points which can be described in several ways,
e.g., as group of  all even permutations in  s8,  or  as its commutator
subgroup.
    gap> a8:= CommutatorSubgroup( s8, s8 );
    Subgroup( Group( (1,2), (1,2,3,4,5,6,7,8) ),
    [ (1,3,2), (2,4,3), (2,3)(4,5), (2,4,6,5,3), (2,5,3)(4,7,6),
      (2,3)(5,6,8,7) ] )
The  alternating group a8  is printed as  instruction  to  compute that
subgroup   of  the  group  s8  that  is  generated  by  the  given  six
permutations.   This representation  is  much shorter than  the  internal
structure,  and  it  is  completely  self--explanatory;  one  could,  for
example, print such a group to a file and read it into GAP later.  But
if one object occurs several times it is useful to refer  to this object;
this can be settled by assigning a name to the group.
    gap> s8.name:= "s8";
    "s8"
    gap> a8;
    Subgroup( s8, [ (1,3,2), (2,4,3), (2,3)(4,5), (2,4,6,5,3),
      (2,5,3)(4,7,6), (2,3)(5,6,8,7) ] )
    gap> a8.name:= "a8";
    "a8"
    gap> a8;
    a8
Whenever a group has a component name,  GAP prints this name instead
of the group itself.  Note that there is no link between the name and the
identifier, but  it is  of  course  useful to choose name and  identifier
compatible.
    gap> copya8:= Copy( a8 );
    a8
We examine  the group a8.  Like  all  complex GAP structures,  it is
represented as a record (see Group Records).
    gap> RecFields( a8 );
    [ "isDomain", "isGroup", "parent", "identity", "generators",
      "operations", "isPermGroup", "1", "2", "3", "4", "5", "6",
      "stabChainOptions", "stabChain", "orbit", "transversal",
      "stabilizer", "name" ]
Many functions store information about the group in this group record, this avoids duplicate computations. But we are not interested in the organisation of data but in the group, e.g., some of its properties (see chapter Groups, especially Properties and Property Tests):
    gap> Size( a8 ); IsAbelian( a8 ); IsPerfect( a8 );
    20160
    false
    true
Some interesting subgroups are the Sylow p subgroups for prime divisors
p of the  group order; a call  of  SylowSubgroup stores the  required
subgroup in the group record:
    gap> Set( Factors( Size( a8 ) ) );
    [ 2, 3, 5, 7 ]
    gap> for p in last do
    >      SylowSubgroup( a8, p );
    >    od;
    gap> a8.sylowSubgroups;
    [ , Subgroup( s8, [ (1,5)(7,8), (1,5)(2,6), (3,4)(7,8), (2,3)(4,6),
          (1,7)(2,3)(4,6)(5,8), (1,2)(3,7)(4,8)(5,6) ] ),
      Subgroup( s8, [ (3,8,7), (2,6,4)(3,7,8) ] ),,
      Subgroup( s8, [ (3,7,8,6,4) ] ),,
      Subgroup( s8, [ (2,8,4,5,7,3,6) ] ) ]
The record component  sylowSubgroups  is a  list  which  stores at  the
p--th position, if bound, the Sylow p subgroup; in  this example this
means that there are holes at  positions 1, 4 and 6.  Note that a call of
SylowSubgroup  for the cyclic group of  order 65521  and for  the prime
65521 would cause  GAP to store the group  at  the end  of  a  list of
length  65521, so  there are special situations where  it is possible  to
bring GAP and yourselves into troubles.
We now can investigate the Sylow 2 subgroup.
    gap> syl2:= last[2];;
    gap> Size( syl2 );
    64
    gap> Normalizer( a8, syl2 );
    Subgroup( s8, [ (3,4)(7,8), (2,3)(4,6), (1,2)(3,7)(4,8)(5,6) ] )
    gap> last = syl2;
    true
    gap> Centre( syl2 );
    Subgroup( s8, [ ( 1, 5)( 2, 6)( 3, 4)( 7, 8) ] )
    gap> cent:= Centralizer( a8, last );
    Subgroup( s8, [ ( 1, 5)( 2, 6)( 3, 4)( 7, 8), (3,4)(7,8), (3,7)(4,8),
      (2,3)(4,6), (1,2)(5,6) ] )
    gap> Size( cent );
    192
    gap> DerivedSeries( cent );
    [ Subgroup( s8, [ ( 1, 5)( 2, 6)( 3, 4)( 7, 8), (3,4)(7,8),
          (3,7)(4,8), (2,3)(4,6), (1,2)(5,6) ] ),
      Subgroup( s8, [ ( 1, 6, 3)( 2, 4, 5), ( 1, 8, 3)( 4, 5, 7),
          ( 1, 7)( 2, 3)( 4, 6)( 5, 8), ( 1, 5)( 2, 6) ] ),
      Subgroup( s8, [ ( 1, 3)( 2, 7)( 4, 5)( 6, 8),
          ( 1, 6)( 2, 5)( 3, 8)( 4, 7), ( 1, 5)( 3, 4), ( 1, 5)( 7, 8) ] )
        , Subgroup( s8, [ ( 1, 5)( 2, 6)( 3, 4)( 7, 8) ] ),
      Subgroup( s8, [  ] ) ]
    gap> List( last, Size );
    [ 192, 96, 32, 2, 1 ]
    gap> low:= LowerCentralSeries( cent );
    [ Subgroup( s8, [ ( 1, 5)( 2, 6)( 3, 4)( 7, 8), (3,4)(7,8),
          (3,7)(4,8), (2,3)(4,6), (1,2)(5,6) ] ),
      Subgroup( s8, [ ( 1, 6, 3)( 2, 4, 5), ( 1, 8, 3)( 4, 5, 7),
          ( 1, 7)( 2, 3)( 4, 6)( 5, 8), ( 1, 5)( 2, 6) ] ) ]
Another kind of subgroups is given by the point stabilizers.
    gap> stab:= Stabilizer( a8, 1 );
    Subgroup( s8, [ (2,5,6), (2,5)(3,6), (2,5,6,4,3), (2,5,3)(4,6,8),
      (2,5)(3,4,7,8) ] )
    gap> Size( stab );
    2520
    gap> Index( a8, stab );
    8
We  can  fetch an arbitrary group element and  look at its centralizer in
a8,  and then get  other subgroups by  conjugation  and intersection of
already  known subgroups.  Note that  we form  the subgroups inside a8,
but GAP regards these groups as subgroups  of s8 because this is the
common  ``parent'' group of all these groups and of a8 (for the idea
of parent groups, see More about Groups and Subgroups).
    gap> Random( a8 );
    (1,6,3,2,7)(4,5,8)
    gap> Random( a8 );
    (1,3,2,4,7,5,6)
    gap> cent:= Centralizer( a8, (1,2)(3,4)(5,8)(6,7) );
    Subgroup( s8, [ (1,2)(3,4)(5,8)(6,7), (5,6)(7,8), (5,7)(6,8),
      (3,4)(6,7), (3,5)(4,8), (1,3)(2,4) ] )
    gap> Size( cent );
    192
    gap> conj:= ConjugateSubgroup( cent, (2,3,4) );
    Subgroup( s8, [ (1,3)(2,4)(5,8)(6,7), (5,6)(7,8), (5,7)(6,8),
      (2,4)(6,7), (2,8)(4,5), (1,4)(2,3) ] )
    gap> inter:= Intersection( cent, conj );
    Subgroup( s8, [ (5,6)(7,8), (5,7)(6,8), (1,2)(3,4), (1,3)(2,4) ] )
    gap> Size( inter );
    16
    gap> IsElementaryAbelian( inter );
    true
    gap> norm:= Normalizer( a8, inter );
    Subgroup( s8, [ (6,7,8), (5,6,8), (3,4)(6,8), (2,3)(6,8), (1,2)(6,8),
      (1,5)(2,6,3,7,4,8) ] )
    gap> Size( norm );
    576
Suppose we do  not only  look which funny  things may appear in our group
but  want   to   construct  a  subgroup,  e.g.,  a  group   of  structure
2^3:L_3(2) in a8.   One idea is  to  look for an  appropriate  2^3
which is specified by the fact that all its involutions  are  fixed point
free, and then compute its normalizer in a8:
    gap> elab:= Group( (1,2)(3,4)(5,6)(7,8), (1,3)(2,4)(5,7)(6,8),
    >                  (1,5)(2,6)(3,7)(4,8) );;
    gap> Size( elab );
    8
    gap> IsElementaryAbelian( elab );
    true
    gap> norm:= Normalizer( a8, AsSubgroup( s8, elab ) );
    Subgroup( s8, [ (5,6)(7,8), (5,7)(6,8), (3,4)(7,8), (3,5)(4,6),
      (2,3)(6,7), (1,2)(7,8) ] )
    gap> Size( norm );
    1344
Note that elab  was defined as separate  group, thus  we  had  to  call
AsSubgroup  to  achieve that  it  has  the  same parent  group as a8.
Let's look at some usual misuses:
    Normalizer( a8, elab );
Intuitively,  it is  clear  that here  again  we  wanted  to  compute the
normalizer of elab in a8,  and in fact  we would get it by this call.
However,  this would be a misuse in the sense  that now GAP cannot use
some clever method for the computation of the normalizer.  So, for larger
groups,  the computation  may be very time consuming.  That is the reason
why we used the the function AsSubgroup in the preceding example.
Let's have a closer look at that function.
    gap> IsSubgroup( a8, AsSubgroup( a8, elab ) );
    Error, <G> must be a parent group in
    AsSubgroup( a8, elab ) called from
    main loop
    brk> quit;
    gap> IsSubgroup( a8, AsSubgroup( s8, elab ) );
    true
What we tried here was not correct.  Since all our computations up to now
are  done  inside  s8  which  is the  parent  of  a8,  it is  easy to
understand that IsSubgroup works for two subgroups with this parent.
By the way, you should not try the operator <  instead of the function
IsSubgroup.  Something like
    gap> elab < a8;
    false
or
    gap> AsSubgroup( s8, elab ) < a8;
    false
will not cause an error, but the result does not tell anything  about the
inclusion of one  group in another; < looks at the  element  lists for
the two domains which means that it computes them if they are not already
stored  --which is not desirable to do for large groups-- and then simply
compares  the   lists  with  respect   to  lexicographical   order   (see
Comparisons of Domains).
On  the  other  hand, the  equality operator  =  in  fact does test the
equality of groups.  Thus
    gap> elab = AsSubgroup( s8, elab );
    true
means that the two  groups are equal in the sense that they have the same
elements.   Note  that  they  may  behave  differently  since  they  have
different parent groups.  In our example,  it  is  necessary to work with
subgroups of s8:
    gap> elab:= AsSubgroup( s8, elab );;
    gap> elab.name:= "elab";;
If  we are  given the  subgroup  norm of  order  1344  and its subgroup
elab, the factor group can be considered.
    gap> f:= norm / elab;
    (Subgroup( s8, [ (5,6)(7,8), (5,7)(6,8), (3,4)(7,8), (3,5)(4,6),
      (2,3)(6,7), (1,2)(7,8) ] ) / elab)
    gap> Size( f );
    168
As the output shows, this is not a permutation group. The factor group and its elements can, however, be handled in the usual way.
    gap> Random( f );
    FactorGroupElement( elab, (2,8,7)(3,5,6) )
    gap> Order( f, last );
    3
The natural link between the group norm and its factor group f is the
natural  homomorphism onto f, mapping each element  of  norm  to  its
coset  modulo  the  kernel  elab.   In GAP  you  can  construct  the
homomorphism, but note that the images lie in f since they are elements
of  the  factor group, but the preimage  of each  such  element is only a
coset,  not a  group element (for  cosets,  see  the relevant sections in
chapter  Groups, for homomorphisms  see chapters Operations of Groups
and Mappings).
    gap> f.name:= "f";;
    gap> hom:= NaturalHomomorphism( norm, f );
    NaturalHomomorphism( Subgroup( s8,
    [ (5,6)(7,8), (5,7)(6,8), (3,4)(7,8), (3,5)(4,6), (2,3)(6,7),
      (1,2)(7,8) ] ), (Subgroup( s8,
    [ (5,6)(7,8), (5,7)(6,8), (3,4)(7,8), (3,5)(4,6), (2,3)(6,7),
      (1,2)(7,8) ] ) / elab) )
    gap> Kernel( hom ) = elab;
    true
    gap> x:= Random( norm );
    (1,7,5,8,3,6,2)
    gap> Image( hom, x );
    FactorGroupElement( elab, (2,7,3,4,6,8,5) )
    gap> coset:= PreImages( hom, last );
    (elab*(2,7,3,4,6,8,5))
    gap> IsCoset( coset );
    true
    gap> x in coset;
    true
    gap> coset in f;
    false
The  group f  acts  on  its elements (not  on the  cosets)  via right
multiplication,  yielding the  regular permutation representation of  f
and thus  a new permutation group, namely  the linear  group L_3(2).  A
more elaborate discussion of operations of groups can be found in section
About Operations of Groups and chapter Operations of Groups.
    gap> op:= Operation( f, Elements( f ), OnRight );;
    gap> IsPermGroup( op );
    true
    gap> Maximum( List( op.generators, LargestMovedPointPerm ) );
    168
    gap> IsSimple( op );
    true
norm  acts  on the seven  nontrivial elements  of its  normal  subgroup
elab by  conjugation,  yielding a  representation of L_3(2)  on seven
points.  We embed this permutation group in norm and deduce that norm
is a split extension of an elementary abelian group 2^3 with L_3(2).
    gap> op:= Operation( norm, Elements( elab ), OnPoints );
    Group( (5,6)(7,8), (5,7)(6,8), (3,4)(7,8), (3,5)(4,6), (2,3)(6,7),
    (3,4)(5,6) )
    gap> IsSubgroup(   a8, AsSubgroup( s8, op ) );
    true
    gap> IsSubgroup( norm, AsSubgroup( s8, op ) );
    true
    gap> Intersection( elab, op );
    Group( () )
Yet another kind of  information about our a8  concerns  its  conjugacy
classes.
    gap> ccl:= ConjugacyClasses( a8 );
    [ ConjugacyClass( a8, () ), ConjugacyClass( a8, (1,3)(2,6)(4,7)(5,8) )
        , ConjugacyClass( a8, (1,3)(2,8,5)(6,7) ),
      ConjugacyClass( a8, (2,5,8) ), ConjugacyClass( a8, (1,3)(6,7) ),
      ConjugacyClass( a8, (1,3,2,5,4,7,8) ),
      ConjugacyClass( a8, (1,5,8,2,7,3,4) ),
      ConjugacyClass( a8, (1,5)(2,8,7,4,3,6) ),
      ConjugacyClass( a8, (2,7,3)(4,6,8) ),
      ConjugacyClass( a8, (1,6)(3,8,5,4) ),
      ConjugacyClass( a8, (1,3,5,2)(4,6,8,7) ),
      ConjugacyClass( a8, (1,8,6,2,5) ),
      ConjugacyClass( a8, (1,7,2,4,3)(5,8,6) ),
      ConjugacyClass( a8, (1,2,3,7,4)(5,8,6) ) ]
    gap> Length( ccl );
    14
    gap> reps:= List( ccl, Representative );
    [ (), (1,3)(2,6)(4,7)(5,8), (1,3)(2,8,5)(6,7), (2,5,8), (1,3)(6,7),
      (1,3,2,5,4,7,8), (1,5,8,2,7,3,4), (1,5)(2,8,7,4,3,6),
      (2,7,3)(4,6,8), (1,6)(3,8,5,4), (1,3,5,2)(4,6,8,7), (1,8,6,2,5),
      (1,7,2,4,3)(5,8,6), (1,2,3,7,4)(5,8,6) ]
    gap> List( reps, r -> Order( a8, r ) );
    [ 1, 2, 6, 3, 2, 7, 7, 6, 3, 4, 4, 5, 15, 15 ]
    gap> List( ccl, Size );
    [ 1, 105, 1680, 112, 210, 2880, 2880, 3360, 1120, 2520, 1260, 1344,
      1344, 1344 ]
Note the  difference  between  Order  (which means the  element order),
Size (which means the size of the conjugacy  class) and Length (which
means the length of a list).
Having the conjugacy classes, we can consider class functions, i.e., maps
that  are defined  on the group elements, and  that are constant on  each
conjugacy class.  One nice example is the number of fixed points; here we
use that permutations act on points via ^.
    gap> nrfixedpoints:= function( perm, support )
    > return Number( [ 1 .. support ], x -> x^perm = x );
    > end;
    function ( perm, support ) ... end
Note that we must specify the support  since a permutation does not  know
about the group it is  an element of; e.g.  the trivial permutation  ()
has as many fixed points as the support denotes.
    gap> permchar1:= List( reps, x -> nrfixedpoints( x, 8 ) );
    [ 8, 0, 1, 5, 4, 1, 1, 0, 2, 2, 0, 3, 0, 0 ]
This is the character of  the natural permutation  representation of a8
(More about characters can  be found in chapters Character Tables ff.).
In order to  get  another representation  of a8,  we  consider  another
action, namely that on the elements of a conjugacy  class by conjugation;
note that this is denoted by OnPoints, too.
    gap> class := First( ccl, c -> Size(c) = 112 );
    ConjugacyClass( a8, (2,5,8) )
    gap> op:= Operation( a8, Elements( class ), OnPoints );;
We get a  permutation  representation op  on 112 points.   It  is  more
useful to look for properties than at the permutations.
    gap> IsPrimitive( op, [ 1 .. 112 ] );
    false
    gap> blocks:= Blocks( op, [ 1 .. 112 ] );
    [ [ 1, 2 ], [ 6, 8 ], [ 14, 19 ], [ 17, 20 ], [ 36, 40 ], [ 32, 39 ],
      [ 3, 5 ], [ 4, 7 ], [ 10, 15 ], [ 65, 70 ], [ 60, 69 ], [ 54, 63 ],
      [ 55, 68 ], [ 50, 67 ], [ 13, 16 ], [ 27, 34 ], [ 22, 29 ],
      [ 28, 38 ], [ 24, 37 ], [ 31, 35 ], [ 9, 12 ], [ 106, 112 ],
      [ 100, 111 ], [ 11, 18 ], [ 93, 104 ], [ 23, 33 ], [ 26, 30 ],
      [ 94, 110 ], [ 88, 109 ], [ 49, 62 ], [ 44, 61 ], [ 43, 56 ],
      [ 53, 58 ], [ 48, 57 ], [ 45, 66 ], [ 59, 64 ], [ 87, 103 ],
      [ 81, 102 ], [ 80, 96 ], [ 92, 98 ], [ 47, 52 ], [ 42, 51 ],
      [ 41, 46 ], [ 82, 108 ], [ 99, 105 ], [ 21, 25 ], [ 75, 101 ],
      [ 74, 95 ], [ 86, 97 ], [ 76, 107 ], [ 85, 91 ], [ 73, 89 ],
      [ 72, 83 ], [ 79, 90 ], [ 78, 84 ], [ 71, 77 ] ]
    gap> op2:= Operation( op, blocks, OnSets );;
    gap> IsPrimitive( op2, [ 1 .. 56 ] );
    true
The action of op on the given block system gave us a new representation
on 56 points which is primitive,  i.e., the point stabilizer is a maximal
subgroup.  We compute its preimage in  the representation on eight points
using homomorphisms (which of course are monomorphisms).
    gap> ophom := OperationHomomorphism( a8, op  );;
    gap> Kernel(ophom);
    Subgroup( s8, [  ] )
    gap> ophom2:= OperationHomomorphism( op, op2 );;
    gap> stab:= Stabilizer( op2, 1 );;
    gap> Size( stab );
    360
    gap> composition:= ophom * ophom2;;
    gap> preim:= PreImage( composition, stab );
    Subgroup( s8, [ (1,3,2), (2,4,3), (1,3)(7,8), (2,3)(4,5), (6,8,7) ] )
And this is the permutation character (with respect to the succession  of
conjugacy classes in ccl):
    gap> permchar2:= List( reps, x->nrfixedpoints(x^composition,56) );
    [ 56, 0, 3, 11, 12, 0, 0, 0, 2, 2, 0, 1, 1, 1 ]
The normalizer of an element in the conjugacy class class is a group of
order 360,  too.   In fact,  it is  essentially the  same  as the maximal
    gap> sgp:= Normalizer( a8,
    >                      Subgroup( s8, [ Representative(class) ] ) );
    Subgroup( s8, [ (2,5)(3,4), (1,3,4), (2,5,8), (1,3,7)(2,5,8),
      (1,4,7,3,6)(2,5,8) ] )
    gap> Size( sgp );
    360
    gap> IsConjugate( a8, sgp, preim );
    true
The scalar product  of permutation characters of two subgroups  U, V,
say,  equals the  number of (U,V)--double cosets  (again, see  chapters
Character Tables ff.  for the details).   For example,  the norm of the
permutation character permchar1 of degree eight is two since the action
of  a8  on the  cosets  of  a  point  stabilizer  is  at  least  doubly
transitive:
    gap> stab:= Stabilizer( a8, 1 );;
    gap> double:= DoubleCosets( a8, stab, stab );
    [ DoubleCoset( Subgroup( s8, [ (3,8,7), (3,4)(7,8), (3,5,4,8,7),
          (3,6,5)(4,8,7), (2,6,4,5)(7,8) ] ), (), Subgroup( s8,
        [ (3,8,7), (3,4)(7,8), (3,5,4,8,7), (3,6,5)(4,8,7),
          (2,6,4,5)(7,8) ] ) ),
      DoubleCoset( Subgroup( s8, [ (3,8,7), (3,4)(7,8), (3,5,4,8,7),
          (3,6,5)(4,8,7), (2,6,4,5)(7,8) ] ), (1,2)(7,8), Subgroup( s8,
        [ (3,8,7), (3,4)(7,8), (3,5,4,8,7), (3,6,5)(4,8,7),
          (2,6,4,5)(7,8) ] ) ) ]
    gap> Length( double );
    2
We compute the numbers of ('sgp','sgp') and ('sgp','stab') double cosets.
    gap> Length( DoubleCosets( a8, sgp, sgp ) );
    4
    gap> Length( DoubleCosets( a8, sgp, stab ) );
    2
Thus both irreducible  constituents  of permchar1 are also constituents
of permchar2, i.e., the difference of the two permutation characters is
a proper character of a8 of norm two.
    gap> permchar2 - permchar1;
    [ 48, 0, 2, 6, 8, -1, -1, 0, 0, 0, 0, -2, 1, 1 ]
GAP 3.4.4