#############################################################################
##
#W  xmod_manual.tst               XMOD test file                Chris Wensley
#W                                                                & Murat Alp
##
#H  $Id: xmod_manual.tst,v 2.007 2006/07/05 gap Exp $
##
#Y  Copyright (C) 1999,2001 University of St. Andrews, North Haugh,
#Y                          St. Andrews, Fife KY16 9SS, Scotland
##
#############################################################################

gap> START_TEST( "Testing all example commands in the XMod manual" );

gap> SetInfoLevel( InfoXMod, 0 );;

## Chapter 2,  Section 2.1.3

gap> c5 := Group( (5,6,7,8,9) );;
gap> SetName( c5, "c5" );;
gap> X1 := XModByAutomorphismGroup( c5 );
[c5->PAut(c5)]
gap> Display(X1);

Crossed module [c5->PAut(c5)] :- 
: Source group c5 has generators:
  [ (5,6,7,8,9) ]
: Range group PAut(c5) has generators:
  [ (1,2,4,3) ]
: Boundary homomorphism maps source generators to:
  [ () ]
: Action homomorphism maps range generators to automorphisms:
  (1,2,4,3) --> { source gens --> [ (5,7,9,6,8) ] }
  This automorphism generates the group of automorphisms.

gap> Size(X1);
[ 5, 4 ]

## Section 2.2.1

gap> c := (11,12,13,14,15,16,17,18);;  d := (12,18)(13,17)(14,16);;
gap> d16 := Group( c, d );;
gap> sk4 := Subgroup( d16, [ c^4, d ] );;
gap> SetName( d16, "d16" );  SetName( sk4, "sk4" );
gap> bdy16 := GroupHomomorphismByImages( d16, sk4, [c,d], [c^4*d,d] );;
gap> h1 := GroupHomomorphismByImages( d16, d16, [c,d], [c^5,d] );;
gap> h2 := GroupHomomorphismByImages( d16, d16, [c,d], [c,c^4*d] );;
gap> aut16 := Group( [ h1, h2 ] );;
gap> act16 := GroupHomomorphismByImages( sk4, aut16, [c^4,d], [h1,h2] );;
gap> P16 := PreXModByBoundaryAndAction( bdy16, act16 );
[d16->sk4]

## Section 2.2.2

gap> P := PeifferSubgroup( P16 );
Group([ (11,15)(12,16)(13,17)(14,18), (11,13,15,17)(12,14,16,18) ])
gap> X16 := XModByPeifferQuotient( P16 );
[d16/P->sk4]
gap> Display( X16 );

Crossed module [d16/P->sk4] :-
: Source group has generators:
  [ f1, f2 ]
: Range group has generators:
  [ (11,15)(12,16)(13,17)(14,18), (12,18)(13,17)(14,16) ]
: Boundary homomorphism maps source generators to:
  [ (12,18)(13,17)(14,16), (11,15)(12,14)(16,18) ]
  The automorphism group is trivial

gap> iso16 := IsomorphismPermGroup( Source( X16 ) );;
gap> S16 := Image( iso16 );
Group([ (1,3)(2,4), (1,2)(3,4) ])

## Section 2.3.2

gap> s3 := SymmetricGroup(IsPcGroup,3);;   SetName(s3,"s3");
gap> gens3 := GeneratorsOfGroup(s3);;
gap> pc4 := CyclicGroup(4);;  SetName( pc4, "pc4" );
gap> s3c4 := DirectProduct( s3, pc4 );;  SetName( s3c4, "s3c4" );  
gap> gens3c4 := GeneratorsOfGroup( s3c4 );;
gap> a := gens3[1];;  b := gens3[2];;  one := One(s3);;
gap> t2 := GroupHomomorphismByImages( s3c4, s3, gens3c4, [a,b,one,one] );
[ f1, f2, f3, f4 ] -> [ f1, f2, <identity> of ..., <identity> of ... ]
gap> e2 := Embedding( s3c4, 1 );
Pcgs([ f1, f2 ]) -> [ f1, f2 ]
gap> C2 := Cat1( t2, t2, e2 );;
gap> Display( C2 );

Cat1-group [s3c4=>s3] :- 
: source group has generators:
  [ f1, f2, f3, f4 ]
:  range group has generators:
  [ f1, f2 ]
: tail homomorphism maps source generators to:
  [ f1, f2, <identity> of ..., <identity> of ... ]
: head homomorphism maps source generators to:
  [ f1, f2, <identity> of ..., <identity> of ... ]
: range embedding maps range generators to:
  [ f1, f2 ]
: kernel has generators:
  [ f3, f4 ]
: boundary homomorphism maps generators of kernel to:
  [ <identity> of ..., <identity> of ... ]
: kernel embedding maps generators of kernel to:
  [ f3, f4 ]

gap> IsPcCat1(C2);
true
gap> Size(C2);
[ 24, 6 ]

## Section 2.3.3

gap> SetName( Kernel(t2), "ker(t2)" );
gap> X2 := XModOfCat1( C2 );;
gap> Display( X2 );

Crossed module [ker(t2)->s3] :- 
: Source group has generators:
  [ f3, f4 ]
: Range group s3 has generators:
  [ f1, f2 ]
: Boundary homomorphism maps source generators to:
  [ <identity> of ..., <identity> of ... ]
  The automorphism group is trivial
: associated cat1-group is [s3c4=>s3]

##Section 2.4.1

gap> L18 := Cat1Select( 18 );
#I  Loading cat1-group data into CAT1_LIST
Usage:  Cat1( size, gpnum, num );
[ "d18", "c18", "s3c3", "c3^2|Xc2", "c6c3" ]
gap> L18_4 := Cat1Select( 18, 4 );
There are 4 cat1-structures for the group c3^2|Xc2.
[ [range gens], source & range names, [tail genimages], [head genimages] ] :-
[ [ (1,2,3), (4,5,6), (2,3)(5,6) ],  tail = head = identity mapping ]
[ [ (2,3)(5,6) ], "c3^2", "c2", [ (), (), (2,3)(5,6) ],
  [ (), (), (2,3)(5,6) ] ]
[ [ (4,5,6), (2,3)(5,6) ], "c3", "s3", [ (), (4,5,6), (2,3)(5,6) ],
  [ (), (4,5,6), (2,3)(5,6) ] ]
[ [ (4,5,6), (2,3)(5,6) ], "c3", "s3", [ (4,5,6), (4,5,6), (2,3)(5,6) ],
  [ (), (4,5,6), (2,3)(5,6) ] ]
Usage:  Cat1( size, gpnum, num );
Group has generators [ (1,2,3), (4,5,6), (2,3)(5,6) ]
4
gap> C4 := Cat1Select( 18, 4, 4 );
[c3^2|Xc2=>s3]
gap> Display( C4 );

Cat1-group [c3^2|Xc2=>s3] :- 
: source group has generators:
  [ (1,2,3), (4,5,6), (2,3)(5,6) ]
:  range group has generators:
  [ (4,5,6), (4,5,6), (2,3)(5,6) ]
: tail homomorphism maps source generators to:
  [ (4,5,6), (4,5,6), (2,3)(5,6) ]
: head homomorphism maps source generators to:
  [ (), (4,5,6), (2,3)(5,6) ]
: range embedding maps range generators to:
  [ (4,5,6), (4,5,6), (2,3)(5,6) ]
: kernel has generators:
  [ ( 1, 2, 3)( 4, 6, 5) ]
: boundary homomorphism maps generators of kernel to:
  [ (4,6,5) ]
: kernel embedding maps generators of kernel to:
  [ (1,2,3)(4,6,5) ]

gap> XC4 := XModOfCat1( C4 );
[Group( [ ( 1, 2, 3)( 4, 6, 5) ] )->s3]

## Chapter 3

gap> sigma1 := GroupHomomorphismByImages(c5,c5,[(5,6,7,8,9)],[(5,9,8,7,6)] );;
gap> rho1 := IdentityMapping( Range(X1) );;
gap> mor1 := XModMorphism( X1, X1, sigma1, rho1 );
[[c5->PAut(c5)] => [c5->PAut(c5)]]
gap> Display( mor1 );
Morphism of crossed modules :- 
: Source = [c5->PAut(c5)] with generating sets:
  [ (5,6,7,8,9) ]
  [ (1,2,4,3) ]
: Range = Source
: Source Homomorphism maps source generators to:
  [ (5,9,8,7,6) ]
: Range Homomorphism maps range generators to:
  [ (1,2,4,3) ]
gap> IsAutomorphism2dObject(mor1);
true
gap> Order(mor1);
2

## Section 3.2

gap> iso2 := IsomorphismPermObject( C2 );;
gap> PC2 := Range( iso2 );;
gap> Display( iso2 );
Morphism of cat1-groups :- 
: Source = [s3c4=>s3] with generating sets:
  [ f1, f2, f3, f4 ]
  [ f1, f2 ]
:  Range = P[s3c4=>s3] with generating sets:
  [ ( 5, 9)( 6,10)( 7,11)( 8,12), ( 1, 5, 9)( 2, 6,10)( 3, 7,11)( 4, 8,12), 
  ( 1, 3, 2, 4)( 5, 7, 6, 8)( 9,11,10,12), ( 1, 2)( 3, 4)( 5, 6)( 7, 8)( 9,10)
    (11,12) ]
  [ (2,3), (1,2,3) ]
: Source Homomorphism maps source generators to:
  [ ( 5, 9)( 6,10)( 7,11)( 8,12), ( 1, 5, 9)( 2, 6,10)( 3, 7,11)( 4, 8,12), 
  ( 1, 3, 2, 4)( 5, 7, 6, 8)( 9,11,10,12), ( 1, 2)( 3, 4)( 5, 6)( 7, 8)( 9,10)
    (11,12) ]
: Range Homomorphism maps range generators to:
  [ (2,3), (1,2,3) ]

## Section 3.3

gap> GeneratorsOfGroup( d16 );
[ (11,12,13,14,15,16,17,18), (12,18)(13,17)(14,16) ]
gap> d8 := Subgroup( d16, [ c^2, d ] );;
gap> c4 := Subgroup( d8, [ c^2 ] );;
gap> SetName( d8, "d8" );  SetName( c4, "c4" );
gap> X16 := XModByNormalSubgroup( d16, d8 );
[d8->d16]
gap> X8 := SubXMod( X16, c4, d8 );
[c4->d8]
gap> IsSubXMod( X16, X8 );
true
gap> inc8 := InclusionMorphism2dObjects( X16, X8 );
[[c4->d8] => [d8->d16]]
gap> rho := GroupHomomorphismByImages( d16, d16, [c,d], [c,d^(c^2)] );;
gap> sigma := GroupHomomorphismByImages( d8, d8, [c^2,d], [c^2,d^(c^2)] );;
gap> mor := XModMorphismByHoms( X16, X16, sigma, rho );
[[d8->d16] => [d8->d16]]
gap> comp := inc8 * mor;
[[c4->d8] => [d8->d16]]
gap> comp = CompositionMorphism(mor,inc8);
true
gap> c2 := Group( (19,20) );;
gap> i2 := Subgroup( c2, [()] );;
gap> X9 := XModByNormalSubgroup( c2, i2 );;
gap> sigma9 := GroupHomomorphismByImages( c4, i2, [c^2], [()] );;
gap> rho9 := GroupHomomorphismByImages( d8, c2, [c^2,d], [(),(19,20)] );;
gap> mor9 := XModMorphism( X8, X9, sigma9, rho9 );
[[c4->d8] => [..]]
gap> K9 := Kernel( mor9 );
[Group( [ (11,13,15,17)(12,14,16,18) ] )->Group( [ (11,13,15,17)(12,14,16,18)
 ] )]


## Chapter 4

gap> g18 := Group( (1,2,3), (4,5,6), (2,3)(5,6) );;
gap> SetName( g18, "g18" );
gap> gen18 := GeneratorsOfGroup( g18 );;
gap> g1 := gen18[1];;  g2 := gen18[2];;  g3 := gen18[3];;
gap> s3 := Subgroup( g18, gen18{[2..3]} );;
gap> SetName( s3, "s3" );
gap> t := GroupHomomorphismByImages( g18, s3, gen18, [g2,g2,g3] );;
gap> h := GroupHomomorphismByImages( g18, s3, gen18, [(),g2,g3] );;
gap> e := GroupHomomorphismByImages( s3, g18, [g2,g3], [g2,g3] );;
gap> C3 := Cat1( t, h, e );
[g18=>s3]
gap> SetName( Kernel(t), "c3" );
gap> X3 := XModOfCat1( C3 );;
gap> Display( X3 );

Crossed module [c3->s3] :- 
: Source group has generators:
  [ ( 1, 2, 3)( 4, 6, 5) ]
: Range group has generators:
  [ (4,5,6), (2,3)(5,6) ]
: Boundary homomorphism maps source generators to:
  [ (4,6,5) ]
: Action homomorphism maps range generators to automorphisms:
  (4,5,6) --> { source gens --> [ (1,2,3)(4,6,5) ] }
  (2,3)(5,6) --> { source gens --> [ (1,3,2)(4,5,6) ] }
  These 2 automorphisms generate the group of automorphisms.
: associated cat1-group is [g18=>s3]

gap> imchi := [ (1,2,3)(4,6,5), (1,2,3)(4,6,5) ];;
gap> chi := DerivationByImages( X3, imchi );
DerivationByImages( s3, c3, [ (4,5,6), (2,3)(5,6) ], 
[ (1,2,3)(4,6,5), (1,2,3)(4,6,5) ] )
gap> xi := SectionByDerivation( chi );
[ (4,5,6), (2,3)(5,6) ] -> [ (1,2,3), (1,2)(4,6) ]

## Section 4.2

gap> all3 := AllDerivations( X3 );;
gap> imall3 := ImagesList( all3 );; 
gap> Display( imall3 );
[ [ (), () ],
  [ (), ( 1, 2, 3)( 4, 6, 5) ],
  [ (), ( 1, 3, 2)( 4, 5, 6) ],
  [ ( 1, 2, 3)( 4, 6, 5), () ],
  [ ( 1, 2, 3)( 4, 6, 5), ( 1, 2, 3)( 4, 6, 5) ],
  [ ( 1, 2, 3)( 4, 6, 5), ( 1, 3, 2)( 4, 5, 6) ],
  [ ( 1, 3, 2)( 4, 5, 6), () ],
  [ ( 1, 3, 2)( 4, 5, 6), ( 1, 2, 3)( 4, 6, 5) ],
  [ ( 1, 3, 2)( 4, 5, 6), ( 1, 3, 2)( 4, 5, 6) ]
  ]
gap> Display( ImagesTable( all3 ) );
[ [  1,  1,  1,  1,  1,  1 ],
  [  1,  1,  1,  2,  2,  2 ],
  [  1,  1,  1,  3,  3,  3 ],
  [  1,  2,  3,  1,  2,  3 ],
  [  1,  2,  3,  2,  3,  1 ],
  [  1,  2,  3,  3,  1,  2 ],
  [  1,  3,  2,  1,  3,  2 ],
  [  1,  3,  2,  2,  1,  3 ],
  [  1,  3,  2,  3,  2,  1 ] ]
gap> reg3 := RegularDerivations( X3 );;
gap> imder3 := ImagesList( reg3 );;
gap> chi4 := DerivationByImages( X3, imder3[4] );
DerivationByImages( s3, c3, [ (4,5,6), (2,3)(5,6) ], 
[ ( 1, 3, 2)( 4, 5, 6), () ] )
gap> chi5 := DerivationByImages( X3, imder3[5] );
DerivationByImages( s3, c3, [ (4,5,6), (2,3)(5,6) ], 
[ ( 1, 3, 2)( 4, 5, 6), ( 1, 2, 3)( 4, 6, 5) ] )
gap> im4 := ImagePositions( chi4 );
[ 1, 3, 2, 1, 3, 2 ]
gap> im5 := ImagePositions( chi5 );
[ 1, 3, 2, 2, 1, 3 ]
gap> chi45 := chi4 * chi5;
DerivationByImages( s3, c3, [ (4,5,6), (2,3)(5,6) ], 
[ (), ( 1, 2, 3)( 4, 6, 5) ] )
gap> im45 := ImagePositions( chi45 );
[ 1, 1, 1, 2, 2, 2 ]
gap> pos := Position( imder3, GeneratorImages( chi45 ) );
2
gap> wgt3 := WhiteheadGroupTable( X3 );; 
gap> Display( wgt3 );
[ [  1,  2,  3,  4,  5,  6 ],
  [  2,  3,  1,  5,  6,  4 ],
  [  3,  1,  2,  6,  4,  5 ],
  [  4,  6,  5,  1,  3,  2 ],
  [  5,  4,  6,  2,  1,  3 ],
  [  6,  5,  4,  3,  2,  1 ] ]
gap> wpg3 := WhiteheadPermGroup( X3 );
Group([ (1,2,3)(4,5,6), (1,4)(2,6)(3,5) ])
gap> wmt3 := WhiteheadMonoidTable( X3 );; 
gap> Display( wmt3 );
[ [  1,  2,  3,  4,  5,  6,  7,  8,  9 ],
  [  2,  3,  1,  5,  6,  4,  8,  9,  7 ],
  [  3,  1,  2,  6,  4,  5,  9,  7,  8 ],
  [  4,  4,  4,  4,  4,  4,  4,  4,  4 ],
  [  5,  5,  5,  5,  5,  5,  5,  5,  5 ],
  [  6,  6,  6,  6,  6,  6,  6,  6,  6 ],
  [  7,  9,  8,  4,  6,  5,  1,  3,  2 ],
  [  8,  7,  9,  5,  4,  6,  2,  1,  3 ],
  [  9,  8,  7,  6,  5,  4,  3,  2,  1 ] ]
gap> wtm3 := WhiteheadTransMonoid( X3 );
<monoid with 9 generators>

## Chapter 5

gap> WGX3 := WhiteheadPermGroup( X3 );
Group([ (1,2,3)(4,5,6), (1,4)(2,6)(3,5) ])
gap> APX3 := AutomorphismPermGroup( X3 );
Group([ (3,4,5), (1,2)(4,5) ])
gap> WX3 := WhiteheadXMod( X3 );; 
gap> Display( WX3 );

Crossed module Whitehead[c3->s3] :- 
: Source group has generators:
  [ ( 1, 2, 3)( 4, 6, 5) ]
: Range group has generators:
  [ (1,2,3)(4,5,6), (1,4)(2,6)(3,5) ]
: Boundary homomorphism maps source generators to:
  [ (1,3,2)(4,6,5) ]
: Action homomorphism maps range generators to automorphisms:
  (1,2,3)(4,5,6) --> { source gens --> [ (1,2,3)(4,6,5) ] }
  (1,4)(2,6)(3,5) --> { source gens --> [ (1,3,2)(4,5,6) ] }
  These 2 automorphisms generate the group of automorphisms.

gap> LX3 := LueXMod( X3 );;
gap> Display( LX3 );

Crossed module Lue[c3->s3] :- 
: Source group has generators:
  [ ( 1, 2, 3)( 4, 6, 5) ]
: Range group has generators:
  [ (3,4,5), (1,2)(4,5) ]
: Boundary homomorphism maps source generators to:
  [ (3,4,5) ]
: Action homomorphism maps range generators to automorphisms:
  (3,4,5) --> { source gens --> [ (1,2,3)(4,6,5) ] }
  (1,2)(4,5) --> { source gens --> [ (1,3,2)(4,5,6) ] }
  These 2 automorphisms generate the group of automorphisms.

gap> NX3 := NorrieXMod( X3 );; 
gap> Display( NX3 );

Crossed module Norrie[c3->s3] :- 
: Source group has generators:
  [ (4,5,6), (2,3)(5,6) ]
: Range group has generators:
  [ (3,4,5), (1,2)(4,5) ]
: Boundary homomorphism maps source generators to:
  [ (3,5,4), (1,2)(4,5) ]
: Action homomorphism maps range generators to automorphisms:
  (3,4,5) --> { source gens --> [ (4,5,6), (2,3)(4,5) ] }
  (1,2)(4,5) --> { source gens --> [ (4,6,5), (2,3)(5,6) ] }
  These 2 automorphisms generate the group of automorphisms.

gap> AX3 := ActorXMod( X3 );; 
gap> Display( AX3);

Crossed module Actor[c3->s3] :- 
: Source group has generators:
  [ (1,2,3)(4,5,6), (1,4)(2,6)(3,5) ]
: Range group has generators:
  [ (3,4,5), (1,2)(4,5) ]
: Boundary homomorphism maps source generators to:
  [ (3,5,4), (1,2)(4,5) ]
: Action homomorphism maps range generators to automorphisms:
  (3,4,5) --> { source gens --> [ (1,2,3)(4,5,6), (1,5)(2,4)(3,6) ] }
  (1,2)(4,5) --> { source gens --> [ (1,3,2)(4,6,5), (1,4)(2,6)(3,5) ] }
  These 2 automorphisms generate the group of automorphisms.

gap> IAX3 := InnerActorXMod( X3 );;  
gap> Display( IAX3 );

Crossed module InnerActor[c3->s3] :- 
: Source group has generators:
  [ (1,3,2)(4,6,5) ]
: Range group has generators:
  [ (3,5,4), (1,2)(4,5) ]
: Boundary homomorphism maps source generators to:
  [ (3,4,5) ]
: Action homomorphism maps range generators to automorphisms:
  (3,5,4) --> { source gens --> [ (1,3,2)(4,6,5) ] }
  (1,2)(4,5) --> { source gens --> [ (1,2,3)(4,5,6) ] }
  These 2 automorphisms generate the group of automorphisms.

gap> IMX3 := InnerMorphism( X3 );; 
gap> Display( IMX3 );
Morphism of crossed modules :-
: Source = [c3->s3] with generating sets:
  [ ( 1, 2, 3)( 4, 6, 5) ]
  [ (4,5,6), (2,3)(5,6) ]
:  Range = Actor[c3->s3] with generating sets:
  [ (1,2,3)(4,5,6), (1,4)(2,6)(3,5) ]
  [ (3,4,5), (1,2)(4,5) ]
: Source Homomorphism maps source generators to:
  [ (1,3,2)(4,6,5) ]
: Range Homomorphism maps range generators to:
  [ (3,5,4), (1,2)(4,5) ]
gap> IsInjective( IMX3 );
true
gap> ZX3 := Centre( X3 );;
gap> ZX3;
[Group( () )->Group( () )]

## Chapter 6

gap> s4gens := [ (1,2), (2,3), (3,4) ];;
gap> s4 := Group( s4gens );; SetName(s4,"s4");
gap> a4gens := [ (1,2,3), (2,3,4) ];;
gap> a4 := Subgroup( s4, a4gens );;  SetName( a4, "a4" );
gap> s3 := Group( (5,6),(6,7) );;  SetName( s3, "s3" );
gap> epi := GroupHomomorphismByImages( s4, s3, s4gens, [(5,6),(6,7),(5,6)] );;
gap> X4 := XModByNormalSubgroup( s4, a4 );;
gap> indX4 := SurjectiveInducedXMod( X4, epi );
[a4/ker->s3]
gap> Display( indX4 );

Crossed module [a4/ker->s3] :- 
: Source group a4/ker has generators:
  [ (1,3,2), (1,2,3) ]
: Range group s3 has generators:
  [ (5,6), (6,7) ]
: Boundary homomorphism maps source generators to:
  [ (5,6,7), (5,7,6) ]
: Action homomorphism maps range generators to automorphisms:
  (5,6) --> { source gens --> [ (1,2,3), (1,3,2) ] }
  (6,7) --> { source gens --> [ (1,2,3), (1,3,2) ] }
  These 2 automorphisms generate the group of automorphisms.

gap> morX4 := MorphismOfInducedXMod( indX4 );
[[a4->s4] => [a4/ker->s3]]
gap> incd8 := RangeHom( inc8 );;
gap> [ Source(incd8), Range(incd8), IsInjective(incd8) ];
[ d8, d16, true ]
gap> indX8 := InducedXMod( X8, incd8 );
#I Simplified presentation for induced group :-
<presentation with 2 gens and 3 rels of total length 12>
#I  generators: [ f11, f14 ]
#I  relators:
#I  1.  4  [ 1, 1, 1, 1 ]
#I  2.  4  [ 2, 2, 2, 2 ]
#I  3.  4  [ 2, -1, -2, 1 ]
#I induced group has Size: 16
#I factor 1 is abelian  with invariants: [ 4, 4 ]
i*([c4->d8])
gap> Display( indX8 );

Crossed module i*([c4->d8]) :- 
: Source group has generators:
  [ ( 1, 2, 6, 3)( 4, 7,12, 9)( 5, 8,13,10)(11,14,16,15), 
  ( 1, 4,11, 5)( 2, 7,14, 8)( 3, 9,15,10)( 6,12,16,13) ]
: Range group d16 has generators:
  [ (11,12,13,14,15,16,17,18), (12,18)(13,17)(14,16) ]
: Boundary homomorphism maps source generators to:
  [ (11,13,15,17)(12,14,16,18), (11,17,15,13)(12,18,16,14) ]
: Action homomorphism maps range generators to automorphisms:
  (11,12,13,14,15,16,17,18) --> { source gens --> 
[ ( 1, 5,11, 4)( 2, 8,14, 7)( 3,10,15, 9)( 6,13,16,12), 
  ( 1, 3, 6, 2)( 4, 9,12, 7)( 5,10,13, 8)(11,15,16,14) ] }
  (12,18)(13,17)(14,16) --> { source gens --> 
[ ( 1, 3, 6, 2)( 4, 9,12, 7)( 5,10,13, 8)(11,15,16,14), 
  ( 1, 5,11, 4)( 2, 8,14, 7)( 3,10,15, 9)( 6,13,16,12) ] }
  These 2 automorphisms generate the group of automorphisms.

gap> morX8 := MorphismOfInducedXMod( indX8 );
[[c4->d8] => i*([c4->d8])]
gap> Display( morX8 );
Morphism of crossed modules :-
: Source = [c4->d8] with generating sets:
  [ (11,13,15,17)(12,14,16,18) ]
  [ (11,13,15,17)(12,14,16,18), (12,18)(13,17)(14,16) ]
:  Range = i*([c4->d8]) with generating sets:
  [ ( 1, 2, 6, 3)( 4, 7,12, 9)( 5, 8,13,10)(11,14,16,15),
  ( 1, 4,11, 5)( 2, 7,14, 8)( 3, 9,15,10)( 6,12,16,13) ]
  [ (11,12,13,14,15,16,17,18), (12,18)(13,17)(14,16) ]
: Source Homomorphism maps source generators to:
  [ ( 1, 2, 6, 3)( 4, 7,12, 9)( 5, 8,13,10)(11,14,16,15) ]
: Range Homomorphism maps range generators to:
  [ (11,13,15,17)(12,14,16,18), (12,18)(13,17)(14,16) ]
gap> s3b := Subgroup( s4, [ (2,3), (3,4) ] );;  SetName( s3b, "s3b" );
gap> indX3 := InducedXMod( s4, s3b, s3b );
#I Simplified presentation for induced group :-
<presentation with 2 gens and 4 rels of total length 33>
#I  generators: [ f11, f112 ]
#I  relators:
#I  1.  2  [ 1, 1 ]
#I  2.  3  [ 2, 2, 2 ]
#I  3.  12  [ 1, -2, 1, 2, 1, 2, 1, -2, 1, 2, 1, 2 ]
#I  4.  16  [ -2, 1, -2, 1, -2, 1, -2, 1, -2, 1, -2, 1, -2, 1, -2, 1 ]
#I induced group has Size: 48
#I IdGroup = [ [  48,  29 ] ]
i*([s3b->s3b])

## Chapter 7

gap> c := (11,12,13,14,15,16);;
gap> d := (12,16)(13,15);;
gap> cd := c*d;;
gap> d12 := Group( [ c, d ] );;
gap> s3a := Subgroup( d12, [ c^2, d ] );;
gap> s3b := Subgroup( d12, [ c^2, cd ] );;
gap> c3 := Subgroup( d12, [ c^2 ] );;
gap> SetName( d12, "d12");  SetName( s3a, "s3a" );
gap> SetName( s3b, "s3b" );  SetName( c3, "c3" );
gap> XSconj := XSqByNormalSubgroups( d12, s3b, s3a, c3 );
[  c3 -> s3b ]
[  |      |  ]
[ s3a -> d12 ]
gap> Name( XSconj );
"[c3->s3b,s3a->d12]"
gap> XStrans := Transpose3dObject( XSconj );
[  c3 -> s3a ]
[  |      |  ]
[ s3b -> d12 ]
gap> X12 := XModByNormalSubgroup( d12, s3a );
[s3a->d12]
gap> XSact := ActorXSq( X12 );
crossed square with:
      up = Whitehead[s3a->d12]
    left = [s3a->d12]
   right = Actor[s3a->d12]
    down = Norrie[s3a->d12]

## Section 7.1.3

gap> Up2dObject( XSconj );
[c3->s3b]
gap> Right2dObject( XSact );
Actor[s3a->d12]
gap> xpconj := XPair( XSconj );;
gap> ImageElmXPair( xpconj, [ (1,6)(2,5)(3,4), (2,6)(3,5) ] );
(1,3,5)(2,4,6)
gap> diag := DiagonalAction( XSact );
[ (2,3)(6,8)(7,9), (1,2)(4,6)(5,7) ] ->
[ [ (11,13,15)(12,14,16), (12,16)(13,15) ] ->
    [ (11,15,13)(12,16,14), (12,16)(13,15) ],
  [ (11,13,15)(12,14,16), (12,16)(13,15) ] ->
    [ (11,15,13)(12,16,14), (11,13)(14,16) ] ]

## Section 7.2.2

gap> ad12 := GroupHomomorphismByImages( d12, d12, [c,d], [c,d^c] );;
gap> as3a := GroupHomomorphismByImages( s3a, s3a, [c^2,d], [c^2,d^c] );;
gap> as3b := GroupHomomorphismByImages( s3b, s3b, [c^2,cd], [c^2,cd^c] );;
gap> idc3 := IdentityMapping( c3 );;
gap> upconj := Up2dObject( XSconj );;
gap> leftconj := Left2dObject( XSconj );; 
gap> downconj := Down2dObject( XSconj );; 
gap> rightconj := Right2dObject( XSconj );; 
gap> up := XModMorphismByHoms( upconj, upconj, idc3, as3b );
[[c3->s3b] => [c3->s3b]]
gap> left := XModMorphismByHoms( leftconj, leftconj, idc3, as3a );
[[c3->s3a] => [c3->s3a]]
gap> down := XModMorphismByHoms( downconj, downconj, as3a, ad12 );
[[s3a->d12] => [s3a->d12]]
gap> right := XModMorphismByHoms( rightconj, rightconj, as3b, ad12 );
[[s3b->d12] => [s3b->d12]]
gap> autoconj := XSqMorphism( XSconj, XSconj, up, left, down, right );; 
gap> ord := Order( autoconj );;
gap> Display( autoconj );
Morphism of crossed squares :-
:    Source = [c3->s3b,s3a->d12]
:     Range = [c3->s3b,s3a->d12]
:     order = 3
:    up-left: [ [ (11,13,15)(12,14,16) ], [ (11,13,15)(12,14,16) ] ]
:   up-right: [ [ (11,13,15)(12,14,16), (11,16)(12,15)(13,14) ],
  [ (11,13,15)(12,14,16), (11,12)(13,16)(14,15) ] ]
:  down-left: [ [ (11,13,15)(12,14,16), (12,16)(13,15) ],
  [ (11,13,15)(12,14,16), (11,13)(14,16) ] ]
: down-right: [ [ (11,12,13,14,15,16), (12,16)(13,15) ],
  [ (11,12,13,14,15,16), (11,13)(14,16) ] ]
gap> KnownPropertiesOfObject( autoconj );
[ "IsTotal", "IsSingleValued", "IsInjective", "IsSurjective", "Is3dMapping",
  "IsPreXSqMorphism", "IsXSqMorphism", "IsEndomorphism3dObject" ]
gap> IsAutomorphism3dObject( autoconj );
true


## Chapter 8

gap> incd8;
[ (11,13,15,17)(12,14,16,18), (12,18)(13,17)(14,16) ] ->
[ (11,13,15,17)(12,14,16,18), (12,18)(13,17)(14,16) ] 
gap> imd8 := Image( incd8 );;
gap> resd8 := RestrictionMappingGroups( incd8, c4, imd8 );
[ (11,13,15,17)(12,14,16,18) ] -> [ (11,13,15,17)(12,14,16,18) ]
gap> Source( resd8 );
c4
gap> Range( resd8 );
Group([ (11,13,15,17)(12,14,16,18), (12,18)(13,17)(14,16) ])
gap> MappingToOne( c4, imd8 );
[ (11,13,15,17)(12,14,16,18) ] -> [ () ]

## Section 8.2

gap> end8 := EndomorphismClasses( d8, 1 );;
gap> Length( end8 );
13
gap> e4 := end8[4];
<enumerator>
gap> EndoClassNaturalHom( e4 );
[ (11,13,15,17)(12,14,16,18), (12,18)(13,17)(14,16) ] -> [ f1, f1 ]
gap> EndoClassIsomorphism( e4 );
[ f1 ] -> [ (11,15)(12,16)(13,17)(14,18) ]
gap> EndoClassConjugators( e4 );
[ () ]
gap> AutoGroup( e4 );
<group with 1 generators>
gap> L := List( end8, e->Length(EndoClassConjugators(e))*Size(AutoGroup(e)) );
[ 8, 6, 6, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1 ]
gap> Sum(L);
36
gap> autd8 := AutomorphismGroup( d8 );;
gap> innd8 := InnerAutomorphismsByNormalSubgroup( d8, d8 );;
gap> GeneratorsOfGroup( innd8 );
[ ^(11,13,15,17)(12,14,16,18), ^(12,18)(13,17)(14,16) ]
gap> IsGroupOfAutomorphisms( innd8 );
true

## Section 8.3

gap> x := (6,7)(8,9);;  y := (6,8)(7,9);;  z := (6,9)(7,8);;
gap> k4 := Group( x, y );;  SetName( k4, "k4" );
gap> s3 := Group( (1,2), (2,3) );;  SetName( s3, "s3" );
gap> alpha := GroupHomomorphismByImages( k4, k4, [x,y], [y,x] );;
gap> beta := GroupHomomorphismByImages( k4, k4, [x,y], [x,z] );;
gap> aut := Group( alpha, beta );;
gap> act := GroupHomomorphismByImages( s3, aut, [(1,2),(2,3)], [alpha,beta] );;
gap> abmod := AbelianModuleObject( k4, act );;
gap> Xabmod := XModByAbelianModule( abmod );
[k4->s3]
gap> Display( Xabmod );

Crossed module [k4->s3] :- 
: Source group k4 has generators:
  [ (6,7)(8,9), (6,8)(7,9) ]
: Range group s3 has generators:
  [ (1,2), (2,3) ]
: Boundary homomorphism maps source generators to:
  [ (), () ]
: Action homomorphism maps range generators to automorphisms:
  (1,2) --> { source gens --> [ (6,8)(7,9), (6,7)(8,9) ] }
  (2,3) --> { source gens --> [ (6,7)(8,9), (6,9)(7,8) ] }
  These 2 automorphisms generate the group of automorphisms.

## Section 8.4

gap> J := [ [1,2,3], [3,4], [3,4], [1,2,4] ];
[ [ 1, 2, 3 ], [ 3, 4 ], [ 3, 4 ], [ 1, 2, 4 ] ]
gap> DistinctRepresentatives( J );
[ 1, 3, 4, 2 ]
gap> K := [ [3,4], [1,2], [2,3], [2,3,4] ];
[ [ 3, 4 ], [ 1, 2 ], [ 2, 3 ], [ 2, 3, 4 ] ]
gap> CommonRepresentatives( J, K );
[ [ 3, 3, 3, 1 ], [ 1, 3, 4, 2 ] ]
gap> CommonTransversal( d16, c4 );
[ (), (12,18)(13,17)(14,16), (11,12,13,14,15,16,17,18), 
  (11,12)(13,18)(14,17)(15,16) ]
gap> autd8 := AutomorphismGroup( d8 );;
gap> innd8 := InnerAutomorphismsByNormalSubgroup( d8, d8 );;
gap> GeneratorsOfGroup( innd8 );
[ ^(11,13,15,17)(12,14,16,18), ^(12,18)(13,17)(14,16) ]
gap> IsGroupOfAutomorphisms( innd8 );
true

gap> STOP_TEST( "xmod_manual.tst", 1000000 );

#############################################################################
##
#E  xmod_manual.tst . . . . . . . . . . . . . . . . . . . . . . . . ends here
