##############################################################################
##
#W  gpd_manual.g                  Gpd Package                    Chris Wensley
#W                                                                & Emma Moore
##
#H  @(#)$Id: gpd_manual.g,v 1.01 2006/05/17 gap Exp $
##
#Y  Copyright (C) 1999,2001 University of St. Andrews, North Haugh,
#Y                          St. Andrews, Fife KY16 9SS, Scotland
##
Revision.("gpd/examples/gpd_manual.g") :=
   "@(#)$Id: gpd_manual.g,v 1.01 2006/05/17 gap Exp $";

### Chapter 2 : Groupoids

Print( "\nSubSection 2.1.1\n" );
d8 := Group( (1,2,3,4), (1,3) );;
SetName( d8, "d8" );
Gd8 := ConnectedGroupoid( [-9,-8,-7], d8 );
Print( Gd8, "\n" );

c6 := Group( (5,6,7)(8,9) );;
SetName( c6, "c6" );
Gc6 := GroupAsGroupoid( -6, c6 );
Print( Gc6, "\n" );
Gd8c6 := GroupoidByUnion( [ Gd8, Gc6 ] );
Display( Gd8c6 );
SetName( Gd8, "Gd8" );
SetName( Gc6, "Gc6" );
SetName( Gd8c6, "Gd8+Gc6" );
Print( "\n" );

Print( "SubSection 2.1.2\n" );
Print( ComponentsOfGroupoid( Gd8c6 ), "\n" );
Print( ObjectsOfGroupoid( Gd8c6 ), "\n\n" );

Print( "SubSection 2.1.4\n" );
f2 := FreeGroup( 2 );
SetName( f2, "f2" );
Gf2 := Groupoid( -22, f2 );
q8 := SmallGroup( 8, 4 );
SetName( q8, "q8" );
Gq8 := Groupoid( [ -28, -27 ], q8 );
SetName( Gq8, "Gq8" );
Gq8f2 := Groupoid( [ Gf2, Gq8 ] );
[ IsFpGroupoid(Gf2), IsPcGroupoid(Gq8), IsPcGroupoid(Gq8f2) ];
G4 := Groupoid( [ Gd8c6, Gf2, Gq8 ] );
Print( "groupoid G4:\n" );
Display( G4 );
G5 := Groupoid( [ Gq8, Gf2, Gd8c6 ] );
Print( "G4 = G5 ?  ", G4=G5, "\n\n" );

Print( "SubSection 2.1.5\n" );
Print( "elements e1, e2, prod, cycle, cycle^2, Order(cycle):\n" );
e1 := GroupoidElement( Gd8, (1,2)(3,4), -9, -8 );
Print( e1, "\n" );
e2 := GroupoidElement( Gd8, (1,3), -8, -7 );
Print( [ GroupElement( e2 ), Tail( e2 ), Head( e2 ) ], "\n" );
prod := e1*e2;
Print( prod, "\n" );
e3 := GroupoidElement( Gd8, (1,3)(2,4), -7, -9 );
cycle := prod*e3;
Print( cycle, "\n", cycle^2, "\n", Order(cycle), "\n" );
Print( cycle^e1, "\n" );
Print( [ Size( Gd8 ), Size( Gc6 ), Size( Gd8c6 ), Size( Gq8f2 ) ], "\n\n" );


### Section 2.2 : Subgroupoids ###

Print( "SubSection 2.2.1\n" );
c4d := Subgroup( d8, [ (1,2,3,4) ] );;
k4d := Subgroup( d8, [ (1,2)(3,4), (1,3)(2,4) ] );;
SetName( c4d, "c4d" );  SetName( k4d, "k4d" );
Ud8 := Subgroupoid( Gd8, [ [[-9], k4d], [[-8,-7], c4d] ] );;
SetName( Ud8, "Ud8" );
Print( "subgroupoid Ud8 of Gd8:\n" );
Display( Ud8 );
Print( "full subgroupoid of Gd8 on [-7,-6]:\n" );
Print( FullSubgroupoid( Gd8c6, [-7,-6] ), "\n" );
Print( "discrete subgroupoid of Gd8 on [-9,-8] with groups [c4d,k4d]:\n" );
Print( DiscreteSubgroupoid( Gd8c6, [-9,-8], [ c4d, k4d ] ), "\n" );
Print( "full identity subgroupoid of Ud8:\n" );
Print( FullIdentitySubgroupoid( Ud8 ), "\n\n" );

### Section 2.3 : Operations on Groupoid Elements ###

Print( "SubSection 2.3.1\n" );
star9 := ObjectStar( Gd8, -9 );
Print( "elements in ", star9, " with group element of order 4:\n" );
for e in star9 do
    if ( Order( e![1] ) = 4 ) then Print( e, "\n" ); fi;
od;
costar6 := ObjectCostar( Gc6, -6 );
Print( "elements in ", costar6, " with group element of order 6:\n" );
for e in costar6 do
    if ( Order( e![1] ) = 6 ) then Print( e, "\n" ); fi;
od;
hset78 := Homset( Ud8, -7, -8 );
Print( hset78, " has elements:\n" );
for e in hset78 do  Print( e, "\n" );  od;
i7 := IdentityElement( Gd8, -7 );;
i8 := IdentityElement( Gd8, -8 );
L := [ i7, i8 ];
for e in hset78 do  Add( L, i7*e*i8 = e );  od;
Print( "L = ", L, "\n\n" );

### Section 2.4 : Left, Right and Double Cosets ###

Print( "SubSection 2.4.1\n" );
re2 := RightCoset( Gd8, Ud8, e2 );
Print( "elements of right coset of Ud8 by ", e2, "\n" );
for x in re2 do Print( x, "\n" ); od;
rcrd8 := RightCosetRepresentatives( Gd8, Ud8 );
Print( "right coset reps for Ud8 in Gd8:\n", rcrd8, "\n");
lcr7 := LeftCosetRepresentativesFromObject( Gd8, Ud8, -7 );
Print( "left coset reps for Ud8 in Gd8 with tail -7 :-\n", lcr7, "\n\n");

###########################################################################
## Chapter 3 : Morphisms

###  Section 3.1

Print( "SubSection 3.1.1\n" );
d12 := Group( (15,16,17,18,19,20), (15,20)(16,19)(17,18) );;
Gd12 := ConnectedGroupoid( [-37,-36,-35,-34], d12 );;
SetName( d12, "d12" );  
SetName( Gd12, "Gd12" );
s3d := Subgroup( d12, [ (15,17,19)(16,18,20), (15,20)(16,19)(17,18) ] );
Gs3d := SubgroupoidByComponents( Gd12, [ [[-36,-35,-34], s3d] ] );;
SetName( s3d, "s3d" );  
SetName( Gs3d, "Gs3d" );
gend8 := GeneratorsOfGroup( d8 );
imhd8 := [ ( ), (15,20)(16,19)(17,18) ];
hd8 := GroupHomomorphismByImages( d8, s3d, gend8, imhd8 );
md8 := MorphismOfConnectedGroupoids( Gd8, Gs3d, [-34,-35,-36], hd8 );
Print( "md8 = ", md8, "\n" );
Print( IsBijectiveOnObjects( md8 ), "\n" );
Display( md8 );
Print("\n" );

Print( "SubSection 3.1.2\n" );
hc6 := GroupHomomorphismByImages( c6, s3d, [(5,6,7)(8,9)], [(15,19)(16,18)] );;
mc6 := GroupoidMorphism( Gc6, Gs3d, [ -36 ], hc6 );
Print( "mc6 = ", mc6, "\n" );

md8c6 := MorphismToConnectedGroupoid( Gd8c6, Gs3d, 
    [ [[-34,-35,-36],hd8], [[-36],hc6] ] );
Print( "md8c6 = ", md8c6, "\n" );
Display( md8c6 ); Print("\n");

gens3d := GeneratorsOfGroup( s3d );
imas3d := [ (15,17,19)(16,18,20), (15,16)(17,20)(18,19) ];
as3d := GroupHomomorphismByImages( s3d, s3d, gens3d, imas3d );
aGs3d := MorphismOfConnectedGroupoids( Gs3d, Gs3d, [-35,-34,-36], as3d );
Print( "automorphism aGs3d :-\n" );
Display( aGs3d );
Print( IsGroupoidAutomorphism( aGs3d ), "\n" );
iaGs3d := InverseMorphism( aGs3d );
Print( "inverse of this automorphism:-\n" );
Display( iaGs3d );
Print( "aGs3d has order: ", Order( aGs3d ), "\n\n" );

Gs3dd8 := GroupoidByUnion( [ Gd8, Gs3d ] );
SetName( Gs3dd8, "Gs3d+Gd8" );
common := GroupoidMorphismWithCommonRange( Gs3dd8, Gs3d, [ aGs3d, md8 ] );
Print( "combining md8 and aGs3d:\n");
Display( common );
Print( "\n" );

Print( "SubSection 3.1.3\n" );
idGd8 := IdentityMapping( Gd8 );
Print( "idGd8 = ", idGd8, "\n" );
copys3d := IsomorphismNewObjects( Gs3d, [-32,-31,-30] );
Hs3d := Range( copys3d );
SetName( Hs3d, "Hs3d" );
Print( "isomorphism from s3d on ", Gs3d!.objects, 
       " to s3d on ", Hs3d!.objects, "\n", copys3d, "\n" );
Display( copys3d );
Print( "\n" );

Print( "SubSection 3.1.4\n" );
SetName( ComponentsOfGroupoid(Ud8)[1], "Ud8a" );
SetName( ComponentsOfGroupoid(Ud8)[2], "Ud8b" );
inc := InclusionMappingGroupoids( Gd8, Ud8 );
Print( "inclusion mapping inc:\n" );
Display( inc );
res := RestrictionMappingGroupoids( md8, Ud8, Gs3d );
Print( "restriction mapping res:\n" );
Display( res );
Print( "\n" );

Print( "SubSection 3.2.1\n" );
imad8 := [ (1,2,3,4), (2,4) ];
ad8 := GroupHomomorphismByImages( d8, d8, [(1,2,3,4),(1,3)], imad8 );
aGd8 := MorphismOfConnectedGroupoids( Gd8, Gd8, [-8,-7,-9], ad8 );
mor1 := GroupoidMorphismByUnion( [ aGd8, mc6 ] );;
mor2 := GroupoidMorphismByComponents( Gd8c6, Gs3dd8, [ aGd8, mc6 ] );;
Display( mor2 );
Print( mor1 = mor2, "\n\n" );

Print( "SubSection 3.2.2\n" );

Print( IsGroupoidMorphism( res ), "\n" );
Print( IsInjectiveOnObjects( res ), "\n" );
Print( IsInjective( res ), "\n" );
Print( IsSurjectiveOnObjects( inc ), "\n" );
Print( IsSurjective( inc ), "\n" );
Print( IsGroupoidAutomorphism( aGd8 ), "\n" );
eGd8 := MorphismOfConnectedGroupoids( Gd8, Gd8, [-7,-7,-9], ad8 );
Print( IsGroupoidEndomorphism( eGd8 ), "\n\n" );

Print( "SubSection 3.2.3\n" );
Print( ImagesOfObjects( md8 ), "\n" );
Print( "ImagesSource( md8 ) = \n", ImagesSource(md8), "\n" );
Print( "      e1 = ", e1, "\nhas image: ", ImageElm( md8c6, e1 ), "\n\n" );

Print( "SubSection 3.2.4\n" );
Hk4d := SubgroupoidByComponents( Gd8, [ [[-9,-8,-7], k4d] ] );
Print( "Hk4d = ", Hk4d, "\n" );
SetName( Hk4d, "Hk4d" );
genq8 := GeneratorsOfGroup(q8);
hq8 := GroupHomomorphismByImages( q8,k4d,genq8,[(1,2)(3,4),(1,3)(2,4),()]);
mq8 := GroupoidMorphism( Gq8, Hk4d, [-7,-9], hq8 );
Print( "groupoid morphism mq8:\n" );
Display( mq8 );
iHk4d := InclusionMappingGroupoids( Gd8, Hk4d );
Print( "inclusion mapping of k4d in d8, iHk4d :-\n" );
Display( iHk4d);
mor3 := mq8*iHk4d;
Print( "composite mor3 of mq8 and iHk4d :-\n" );
Display( mor3 );
mor4 := mor3*aGd8;
Print( "composite mor4 of mor3 and automorphism aGd8 :-\n" );
Display( mor4 );
Print( "\n" );

Print( "SubSection 3.2.5\n" );
isos3d := aGs3d * copys3d;
invs3d := InverseMorphism( isos3d );
Print( "inverse invs3d of isomorphism isos3d:\n" );
Display( invs3d );
genq8 := GeneratorsOfGroup( q8 );
imq8 := [ q8.2, q8.1*q8.2, q8.3 ];
Print( "\nimq8 = ", imq8, "\n" );
autq8 := GroupHomomorphismByImages( q8, q8, genq8, imq8 );
autGq8 := GroupoidMorphism( Gq8, Gq8, [-27,-28], autq8 );
Print( "automorphism autGq8 of Gq8:\n" );
Display( autGq8 );
Print( "inverse of autGq8:\n" );
Display( InverseMorphism( autGq8 ) );
Print( Order( autGq8 ), "\n\n" );

###########################################################################
## Chapter 4 : Graphs of Groups or Groupoids

###  Section 4.1  Digraphs

Print( "SubSection 4.1.1\n" );
## define the graph D1
V1 := [5,6];
f1 := FreeGroup("y");
y := f1.1;
A1 := [ [y,5,6], [y^-1,6,5]];
D1 := FpWeightedDigraph( V1, A1 );
Print( D1!.vertices, "\n", D1!.arcs, "\n" );
# Display( D1 );
inv1 := InvolutoryArcs( D1 );
Print( inv1, "\n\n" );

## define the graph D3
f3 := FreeGroup(3,"z");
Print( f3, "\n" );
gf3 := GeneratorsOfGroup(f3);
Print( gf3, "\n" );
z1:=f3.1;; z2:=f3.2;; z3:=f3.3;;
V3 := [7,8,9];
Print( V3, "\n" );
A3 := [[z1,7,8],[z2,8,9],[z3,9,7],[z1^-1,8,7],[z2^-1,9,8],[z3^-1,7,9]];
Print( A3, "\n" );
D3 := FpWeightedDigraph( V3, A3 );
Print( D3, "\n" );
inv3 := InvolutoryArcs( D3 );
Print( inv3, "\n\n" );

### Section 4.2 : Graphs of Groups

Print( "SubSection 4.2.1\n" );
## group fa and subgroup 3fa
fa := FreeGroup( "a" );;
a := fa.1;;
SetName( fa, "fa" );
hy := Subgroup( fa, [a^3] );;
SetName( hy, "hy" );

## group fb and subgroup 2fb
fb := FreeGroup( "b" );;
b := fb.1;;
SetName( fb, "fb" );
hybar := Subgroup( fb, [b^2] );;
SetName( hybar, "hybar" );
## Isomorphisms between subgroups 
homy := GroupHomomorphismByImagesNC( hy, hybar, [a^3], [b^2] );;
homybar := GroupHomomorphismByImagesNC( hybar, hy, [b^2], [a^3] );; 

## defining graph of groups 
G1 := GraphOfGroups( D1, [fa,fb], [hy,hybar], [homy,homybar] );
Display( G1 );

Print( "SubSection 4.2.2\n" );
Print( "IsGraphOfFpGroups(G1)? ", IsGraphOfFpGroups(G1), "\n" );
Print( "G1 has isomorphisms:\n", IsomorphismsOfGraphOfGroups(G1), "\n" );

Print( "SubSection 4.2.3\n" );
RTG1 := RightTransversalsOfGraphOfGroups( G1 );
Print( "right transversals = \n", RTG1, "\n" );
LTG1 := LeftTransversalsOfGraphOfGroups( G1 );
Print( "left transversals = \n", LTG1, "\n\n" );

### Section 4.3  Words in a Graph of Groups and their normal forms

Print( "SubSection 4.3.1\n" );
L1 := [ a^7, 1, b^-6, 2, a^-11, 1, b^9, 2, a^7 ];
gw1 := GraphOfGroupsWord( G1, 5, L1 );
Print( gw1, "\n");
Print( IsGraphOfGroupsWord( gw1 ), "\n" );
Print( [ Tail( gw1 ), Head( gw1 ) ], "\n" );
Print( GraphOfGroupsOfWord( gw1 ), "\n" );
Print( WordOfGraphOfGroupsWord( gw1 ), "\n\n" );

nw1 := ReducedGraphOfGroupsWord( gw1 );
Print( nw1, "\n\n");

### Section 4,4 : Free products with amalgamation and HNN extensions

Print( "Subsection 4.4.1\n");
## set up the first group s3 and a subgroup c3=<a1>
f1 := FreeGroup( 2, "a" );
Print( f1, "\n" );
rel1 := [f1.1^3, f1.2^2, (f1.1*f1.2)^2];
Print( rel1, "\n" );
s3 := f1/rel1;
Print( s3, "\n" );
gs3 := GeneratorsOfGroup(s3);
Print( gs3, "\n" );
SetName(s3,"s3");
a1:=gs3[1];  a2:=gs3[2];
Print( a1, "\n", a2, "\n" );
H1 := Subgroup(s3,[a1]);
Print( H1, "\n" );
## then the second group a4 and subgroup c3=<b1>
f2 := FreeGroup( 2, "b" );
Print( f2, "\n" );
rel2 := [f2.1^3, f2.2^3, (f2.1*f2.2)^2];
Print( rel2, "\n" );
a4 := f2/rel2;
Print( a4, "\n" );
ga4 := GeneratorsOfGroup(a4);
Print( ga4, "\n" );
SetName(a4,"a4");
b1 := ga4[1];  b2:=ga4[2];
Print( b1, "\n", b2, "\n" );
H2 := Subgroup(a4,[b1]);
Print( H2, "\n" );
iso := GroupHomomorphismByImages(H1,H2,[a1],[b1]);
Print( iso, "\n" );
inv := InverseGeneralMapping(iso);
Print( inv, "\n" );
fpa := FreeProductWithAmalgamation( s3, a4, iso );
Print( fpa, "\n" );
Print( RelatorsOfFpGroup( fpa ), "\n" );
gg1 := GraphOfGroupsRewritingSystem( fpa );
Display( gg1 );
Print( LeftTransversalsOfGraphOfGroups( gg1 ), "\n" );
gfpa := GeneratorsOfGroup( fpa );
Print( gfpa, "\n" );
w2 := (gfpa[1]*gfpa[2]*gfpa[3]^gfpa[4])^3;
Print( w2, "\n" );
n2 := NormalFormGGRWS( fpa, w2 );
Print( n2, "\n\n" );

Print( "Subsection 4.4.2\n");
H3 := Subgroup(a4,[b2]);
Print( H3, "\n" );
i23 := GroupHomomorphismByImages( H2, H3, [b1], [b2] );
Print( i23, "\n" );
hnn := HnnExtension( a4, i23 );
Print( hnn, "\n" );
phnn := PresentationFpGroup( hnn );;
TzPrint( phnn );
gg2 := GraphOfGroupsRewritingSystem( hnn );
Print( gg2, "\n" );
Print( LeftTransversalsOfGraphOfGroups( gg2 ), "\n" );
gh := GeneratorsOfGroup( hnn );;
w3 := (gh[1]^gh[2])*gh[3]^-1*(gh[1]*gh[3]*gh[2]^2)^2*gh[3]*gh[2];
Print( w3, "\n" );
n3 := NormalFormGGRWS( hnn, w3 );
Print( n3, "\n\n");

fpainfo := FpaInfo( fpa );
Print( fpainfo, "\n" );
hnninfo := HnnInfo( hnn );
Print( hnninfo, "\n\n" );


### Section 4.5 : GraphsOfGroupoids and their Words

Print( "SubSection 4.5.1\n" );
Gfa := ConnectedGroupoid( [-2,-1], fa );
SetName( Gfa, "Gfa" );
Uhy := Subgroupoid( Gfa, [ [[-2,-1], hy ] ] );
SetName( Uhy, "Uhy" );
Gfb := ConnectedGroupoid( [-4,-3], fb );
SetName( Gfb, "Gfb" );
Uhybar := Subgroupoid( Gfb, [ [[-4,-3], hybar ] ] );
SetName( Uhybar, "Uhybar" );
mory := MorphismOfConnectedGroupoids( Uhy, Uhybar, [-4,-3], homy );
morybar := MorphismOfConnectedGroupoids( Uhybar, Uhy, [-2,-1], homybar );

gg3 := GraphOfGroupoids( D1, [Gfa,Gfb], [Uhy,Uhybar], [mory,morybar] );
Display( gg3 );
Print( "\n" );

Print( "SubSection 4.5.2\n" );
f1 := GroupoidElement( Gfa, a^7, -1, -2);
f2 := GroupoidElement( Gfb, b^-6, -4, -4 );
f3 := GroupoidElement( Gfa, a^-11, -2, -1 );
f4 := GroupoidElement( Gfb, b^9, -3, -4 );
f5 := GroupoidElement( Gfa, a^7, -2, -1 );

Print( "\nf1,f2,f3,f4 = \n", f1,"\n",f2,"\n",f3,"\n",f4,"\n",f5,"\n\n");

L3 := [ f1, 1, f2, 2, f3, 1, f4, 2, f5 ];
Print( "L3 = ", L3, "\n" );
gw3 := GraphOfGroupoidsWord( gg3, 5, L3);
Print( "\ngw3 = ", gw3, "\n" );
nw3 := ReducedGraphOfGroupoidsWord( gw3 );
Print( "\nnw3 = ", nw3, "\n");

Print("\n=============================================================\n");
