2 2d-groups : crossed modules and cat^1-groups

The term *2d-group* refers to a set of equivalent categories of which the most common are the categories of *crossed modules*; *cat^1-groups*; and *group-groupoids*, all of which involve a pair of groups.

A crossed module (of groups) calX = (∂ : S -> R ) consists of a group homomorphism ∂, called the *boundary* of calX, with *source* S and *range* R. The group R acts on itself by conjugation, and on S by an *action* α : R -> Aut(S) such that, for all s,s_1,s_2 ∈ S and r ∈ R,

{\bf XMod\ 1} : \partial(s^r) = r^{-1} (\partial s) r = (\partial s)^r, \qquad {\bf XMod\ 2} : s_1^{\partial s_2} = s_2^{-1}s_1 s_2 = {s_1}^{s_2}.

When only the first of these axioms is satisfied, the resulting structure is a *pre-crossed module* (see section 2.3). The kernel of ∂ is abelian.

(Much of the literature on crossed modules uses left actions, but we have chosen to use right actions in this package since that is the standard choice for group actions in **GAP**.)

`‣ XMod` ( args ) | ( function ) |

`‣ XModByBoundaryAndAction` ( bdy, act ) | ( operation ) |

The global function `XMod`

calls one of the standard constructions described in the following subsections. In the example the boundary is the identity mapping on `c5`

and the action is trivial.

gap> c5 := Group( (5,6,7,8,9) );; gap> SetName( c5, "c5" ); gap> id5 := IdentityMapping( c5 );; gap> ac5 := AutomorphismGroup( c5 );; gap> act := MappingToOne( c5, ac5 );; gap> XMod( id5, act ) = XModByBoundaryAndAction( id5, act ); true

`‣ XModByNormalSubgroup` ( G, N ) | ( operation ) |

A *conjugation crossed module* is the inclusion of a normal subgroup S ⊴ R, where R acts on S by conjugation.

`‣ XModByTrivialAction` ( bdy ) | ( operation ) |

A *trivial action crossed module* (∂ : S -> R) has s^r = s for all s ∈ S, r ∈ R, the source is abelian and the image lies in the centre of the range.

gap> q8 := QuaternionGroup( IsPermGroup, 8 ); Group([ (1,5,3,7)(2,8,4,6), (1,2,3,4)(5,6,7,8) ]) gap> SetName( q8, "q8" ); gap> c2 := Centre( q8 ); Group([ (1,3)(2,4)(5,7)(6,8) ]) gap> SetName( c2, "<-1>" ); gap> bdy := InclusionMappingGroups( q8, c2 );; gap> X8a := XModByTrivialAction( bdy ); [<-1>->q8] gap> c4 := Subgroup( q8, [q8.1] );; gap> SetName( c4, "<i>" ); gap> X8b := XModByNormalSubgroup( q8, c4 ); [<i>->q8] gap> Display(X8b); Crossed module [<i>->q8] :- : Source group has generators: [ (1,5,3,7)(2,8,4,6) ] : Range group q8 has generators: [ (1,5,3,7)(2,8,4,6), (1,2,3,4)(5,6,7,8) ] : Boundary homomorphism maps source generators to: [ (1,5,3,7)(2,8,4,6) ] : Action homomorphism maps range generators to automorphisms: (1,5,3,7)(2,8,4,6) --> { source gens --> [ (1,5,3,7)(2,8,4,6) ] } (1,2,3,4)(5,6,7,8) --> { source gens --> [ (1,7,3,5)(2,6,4,8) ] } These 2 automorphisms generate the group of automorphisms.

`‣ XModByAutomorphismGroup` ( grp ) | ( attribute ) |

`‣ XModByInnerAutomorphismGroup` ( grp ) | ( attribute ) |

`‣ XModByGroupOfAutomorphisms` ( G, A ) | ( operation ) |

An *automorphism crossed module* has as range a subgroup R of the automorphism group Aut(S) of S which contains the inner automorphism group of S. The boundary maps s ∈ S to the inner automorphism of S by s.

gap> X5 := XModByAutomorphismGroup( c5 ); [c5 -> Aut(c5)] gap> Display( X5 ); Crossed module [c5->Aut(c5)] :- : Source group c5 has generators: [ (5,6,7,8,9) ] : Range group Aut(c5) has generators: [ GroupHomomorphismByImages( c5, c5, [ (5,6,7,8,9) ], [ (5,7,9,6,8) ] ) ] : Boundary homomorphism maps source generators to: [ IdentityMapping( c5 ) ] : Action homomorphism maps range generators to automorphisms: GroupHomomorphismByImages( c5, c5, [ (5,6,7,8,9) ], [ (5,7,9,6,8) ] ) --> { source gens --> [ (5,7,9,6,8) ] } This automorphism generates the group of automorphisms.

`‣ XModByCentralExtension` ( bdy ) | ( operation ) |

A *central extension crossed module* has as boundary a surjection ∂ : S -> R, with central kernel, where r ∈ R acts on S by conjugation with ∂^-1r.

gap> gen12 := [ (1,2,3,4,5,6), (2,6)(3,5) ];; gap> d12 := Group( gen12 );; gap> gen6 := [ (7,8,9), (8,9) ];; gap> s3 := Group( gen6 );; gap> pr12 := GroupHomomorphismByImages( d12, s3, gen12, gen6 );; gap> Kernel( pr12 ) = Centre( d12 ); true gap> X12 := XModByCentralExtension( pr12 );; gap> Display( X12 ); Crossed module :- : Source group has generators: [ (1,2,3,4,5,6), (2,6)(3,5) ] : Range group has generators: [ (7,8,9), (8,9) ] : Boundary homomorphism maps source generators to: [ (7,8,9), (8,9) ] : Action homomorphism maps range generators to automorphisms: (7,8,9) --> { source gens --> [ (1,2,3,4,5,6), (1,3)(4,6) ] } (8,9) --> { source gens --> [ (1,6,5,4,3,2), (2,6)(3,5) ] } These 2 automorphisms generate the group of automorphisms.

`‣ XModByPullback` ( xmod, hom ) | ( operation ) |

Let calX_0 = (μ : M -> P) be a crossed module. If ν : N -> P is a group homomorphism with the same range as calX_0, form the pullback group L = M ×_P N, with projection λ : L -> N (as defined in the **Utils** package). Then N acts on L by (m,n)^n' := (m^ν n',n^n'), so that calX_1 = (λ : L -> N) is the * pullback crossed module* determined by calX_0 and ν. There is also a morphism of crossed modules (κ,ν) : calX_1 -> calX_2.

The example forms a pullback of the crossed module `X12`

of the previous subsection.

gap> gens4 := [ (11,12), (12,13), (13,14) ];; gap> s4 := Group( gens4 );; gap> theta := GroupHomomorphismByImages( s4, s3, gens4, [(7,8),(8,9),(7,8)] );; gap> X1 := XModByPullback( X12, theta );; gap> StructureDescription( Source( X1 ) ); "C2 x S4" gap> info := PullbackInfo( Source( X1 ) );; gap> info!.directProduct; Group([ (1,2,3,4,5,6), (2,6)(3,5), (7,8), (8,9), (9,10) ]) gap> info!.projections[1]; [ (7,8)(9,10), (7,9)(8,10), (2,6)(3,5)(8,9), (1,5,3)(2,6,4)(8,10,9), (1,6,5,4,3,2)(8,9,10) ] -> [ (), (), (2,6)(3,5), (1,5,3)(2,6,4), (1,6,5,4,3,2) ] gap> info!.projections[2]; [ (7,8)(9,10), (7,9)(8,10), (2,6)(3,5)(8,9), (1,5,3)(2,6,4)(8,10,9), (1,6,5,4,3,2)(8,9,10) ] -> [ (11,12)(13,14), (11,13)(12,14), (12,13), (12,14,13), (12,13,14) ]

`‣ XModByAbelianModule` ( abmod ) | ( operation ) |

A *crossed abelian module* has an abelian module as source and the zero map as boundary. See section 12.2 for an example.

`‣ DirectProductOp` ( L, X1 ) | ( operation ) |

The direct product calX_1 × calX_2 of two crossed modules has source S_1 × S_2, range R_1 × R_2 and boundary ∂_1 × ∂_2, with R_1, R_2 acting trivially on S_2, S_1 respectively.

Since `DirectProduct`

is a global function which only accepts groups, it is necessary to provide an "other method" for the operation `DirectProductOp`

. This operation takes as parameters a list of crossed modules, followed by the first of these: `DirectProductOp([X1,X2],X1);`

. At present only the direct product of two crossed modules is implemented.

The example constructs the product of the two crossed modules formed in subsection `XModByTrivialAction`

(2.1-3).

gap> DirectProductOp( [X8a,X8b], X8a ); [<-1>x<i>->q8xq8]

`‣ Source` ( X0 ) | ( attribute ) |

`‣ Range` ( X0 ) | ( attribute ) |

`‣ Boundary` ( X0 ) | ( attribute ) |

`‣ XModAction` ( X0 ) | ( attribute ) |

The following attributes are used in the construction of a crossed module `X0`

.

`Source(X0)`

and`Range(X0)`

are the source S and range R of ∂, the boundary`Boundary(X0)`

;`XModAction(X0)`

is a homomorphism from R to a group of automorphisms of`X0`

.

(Up until version 2.63 there was an additional attribute `AutoGroup`

, the range of `XModAction(X0)`

.)

The example uses the crossed module `X12`

constructed in subsection `XModByCentralExtension`

(2.1-5).

gap> Source( X12 ); Group([ (1,2,3,4,5,6), (2,6)(3,5) ]) gap> Range( X12 ); Group([ (7,8,9), (8,9) ]) gap> Boundary( X12 ); [ (1,2,3,4,5,6), (2,6)(3,5) ] -> [ (7,8,9), (8,9) ] gap> XModAction( X12 ); [ (7,8,9), (8,9) ] -> [ [ (1,2,3,4,5,6), (2,6)(3,5) ] -> [ (1,2,3,4,5,6), (1,3)(4,6) ], [ (1,2,3,4,5,6), (2,6)(3,5) ] -> [ (1,6,5,4,3,2), (2,6)(3,5) ] ]

`‣ ImageElmXModAction` ( X0, s, r ) | ( operation ) |

This function returns the element s^r given by `XModAction(X0)`

.

`‣ Size` ( X0 ) | ( attribute ) |

`‣ Name` ( X0 ) | ( attribute ) |

`‣ IdGroup` ( X0 ) | ( attribute ) |

`‣ ExternalSetXMod` ( X0 ) | ( attribute ) |

More familiar attributes are `Name`

, `Size`

and `IdGroup`

. The name is formed by concatenating the names of the source and range (if these exist). `Size`

and `IdGroup`

return two-element lists.

The `ExternalSetXMod`

for a crossed module is the source group considered as a G-set of the range group using the crossed module action.

The `Display`

function is used to print details of 2d-groups.

In the simple example below, `X5`

is the automorphism crossed module constructed in subsection `XModByAutomorphismGroup`

(2.1-4). The `Print`

statements at the end of the example list the **GAP** representations and attributes of `X5`

.

gap> Size( X5 ); IdGroup( X5 ); [ 5, 4 ] [ [ 5, 1 ], [ 4, 1 ] ] gap> ext := ExternalSetXMod( X5 ); <xset:[ (), (5,6,7,8,9), (5,7,9,6,8), (5,8,6,9,7), (5,9,8,7,6) ]> gap> Orbits( ext ); [ [ () ], [ (5,6,7,8,9), (5,7,9,6,8), (5,9,8,7,6), (5,8,6,9,7) ] ] gap> a := GeneratorsOfGroup( Range( X5 ) )[1]^2; [ (5,6,7,8,9) ] -> [ (5,9,8,7,6) ] gap> ImageElmXModAction( X5, (5,7,9,6,8), a ); (5,8,6,9,7) gap> RepresentationsOfObject( X5 ); [ "IsComponentObjectRep", "IsAttributeStoringRep", "IsPreXModObj" ] gap> KnownAttributesOfObject( X5); [ "Name", "Size", "Range", "Source", "IdGroup", "Boundary", "XModAction", "ExternalSetXMod" ]

The underlying category structures for the objects constructed in this chapter follow the sequence `Is2DimensionalDomain`

; `Is2DimensionalMagma`

; `Is2DimensionalMagmaWithOne`

; `Is2DimensionalMagmaWithInverses`

, mirroring the situation for (one-dimensional) groups. From these we construct `Is2DimensionalSemigroup`

, `Is2DimensionalMonoid`

and `Is2DimensionalGroup`

.

There are then a variety of properties associated with crossed modules, starting with `IsPreXMod`

and `IsXMod`

.

`‣ IsXMod` ( X0 ) | ( property ) |

`‣ IsPreXMod` ( X0 ) | ( property ) |

`‣ IsPerm2DimensionalGroup` ( X0 ) | ( property ) |

`‣ IsPc2DimensionalGroup` ( X0 ) | ( property ) |

`‣ IsFp2DimensionalGroup` ( X0 ) | ( property ) |

A structure which has `IsPerm2DimensionalGroup`

is a precrossed module or a pre-cat^1-group (see section 2.4) whose source and range are both permutation groups. The properties `IsPc2DimensionalGroup`

, `IsFp2DimensionalGroup`

are defined similarly. In the example below we see that `X5`

has `IsPreXMod`

, `IsXMod`

and `IsPerm2DimensionalGroup`

. There are also properties corresponding to the various construction methods listed in section 2.1: `IsTrivialAction2DimensionalGroup`

; `IsNormalSubgroup2DimensionalGroup`

; `IsCentralExtension2DimensionalGroup`

; `IsAutomorphismGroup2DimensionalGroup`

; `IsAbelianModule2DimensionalGroup`

.

gap> KnownPropertiesOfObject( X5 ); [ "IsEmpty", "IsTrivial", "IsNonTrivial", "IsFinite", "CanEasilyCompareElements", "CanEasilySortElements", "IsDuplicateFree", "IsGeneratorsOfSemigroup", "IsPreXModDomain", "IsPreXMod", "IsXMod", "IsAutomorphismGroup2DimensionalGroup" ]

`‣ SubXMod` ( X0, src, rng ) | ( operation ) |

`‣ TrivialSubXMod` ( X0 ) | ( attribute ) |

`‣ NormalSubXMods` ( X0 ) | ( attribute ) |

With the standard crossed module constructors listed above as building blocks, sub-crossed modules, normal sub-crossed modules calN ⊲ calX, and also quotients calX/calN may be constructed. A sub-crossed module calS = (δ : N -> M) is *normal* in calX = (∂ : S -> R) if

N,M are normal subgroups of S,R respectively,

δ is the restriction of ∂,

n^r ∈ N for all n ∈ N,~r ∈ R,

(s^-1)^ms ∈ N for all m ∈ M,~s ∈ S.

These conditions ensure that M ⋉ N is normal in the semidirect product R ⋉ S. (Note that ⟨ s,m ⟩ = (s^-1)^ms is a displacement: see `Displacement`

(4.1-3).)

A method for `IsNormal`

for precrossed modules is provided. See section 4.1 for factor crossed modules and their natural morphisms.

The five normal subcrossed modules of `X4`

found in the following example are `[id,id], [k4,k4], [k4,a4], [a4,a4]`

and `X4`

itself.

gap> s4 := Group( (1,2), (2,3), (3,4) );; gap> a4 := Subgroup( s4, [ (1,2,3), (2,3,4) ] );; gap> k4 := Subgroup( a4, [ (1,2)(3,4), (1,3)(2,4) ] );; gap> SetName(s4,"s4"); SetName(a4,"a4"); SetName(k4,"k4"); gap> X4 := XModByNormalSubgroup( s4, a4 ); [a4->s4] gap> Y4 := SubXMod( X4, k4, a4 ); [k4->a4] gap> IsNormal(X4,Y4); true gap> NX4 := NormalSubXMods( X4 );; gap> Length( NX4 ); 5

`‣ KernelCokernelXMod` ( X0 ) | ( attribute ) |

Let calX = (∂ : S -> R). If K leqslant S is the kernel of ∂, and J leqslant R is the image of ∂, form C = R/J. Then (ν∂|_K : K -> C) is a crossed module where ν : R -> C, r ↦ Jr is the natural map, and the action of C on K is given by k^Jr = k^r.

gap> d8d8 := Group( (1,2,3,4), (1,3), (5,6,7,8), (5,7) );; gap> X88 := XModByAutomorphismGroup( d8d8 );; gap> Size( X88 ); [ 64, 2048 ] gap> Y88 := KernelCokernelXMod( X88 );; gap> StructureDescription( Y88 ); [ "C2 x C2", "(D8 x D8) : C2" ]

`‣ PreXModByBoundaryAndAction` ( bdy, act ) | ( operation ) |

`‣ SubPreXMod` ( X0, src, rng ) | ( operation ) |

If axiom XMod 2 is *not* satisfied, the corresponding structure is known as a *pre-crossed module*.

gap> b1 := (11,12,13,14,15,16,17,18);; b2 := (12,18)(13,17)(14,16);; gap> d16 := Group( b1, b2 );; gap> sk4 := Subgroup( d16, [ b1^4, b2 ] );; gap> SetName( d16, "d16" ); SetName( sk4, "sk4" ); gap> bdy16 := GroupHomomorphismByImages( d16, sk4, [b1,b2], [b1^4,b2] );; gap> aut1 := GroupHomomorphismByImages( d16, d16, [b1,b2], [b1^5,b2] );; gap> aut2 := GroupHomomorphismByImages( d16, d16, [b1,b2], [b1,b2^4*b2] );; gap> aut16 := Group( [ aut1, aut2 ] );; gap> act16 := GroupHomomorphismByImages( sk4, aut16, [b1^4,b2], [aut1,aut2] );; gap> P16 := PreXModByBoundaryAndAction( bdy16, act16 ); [d16->sk4] gap> IsXMod(P16); false

`‣ PeifferSubgroup` ( X0 ) | ( attribute ) |

`‣ XModByPeifferQuotient` ( prexmod ) | ( attribute ) |

The *Peiffer subgroup* P of a pre-crossed module calX is the subgroup of ker(∂) generated by *Peiffer commutators*

\lfloor s_1,s_2 \rfloor ~=~ (s_1^{-1})^{\partial s_2}~s_2^{-1}~s_1~s_2 ~=~ \langle \partial s_2, s_1 \rangle\ [s_1,s_2]~.

Then calP = (0 : P -> {1_R}) is a normal sub-pre-crossed module of calX and calX/calP = (∂ : S/P -> R) is a crossed module.

In the following example the Peiffer subgroup is cyclic of size 4.

gap> P := PeifferSubgroup( P16 ); Group( [ (11,15)(12,16)(13,17)(14,18), (11,17,15,13)(12,18,16,14) ] ) gap> X16 := XModByPeifferQuotient( P16 ); Peiffer([d16->sk4]) gap> Display( X16 ); Crossed module Peiffer([d16->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,16)(13,17)(14,18) ] The automorphism group is trivial gap> iso16 := IsomorphismPermGroup( Source( X16 ) );; gap> S16 := Image( iso16 ); Group([ (1,2), (3,4) ])

In [Lod82], Loday reformulated the notion of a crossed module as a cat^1-group, namely a group G with a pair of endomorphisms t,h : G -> G having a common image R and satisfying certain axioms. We find it computationally convenient to define a cat^1-group calC = (e;t,h : G -> R ) as having source group G, range group R, and three homomorphisms: two surjections t,h : G -> R and an embedding e : R -> G satisfying:

{\bf Cat\ 1} : ~t \circ e ~=~ h \circ e = {\rm id}_R, \qquad {\bf Cat\ 2} : ~[\ker t, \ker h] ~=~ \{ 1_G \}.

It follows that t ∘ e ∘ h = h,~ h ∘ e ∘ t = t,~ t ∘ e ∘ t = t~ and ~h ∘ e ∘ h = h. (See section 2.5 for the case when t,h are endomorphisms.)

`‣ Cat1Group` ( args ) | ( function ) |

`‣ PreCat1Group` ( args ) | ( function ) |

`‣ PreCat1GroupByTailHeadEmbedding` ( t, h, e ) | ( operation ) |

`‣ PreCat1GroupByEndomorphisms` ( t, h ) | ( operation ) |

The global functions `Cat1Group`

and `PreCat1Group`

can be called in various ways.

as

`Cat1Group(t,h,e);`

when t,h,e are three homomorphisms, which is equivalent to`PreCat1GroupByTailHeadEmbedding(t,h,e);`

as

`Cat1Group(t,h);`

when t,h are two endomorphisms, which is equivalent to`PreCat1GroupByEndomorphisms(t,h);`

as

`Cat1Group(t);`

when t=h is an endomorphism, which is equivalent to`PreCat1GroupByEndomorphisms(t,t);`

as

`Cat1Group(t,e);`

when t=h and e are homomorphisms, which is equivalent to`PreCat1GroupByTailHeadEmbedding(t,t,e);`

as

`Cat1Group(i,j,k);`

when i,j,k are integers, which is equivalent to`Cat1Select(i,j,k);`

as described in section 2.7.

gap> g18gens := [ (1,2,3), (4,5,6), (2,3)(5,6) ];; gap> s3agens := [ (7,8,9), (8,9) ];; gap> g18 := Group( g18gens );; SetName( g18, "g18" ); gap> s3a := Group( s3agens );; SetName( s3a, "s3a" ); gap> t1 := GroupHomomorphismByImages(g18,s3a,g18gens,[(7,8,9),(),(8,9)]); [ (1,2,3), (4,5,6), (2,3)(5,6) ] -> [ (7,8,9), (), (8,9) ] gap> h1 := GroupHomomorphismByImages(g18,s3a,g18gens,[(7,8,9),(7,8,9),(8,9)]); [ (1,2,3), (4,5,6), (2,3)(5,6) ] -> [ (7,8,9), (7,8,9), (8,9) ] gap> e1 := GroupHomomorphismByImages(s3a,g18,s3agens,[(1,2,3),(2,3)(5,6)]); [ (7,8,9), (8,9) ] -> [ (1,2,3), (2,3)(5,6) ] gap> C18 := Cat1Group( t1, h1, e1 ); [g18=>s3a]

`‣ Source` ( C ) | ( attribute ) |

`‣ Range` ( C ) | ( attribute ) |

`‣ TailMap` ( C ) | ( attribute ) |

`‣ HeadMap` ( C ) | ( attribute ) |

`‣ RangeEmbedding` ( C ) | ( attribute ) |

`‣ KernelEmbedding` ( C ) | ( attribute ) |

`‣ Boundary` ( C ) | ( attribute ) |

`‣ Name` ( C ) | ( attribute ) |

`‣ Size` ( C ) | ( attribute ) |

These are the attributes of a cat^1-group calC in this implementation.

The maps t,h are often referred to as the *source* and *target*, but we choose to call them the *tail* and *head* of calC, because *source* is the **GAP** term for the domain of a function. The `RangeEmbedding`

is the embedding of `R`

in `G`

, the `KernelEmbedding`

is the inclusion of the kernel of `t`

in `G`

, and the `Boundary`

is the restriction of `h`

to the kernel of `t`

. It is frequently the case that t=h, but not in the example `C18`

above.

gap> Source( C18 ); g18 gap> Range( C18 ); s3a gap> TailMap( C18 ); [ (1,2,3), (4,5,6), (2,3)(5,6) ] -> [ (7,8,9), (), (8,9) ] gap> HeadMap( C18 ); [ (1,2,3), (4,5,6), (2,3)(5,6) ] -> [ (7,8,9), (7,8,9), (8,9) ] gap> RangeEmbedding( C18 ); [ (7,8,9), (8,9) ] -> [ (1,2,3), (2,3)(5,6) ] gap> Kernel( C18 ); Group([ (4,5,6) ]) gap> KernelEmbedding( C18 ); [ (4,5,6) ] -> [ (4,5,6) ] gap> Name( C18 ); "[g18=>s3a]" gap> Size( C18 ); [ 18, 6 ] gap> StructureDescription( C18 ); [ "(C3 x C3) : C2", "S3" ]

`‣ DiagonalCat1Group` ( gen1 ) | ( operation ) |

**[Needs revising!]**

The next three subsections contain some more constructors for cat^1-groups. The following listing shows an example of a permutation cat^1-group of size [576,24] with source group S_4 × S_4, range group a third S_4, and t ≠ h. A similar example may be reproduced using the command `C := DiagonalCat1Group([(1,2,3,4),(3,4)]);`

.

gap> G4 := Group( (1,2,3,4), (3,4), (5,6,7,8), (7,8) );; gap> R4 := Group( (9,10,11,12), (11,12) );; gap> SetName( G4, "s4s4" ); SetName( R4, "s4d" ); gap> G4gens := GeneratorsOfGroup( G4 );; gap> R4gens := GeneratorsOfGroup( R4 );; gap> t := GroupHomomorphismByImages( G4, R4, G4gens, > Concatenation( R4gens, [ (), () ] ) );; gap> h := GroupHomomorphismByImages( G4, R4, G4gens, > Concatenation( [ (), () ], R4gens ) );; gap> e := GroupHomomorphismByImages( R4, G4, R4gens, > [ (1,2,3,4)(5,6,7,8), (3,4)(7,8) ] );; gap> C4 := PreCat1GroupByTailHeadEmbedding( t, h, e );; gap> Display(C4); Cat1-group [s4s4=>s4d] :- : Source group s4s4 has generators: [ (1,2,3,4), (3,4), (5,6,7,8), (7,8) ] : Range group s4d has generators: [ ( 9,10,11,12), (11,12) ] : tail homomorphism maps source generators to: [ ( 9,10,11,12), (11,12), (), () ] : head homomorphism maps source generators to: [ (), (), ( 9,10,11,12), (11,12) ] : range embedding maps range generators to: [ (1,2,3,4)(5,6,7,8), (3,4)(7,8) ] : kernel has generators: [ (5,6,7,8), (7,8) ] : boundary homomorphism maps generators of kernel to: [ ( 9,10,11,12), (11,12) ] : kernel embedding maps generators of kernel to: [ (5,6,7,8), (7,8) ]

`‣ ReverseCat1Group` ( C0 ) | ( attribute ) |

The *reverse* of a cat^1-group C has the same source, range and embedding, but has the tail and head maps interchanged.

gap> R4 := ReverseCat1Group( C4 ); [s4s4=>s4d] gap> Boundary( R4 ); [ (3,4), (2,3), (1,2,3,4) ] -> [ (11,12), (10,11), (9,10,11,12) ] gap> TailMap( R4 ) = HeadMap( C4 ); true

`‣ Cat1GroupByPeifferQuotient` ( P ) | ( operation ) |

If C = (e;t,h : G -> R) is a pre-cat^1-group, its Peiffer subgroup is P = [ker t,ker h] and the associated cat^1-group C_2 has source G/P. In the example, t=h : s4 -> c2 with ker t = ker h = a4 and P = [a4,a4]=k4, so that G/P = s4/k4 ≅ s3.

gap> s4:=Group( (1,2,3), (3,4) );; SetName( s4, "s4" ); gap> h := GroupHomomorphismByImages( s4, s4, [(1,2,3),(3,4)], [(),(3,4)] );; gap> c2 := Image( h );; SetName( c2, "c2" ); gap> C := PreCat1Group( h, h ); [s4=>c2] gap> P := PeifferSubgroupPreCat1Group( C ); Group([ (1,3)(2,4), (1,2)(3,4) ]) gap> C2 := Cat1GroupByPeifferQuotient( C ); [Group( [ f1, f2 ] )=>c2] gap> StructureDescription( C2 ); [ "S3", "C2" ] gap> XC := PreXModOfPreCat1Group( C );; gap> StructureDescription( XC ); [ "A4", "C2" ] gap> XC2 := XModByPeifferQuotient( XC );; gap> StructureDescription( XC2 ); [ "C3", "C2" ] gap> CXC2 := Cat1GroupOfXMod( XC2 );; gap> StructureDescription( CXC2 ); [ "S3", "C2" ] gap> IsomorphismCat1Groups( C2, CXC2 ); [[..] => [(..|X..)=>c2]]

Many of the properties listed in section 2.2 apply to pre-cat^1-groups and to cat^1-groups since these are also 2d-groups. There are also more specific properties.

`‣ IsCat1Group` ( C0 ) | ( property ) |

`‣ IsPreXCat1Group` ( C0 ) | ( property ) |

`‣ IsIdentityCat1Group` ( C0 ) | ( property ) |

`‣ IsPreCat1GroupByEndomorphisms` ( C0 ) | ( property ) |

`‣ EndomorphismPreCat1Group` ( C0 ) | ( attribute ) |

`IsIdentityCat1Group(C0)`

is true when the head and tail maps of `C0`

are identity mappings. `IsPreCat1GroupByEndomorphisms(C0)`

is true when the range of `C0`

is a subgroup of the source. When this is not the case, replacing t,h,e by t*e,h*e and the inclusion mapping of the image of e gives an isomorphic cat^1-group for which `IsPreCat1GroupByEndomorphisms`

is true.

gap> G2 := SmallGroup( 288, 956 ); SetName( G2, "G2" ); <pc group of size 288 with 7 generators> gap> d12 := DihedralGroup( 12 ); SetName( d12, "d12" ); <pc group of size 12 with 3 generators> gap> a1 := d12.1;; a2 := d12.2;; a3 := d12.3;; a0 := One( d12 );; gap> gensG2 := GeneratorsOfGroup( G2 );; gap> t2 := GroupHomomorphismByImages( G2, d12, gensG2, > [ a0, a1*a3, a2*a3, a0, a0, a3, a0 ] );; gap> h2 := GroupHomomorphismByImages( G2, d12, gensG2, > [ a1*a2*a3, a0, a0, a2*a3, a0, a0, a3^2 ] );; gap> e2 := GroupHomomorphismByImages( d12, G2, [a1,a2,a3], > [ G2.1*G2.2*G2.4*G2.6^2, G2.3*G2.4*G2.6^2*G2.7, G2.6*G2.7^2 ] ); [ f1, f2, f3 ] -> [ f1*f2*f4*f6^2, f3*f4*f6^2*f7, f6*f7^2 ] gap> C2 := PreCat1GroupByTailHeadEmbedding( t2, h2, e2 ); [G2=>d12] gap> IsCat1Group( C2 ); true gap> KnownPropertiesOfObject( C2 ); [ "CanEasilyCompareElements", "CanEasilySortElements", "IsDuplicateFree", "IsGeneratorsOfSemigroup", "IsPreCat1Domain", "IsPerm2DimensionalGroup", "IsPreCat1Group", "IsCat1Group", "IsPreCat1GroupByEndomorphisms" ] gap> IsPreCat1GroupByEndomorphisms( C2 ); false gap> EC4 := EndomorphismPreCat1Group( C4 ); [s4s4=>Group( [ (1,2,3,4)(5,6,7,8), (3,4)(7,8), (), () ] )]

`‣ Cat1GroupOfXMod` ( X0 ) | ( attribute ) |

`‣ XModOfCat1Group` ( C0 ) | ( attribute ) |

`‣ PreCat1GroupOfPreXMod` ( P0 ) | ( attribute ) |

`‣ PreXModOfPreCat1Group` ( P0 ) | ( attribute ) |

The category of crossed modules is equivalent to the category of cat^1-groups, and the functors between these two categories may be described as follows. Starting with the crossed module calX = (∂ : S -> R) the group G is defined as the semidirect product G = R ⋉ S using the action from calX, with multiplication rule

(r_1,s_1)(r_2,s_2) ~=~ (r_1r_2,{s_1}^{r_2}s_2).

The structural morphisms are given by

t(r,s) = r, \quad h(r,s) = r (\partial s), \quad er = (r,1).

On the other hand, starting with a cat^1-group calC = (e;t,h : G -> R), we define S = ker t, the range R is unchanged, and ∂ = h∣_S. The action of R on S is conjugation in G via the embedding of R in G.

As from version 2.74, the attribute `PreCat1GroupOfPreXMod`

of a pre-crossed modute X = (∂ : S -> R) returns a record with fields

`.precat1`

, the pre-cat1-group C = (e;t,h: G -> R) of X, where G = R ⋉ S;`.iscat1`

, true if C is a cat1-group;`.xmodSourceEmbedding`

, the image S' of S in G;`.xmodSourceEmbeddingIsomorphism`

, the isomorphism S -> S';`.xmodRangeEmbedding`

, the image R' of R in G;`.xmodRangeEmbeddingIsomorphism`

, the isomorphism R -> R';

gap> X2 := XModOfCat1Group( C2 );; gap> Display( X2 ); Crossed module X([G2=>d12]) :- : Source group has generators: [ f1, f4, f5, f7 ] : Range group d12 has generators: [ f1, f2, f3 ] : Boundary homomorphism maps source generators to: [ f1*f2*f3, f2*f3, <identity> of ..., f3^2 ] : Action homomorphism maps range generators to automorphisms: f1 --> { source gens --> [ f1*f5, f4*f5, f5, f7^2 ] } f2 --> { source gens --> [ f1*f5*f7^2, f4, f5, f7 ] } f3 --> { source gens --> [ f1*f7, f4, f5, f7 ] } These 3 automorphisms generate the group of automorphisms. : associated cat1-group is [G2=>d12] gap> StructureDescription(X2); [ "D24", "D12" ]

As the size of a group G increases, the number of cat^1-groups with source G increases rapidly. However, one is usually only interested in the isomorphism classes of cat^1-groups with source G. An iterator `AllCat1GroupsIterator`

is provided, which runs through the various cat^1-groups. This iterator finds, for each subgroup R of G, the cat^1-groups with range R. It does this by running through the `AllSubgroupsIterator(G)`

provided by the **Utils** package, and then using the iterator `AllCat1GroupsWithImageIterator(G,R)`

.

`‣ AllCat1GroupsWithImageIterator` ( G, R ) | ( operation ) |

`‣ AllCat1GroupsWithImageNumber` ( G, R ) | ( attribute ) |

`‣ AllCat1GroupsWithImageUpToIsomorphism` ( G, R ) | ( operation ) |

`‣ AllCat1GroupsWithImage` ( G, R ) | ( operation ) |

The iterator `AllCat1GroupsWithImageIterator(G,R)`

iterates through all the cat^1-groups with source `G`

and range R. The attribute `AllCat1GroupsWithImageNumber(G)`

runs through this iterator to count the number n_R of these cat^1-groups. The operation `AllCat1GroupsWithImage(G)`

returns a list containing these n_R cat^1-groups. Since these lists can get very long, this operation should only be used for simple cases. The operation `AllCat1GroupsWithImageUpToIsomorphism(G)`

returns representatives of the isomorphism classes of these cat^1-groups.

gap> d12 := DihedralGroup( IsPermGroup, 12 ); SetName( d12, "d12" ); Group([ (1,2,3,4,5,6), (2,6)(3,5) ]) gap> c2 := Subgroup( d12, [ (1,6)(2,5)(3,4) ] );; gap> AllCat1GroupsWithImageNumber( d12, c2 ); 1 gap> L12 := AllCat1GroupsWithImage( d12, c2 ); [ [d12=>Group( [ (), (1,6)(2,5)(3,4) ] )] ]

`‣ AllCat1GroupsIterator` ( G ) | ( operation ) |

`‣ AllCat1GroupsNumber` ( G ) | ( attribute ) |

`‣ AllCat1GroupsUpToIsomorphism` ( G ) | ( operation ) |

`‣ AllCat1Groups` ( G ) | ( operation ) |

The iterator `AllCat1GroupsIterator(G)`

iterates through all the cat^1-groups with source `G`

. The attribute `AllCat1GroupsNumber(G)`

runs this iterator to count the number n of these cat^1-groups. The operation `AllCat1Groups(G)`

returns a list containing these n cat^1-groups. Since these lists can get very long, this operation should only be used for simple cases. The operation `AllCat1GroupsUpToIsomorphism(G)`

returns representatives of the isomorphism classes of these subgroups.

gap> iter := AllCat1GroupsIterator( d12 );; gap> AllCat1GroupsNumber( d12 ); 12 gap> iso12 := AllCat1GroupsUpToIsomorphism( d12 ); [ [d12=>Group( [ (), (2,6)(3,5) ] )], [d12=>Group( [ (1,4)(2,5)(3,6), (2,6)(3,5) ] )], [d12=>Group( [ (1,5,3)(2,6,4), (2,6)(3,5) ] )], [d12=>Group( [ (1,2,3,4,5,6), (2,6)(3,5) ] )] ]

`‣ CatnGroupNumbers` ( G ) | ( attribute ) |

`‣ CatnGroupLists` ( G ) | ( attribute ) |

`‣ InitCatnGroupRecords` ( G ) | ( operation ) |

The attribute `CatnGroupNumbers`

for a group G is a mutable record which stores numbers of cat^1-groups, cat^2-groups, etc. as they are calculated. The field `CatnGroupNumbers(G).idem`

is the number of idempotent endomorphisms of G. Similarly, `CatnGroupNumbers(G).cat1`

is the number of cat^1-groups on G, while `CatnGroupNumbers(G).iso1`

is the number of isomorphism classes of these cat^1-groups. The attribute `CatnGroupLists`

is used for storing results of cat^2-group calculations.

gap> CatnGroupNumbers( d12 ); rec( cat1 := 12, idem := 21, iso1 := 4 )

The `Cat1Group`

function may also be used to select a cat^1-group from a data file. All cat^1-structures on groups of size up to 70 (ordered according to the **GAP** 4 numbering of small groups) are stored in a list in file `cat1data.g`

. Global variables `CAT1_LIST_MAX_SIZE := 70`

and `CAT1_LIST_CLASS_SIZES`

are also stored. The data is read into the list `CAT1_LIST`

only when this function is called.

`‣ Cat1Select` ( size, gpnum, num ) | ( operation ) |

The function `Cat1Select`

may be used in three ways. `Cat1Select( size )`

returns the names of the groups with this size, while `Cat1Select( size, gpnum )`

prints a list of cat^1-structures for this chosen group. `Cat1Select( size, gpnum, num )`

returns the chosen cat^1-group.

The example below is the first case in which t ≠ h and the associated conjugation crossed module is given by the normal subgroup `c3`

of `s3`

.

gap> ## check the number of groups of size 18 gap> L18 := Cat1Select( 18 ); Usage: Cat1Select( size, gpnum, num ); [ "D18", "C18", "C3 x S3", "(C3 x C3) : C2", "C6 x C3" ] gap> ## check the number of cat1-structures on the fourth of these gap> Cat1Select( 18, 4 ); Usage: Cat1Select( size, gpnum, num ); There are 4 cat1-structures for the group (C3 x C3) : C2. Using small generating set [ f1, f2, f2*f3 ] for source of homs. [ [range gens], [tail genimages], [head genimages] ] :- (1) [ [ f1 ], [ f1, <identity> of ..., <identity> of ... ], [ f1, <identity> of ..., <identity> of ... ] ] (2) [ [ f1, f3 ], [ f1, <identity> of ..., f3 ], [ f1, <identity> of ..., f3 ] ] (3) [ [ f1, f3 ], [ f1, <identity> of ..., f3 ], [ f1, f3^2, <identity> of ... ] ] (4) [ [ f1, f2, f2*f3 ], tail = head = identity mapping ] 4 gap> ## select the third of these cat1-structures gap> C18 := Cat1Select( 18, 4, 3 ); [(C3 x C3) : C2=>Group( [ f1, <identity> of ..., f3 ] )] gap> ## convert from a pc-cat1-group to a permutation cat1-group gap> iso18 := IsomorphismPermObject( C18 );; gap> PC18 := Image( iso18 );; gap> Display( PC18 ); Cat1-group :- : Source group has generators: [ (2,3)(5,6), (4,5,6), (1,2,3) ] : Range group has generators: [ (2,3), (), (1,2,3) ] : tail homomorphism maps source generators to: [ (2,3), (), (1,2,3) ] : head homomorphism maps source generators to: [ (2,3), (1,3,2), (1,2,3) ] : range embedding maps range generators to: [ (2,3)(5,6), (), (1,2,3) ] : kernel has generators: [ (4,5,6) ] : boundary homomorphism maps generators of kernel to: [ (1,3,2) ] : kernel embedding maps generators of kernel to: [ (4,5,6) ] gap> convert the result to the associated permutation crossed module gap> X18 := XModOfCat1Group( PC18 );; gap> Display( X18 ); Crossed module:- : Source group has generators: [ (4,5,6) ] : Range group has generators: [ (2,3), (), (1,2,3) ] : Boundary homomorphism maps source generators to: [ (1,3,2) ] : Action homomorphism maps range generators to automorphisms: (2,3) --> { source gens --> [ (4,6,5) ] } () --> { source gens --> [ (4,5,6) ] } (1,2,3) --> { source gens --> [ (4,5,6) ] } These 3 automorphisms generate the group of automorphisms. : associated cat1-group is [..=>..]

`‣ AllCat1DataGroupsBasic` ( gp ) | ( operation ) |

For a group G of size greater than 70 which is reasonably straightforward this function may be used to construct a list of all cat^1-group structures on G. The operation also attempts to write output to a file in the folder `xmod/lib`

. (Other operations in the file `cat1data.gi`

have been used to deal with the more complicated groups of size up to 70, but these are not described here.)

Van Luyen Le has a more efficient algorithm, extending the data up to groups of size 171, which is expected to appear in a future release of **HAP**.

gap> gp := SmallGroup( 102, 2 ); <pc group of size 102 with 3 generators> gap> StructureDescription( gp ); "C3 x D34" gap> all := AllCat1DataGroupsBasic( gp ); #I Edit last line of .../xmod/lib/nn.kk.out to end with ] ] ] ] ] [ [Group( [ f1, f2, f3 ] )=>Group( [ f1, <identity> of ..., <identity> of ... ] )], [Group( [ f1, f2, f3 ] )=>Group( [ f1, f2, <identity> of ... ] )], [Group( [ f1, f2, f3 ] )=>Group( [ f1, <identity> of ..., f3 ] )], [Group( [ f1, f2, f3 ] )=>Group( [ f1, f2, f3 ] )] ]

Chapter 4 contains functions for quotient crossed modules; centre of a crossed module; commutator and derived subcrossed modules; etc.

Here we mention two functions for groups which have been extended to the two-dimensional case.

`‣ IdGroup` ( 2DimensionalGroup ) | ( operation ) |

`‣ StructureDescription` ( 2DimensionalGroup ) | ( operation ) |

These functions return two-element lists formed by applying the function to the source and range of the 2d-group.

gap> IdGroup( X2 ); [ [ 24, 6 ], [ 12, 4 ] ] gap> StructureDescription( C2 ); [ "(S3 x D24) : C2", "D12" ]

A *group groupoid* is an algebraic object which is both a groupoid and a group. The category of group groupoids is equivalent to the categories of precrossed modules and precat^1-groups. Starting with a (pre)cat^1-group calC = (e;t,h : G -> R), we form the groupoid calG having the elements of R as objects and the elements of G as arrows. The arrow g has tail tg and head hg. calG has one connected component for each coset of tG in R.

The groupoid (partial) multiplication * on these arrows is defined by:

(g_1 : r_1 \to r_2) * (g_2 : r_2 \to r_3) ~=~ (g_1(er_2^{-1})g_2 : r_1 \to r_3).

`‣ GroupGroupoid` ( precat1 ) | ( attribute ) |

The operation `GroupGroupoid`

implements this construction. In the example we start with a crossed module (C_3^2 -> S_3), form the associated cat^1-group (S_3 ⋉ C_3^2 ⇒ S_3), and then form the group groupoid `gpd33`

. Since the image of the boundary of the crossed module is C_3, with index 2 in the range, the groupoid has two connected components, and the root objects are {(),(12,13)}. The size of the vertex groups is |ker t ∩ ker h| = 3, and the generators at the root objects are () -> ( 4, 5, 6)( 7, 9, 8) -> () and (12,13) -> ( 2, 3)( 4, 6)( 7, 8) -> (12,13).

gap> s3 := Group( (11,12), (12,13) );; gap> c3c3 := Group( [ (14,15,16), (17,18,19) ] );; gap> bdy := GroupHomomorphismByImages( c3c3, s3, > [(14,15,16),(17,18,19)], [(11,12,13),(11,12,13)] );; gap> a := GroupHomomorphismByImages( c3c3, c3c3, > [(14,15,16),(17,18,19)], [(14,16,15),(17,19,18)] );; gap> aut := Group( [a] );; gap> act := GroupHomomorphismByImages( s3, aut, [(11,12),(12,13)], [a,a] );; gap> X33 := XModByBoundaryAndAction( bdy, act );; gap> C33 := Cat1GroupOfXMod( X33 ).precat1;; gap> G33 := Source( C33 );; gap> gpd33 := GroupGroupoid( C33 ); groupoid with 2 pieces: 1: single piece groupoid with rays: < Group( [ ()>-( 4, 5, 6)( 7, 9, 8)->() ] ), [ (), (11,12,13), (11,13,12) ], [ ()>-()->(), ()>-(7,8,9)->(11,12,13), ()>-(7,9,8)->(11,13,12) ] > 2: single piece groupoid with rays: < Group( [ (12,13)>-( 2, 3)( 4, 6)( 7, 8)->(12,13) ] ), [ (12,13), (11,12), (11,13) ], [ (12,13)>-(2,3)(5,6)(8,9)->(12,13), (12,13)>-(2,3)(5,6)(7,9)->(11,13), (12,13)>-(2,3)(5,6)(7,8)->(11,12) ] >

`‣ GroupGroupoidElement` ( precat1, root, g ) | ( operation ) |

Since we need to define a second multiplication on the elements of G, we have to convert g ∈ G into a new type of object, `GroupGroupoidElementType`

, a record e with fields:

`e!.precat1`

, the precat^1-group from which calG was formed;`e!.root`

, the root object of the component containing e;`e!.element`

, the element g ∈ G;`e!.tail`

, the tail object of the element e;`e!.head`

, the head object of the element e;`e!.tailid`

, the identity element at the tail object;`e!.headid`

, the identity element at the head object;

In the example we pick a particular pair of elements g_1,g_2 ∈ G, construct group groupoid elements e_1,e_2 from them, and show that g_1*g_2 and e_1*e_2 give very different results. (Warning: at present iterators for object groups and homsets do not work.)

gap> piece2 := Pieces( gpd33 )[2];; gap> obs2 := piece2!.objects; [ (12,13), (11,12), (11,13) ] gap> RaysOfGroupoid( piece2 ); [ (12,13)>-(2,3)(5,6)(8,9)->(12,13), (12,13)>-(2,3)(5,6)(7,9)->(11,13), (12,13)>-(2,3)(5,6)(7,8)->(11,12) ] gap> g1 := (1,2)(5,6)(7,9);; gap> g2 := (2,3)(4,5)(7,8);; gap> g1 * g2; (1,3,2)(4,5,6)(7,9,8) gap> e1 := GroupGroupoidElement( C33, (12,13), g1 ); (11,12)>-(1,2)(5,6)(7,9)->(12,13) gap> e2 := GroupGroupoidElement( C33, (12,13), g2 ); (12,13)>-(2,3)(4,5)(7,8)->(11,13) gap> e1*e2; (11,12)>-(1,2)(4,5)(8,9)->(11,13) gap> e2^-1; (11,13)>-(1,3)(4,6)(7,9)->(12,13) gap> obgp := ObjectGroup( gpd33, (11,12) ); <group with 1 generators> gap> GeneratorsOfGroup( obgp )[1]; (11,13)>-( 1, 3)( 4, 6)( 7, 8)->(11,13) gap> Homset( gpd33, (11,12), (11,13) ); <homset (11,12) -> (11,13) with head group Group( [ (11,12)>-( 1, 2)( 4, 6)( 7, 8)->(11,12) ] )>

generated by GAPDoc2HTML