<!-- ------------------------------------------------------------------- -->
<!--                                                                     -->
<!--  gpd.xml                Gpd documentation            Chris Wensley  -->
<!--                                                       & Emma Moore  -->
<!--                                                                     -->
<!--  $Id: gpd.xml,v 1.01 2006/06/01 gap Exp $                           -->
<!--                                                                     -->
<!-- ------------------------------------------------------------------- -->

<?xml version="1.0" encoding="ISO-8859-1"?>
  <!-- $Id: gpd.xml,v 1.01  Exp $ -->

<Chapter Label="chap-gpd">
<Heading>Groupoids</Heading>

A <E>groupoid</E> is a (mathematical) category in which every element
is invertible. 
It consists of a set of components, each of which is a connected groupoid.
<P/>
A <E>connected groupoid</E> is determined by a set of <E>objects</E> <C>obs</C>
and an <E>object group</E> <C>grp</C>. 
Connected groupoids are represented as <C>IsConnectedGroupoidRep</C>, 
a record with components <C>objects</C> and <C>group</C>.
The objects of a connected groupoid are generally chosen to be 
consecutive negative integers, but any suitable ordered set is acceptable, 
and `consecutive' is not a requirement.
The object groups will usually be taken to be permutation groups,
but pc-groups and fp-groups are also supported. 
<P/>
A <E>group</E> is a connected groupoid with one object.
<P/>
A <E>groupoid</E> is a set of one or more connected groupoids, 
its connected <E>components</E>, and is represented as <C>IsGroupoidRep</C>, 
with attribute <C>ComponentsOfGroupoid</C>.
<P/>
For the definitions of the standard properties of groupoids
we refer to R. Brown's book ``Topology'' <Cite Key="BrTop" />, 
recently revised and reissued as ``Topology and Groupoids'' 
<Cite Key="BrTopGpd" />.

<Section><Heading>Groupoids: their elements and attributes</Heading>

<ManSection>
   <Oper Name="ConnectedGroupoid"
         Arg="obs, grp" />
   <Oper Name="GroupAsGroupoid"
         Arg="obj, grp" />
   <Oper Name="GroupoidByUnion"
         Arg="comps" />
   <Func Name="Groupoid"
         Arg="args" />
<Description>
There are a variety of constructors for groupoids, with one or two parameters. 
The global function <C>Groupoid</C> will normally find the appropriate one 
to call, the options being:
<List>
<Item>
a list of objects, the object group;
</Item>
<Item>
a single object, a group being converted to a groupoid;
</Item>
<Item>
a list of groupoids which have already been constructed.
</Item>
</List>
<P/>
Methods for <C>ViewObj</C>, <C>PrintObj</C> and <C>Display</C> are
provided for groupoids and the other types of object in this package.
Users are advised to supply names for all the groups and groupoids 
they construct.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> d8 := Group( (1,2,3,4), (1,3) );;
gap> SetName( d8, "d8" );
gap> Gd8 := ConnectedGroupoid( [-9,-8,-7], d8 );
Perm Connected Groupoid:
< [ -9, -8, -7 ], d8 >
gap> c6 := Group( (5,6,7)(8,9) );;
gap> SetName( c6, "c6" );
gap> Gc6 := GroupAsGroupoid( -6, c6 );
Perm Connected Groupoid:
< [ -6 ], c6 >
gap> Gd8c6 := GroupoidByUnion( [ Gd8, Gc6 ] );;
gap> Display( Gd8c6 );
Perm Groupoid with 2 components:
< objects: [ -9, -8, -7 ]
    group: d8 = <[ (1,2,3,4), (1,3) ]> >
< objects: [ -6 ]
    group: c6 = <[ (5,6,7)(8,9) ]> >
gap> SetName( Gd8, "Gd8" );  SetName( Gc6, "Gc6" );  SetName( Gd8c6, "Gd8+Gc6" );
]]>
</Example>

<ManSection>
   <Attr Name="ComponentsOfGroupoid"
         Arg="gpd" />
   <Attr Name="ObjectsOfGroupoid"
         Arg="gpd" />
<Description>
When a groupoid consists of two or more components, 
we require their object lists to be disjoint. 
The components are sorted by the first object in their object lists, 
which must be disjoint. 
The list <C>ObjectsOfGroupoid</C> of a groupoid 
is the sorted concatenation of the objects in the components.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> ComponentsOfGroupoid( Gd8c6 );
[ Gd8, Gc6 ]
gap> ObjectsOfGroupoid( Gd8c6 );
[ -9, -8, -7, -6 ]
]]>
</Example>

<ManSection>
   <Prop Name="IsPermGroupoid"
         Arg="gpd" />
   <Prop Name="IsPcGroupoid"
         Arg="gpd" />
   <Prop Name="IsFpGroupoid"
         Arg="gpd" />
<Description>
A groupoid is a permutation groupoid if all its components have 
permutation groups.
Most of the examples in this chapter are permutation groupoids,
but in principle any type of group known to &GAP; may be used.
<P/>
In the following example <C>Gf2</C> is an fp-groupoid, 
while <C>Gq8</C> is a pc-groupoid.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> f2 := FreeGroup( 2 );;
gap> SetName( f2, "f2" );
gap> Gf2 := Groupoid( -22, f2 );;
gap> q8 := SmallGroup( 8, 4 );;
gap> Gq8 := Groupoid( [ -28, -27 ], q8 );;
gap> SetName( q8, "q8" );  SetName( Gq8, "Gq8" );
gap> Gf2q8 := Groupoid( [ Gf2, Gq8 ] );;
gap> [ IsFpGroupoid( Gf2 ), IsPcGroupoid( Gq8 ), IsPcGroupoid( Gf2q8 ) ];
[ true, true, false ]
gap> G4 := Groupoid( [ Gd8c6, Gf2, Gq8 ] );;
gap> Display( G4 );
Groupoid with 4 components:
< objects: [ -28, -27 ]
    group: q8 = <[ f1, f2, f3 ]> >
< objects: [ -22 ]
    group: f2 = <[ f1, f2 ]> >
< objects: [ -9, -8, -7 ]
    group: d8 = <[ (1,2,3,4), (1,3) ]> >
< objects: [ -6 ]
    group: c6 = <[ (5,6,7)(8,9) ]> >
gap> G4 = Groupoid( [ Gq8, Gf2, Gd8c6 ] );
true
]]>
</Example>

<ManSection>
   <Oper Name="GroupoidElement"
         Arg="gpd, elt, tail, head" />
   <Prop Name="IsElementOfGroupoid"
         Arg="elt" />
   <Attr Name="GroupElement"
         Arg="elt" />
   <Attr Name="Tail"
         Arg="elt" />
   <Attr Name="Head"
         Arg="elt" />
   <Attr Name="Size"
         Arg="gpd" />
<Description>
A <E>groupoid element</E> <C>e</C> is a triple consisting of 
a group element, <C>GroupElement(e)</C> or <C>e![1]</C>; 
the tail (source) object, <C>Tail(e)</C> or <C>e![2]</C>;
and the head (target) object, <C>Head(e)</C> or <C>e![3]</C>.
<P/>
The <C>Size</C> of a groupoid is the number of its elements which, 
for a connected groupoid, is the product of the size of the group 
with the square of the number of objects.
<P/>
Groupoid elements have a <E>partial composition</E>: 
two elements may be multiplied when the head of the first 
coincides with the tail of the second. 
Conjugate <M>a^b</M> is defined when <M>a</M> is a loop 
at the tail of <M>b</M>.
<P/>
</Description>
</ManSection>
<Index>*,\^{} for groupoid elements</Index>
<Example>
<![CDATA[
gap> e1 := GroupoidElement( Gd8, (1,2)(3,4), -9, -8 );
[(1,2)(3,4) : -9 -> -8]
gap> e2 := GroupoidElement( Gd8, (1,3), -8, -7 );;
gap> Print( [ GroupElement( e2 ), Tail( e2 ), Head( e2 ) ], "\n" );
[ (1,3), -8, -7 ]
gap> prod := e1*e2;
[(1,2,3,4) : -9 -> -7]
gap> e3 := GroupoidElement( Gd8, (1,3)(2,4), -7, -9 );;
gap> cycle := prod*e3;
[(1,4,3,2) : -9 -> -9]
gap> cycle^2;
[(1,3)(2,4) : -9 -> -9]
gap> Order( cycle );
4
gap> cycle^e1;
[(1,2,3,4) : -8 -> -8]
gap> [ Size( Gd8 ), Size( Gc6 ), Size( Gd8c6 ), Size( Gf2q8 ) ];
[ 72, 6, 78, infinity ]
]]>
</Example>

<ManSection>
   <Prop Name="IsConnectedGroupoid"
         Arg="gpd" />
   <Prop Name="IsDiscreteGroupoid"
         Arg="gpd" />
<Description>
The forgetful functor, which forgets the composition of elements, 
maps the category of groupoids and their morphisms 
to the category of digraphs and their morphisms. 
Applying this functor to a particular groupoid gives the 
<E>underlying digraph</E> of the groupoid.
A groupoid is <E>connected</E> if its underlying digraph 
is connected (and so complete). 
A groupoid is <E>discrete</E> if it is a union of groups, 
so that all the arcs in its underlying digraph are loops. 
It is sometimes convenient to call a groupoid element a <E>loop</E> 
when its tail and head are the same object.
<P/>
</Description>
</ManSection>
</Section>



<Section><Heading>Subgroupoids</Heading>

<ManSection>
   <Oper Name="SubgroupoidByComponents"
         Arg="gpd, obhoms" />
   <Func Name="Subgroupoid"
         Arg="args" />
   <Oper Name="FullSubgroupoid"
         Arg="gpd, obs" />
   <Attr Name="MaximalDiscreteSubgroupoid"
         Arg="gpd" />
   <Oper Name="DiscreteSubgroupoid"
         Arg="gpd, obs, sgps" />
   <Attr Name="FullIdentitySubgroupoid"
         Arg="gpd" />
   <Attr Name="DiscreteIdentitySubgroupoid"
         Arg="gpd" />
<Description>
A <E>subgroupoid</E> <C>sgpd</C> of <C>gpd</C> has as objects 
a subset of the objects of <C>gpd</C>.
It is <E>wide</E> if all the objects are included.
It is <E>full</E> if, for any two objects in <C>sgpd</C>, 
the <C>Homset</C> is the same as in <C>gpd</C>.
The elements of <C>sgpd</C> are a subset of those of <C>gpd</C>,
closed under multiplication and
with tail and head in the chosen object set.
<P/>
There are a variety of constructors for a subgroupoid of a groupoid.
The operation <C>SubgroupoidByComponents</C> is the most general. 
Its two parameters are a groupoid and a list of connected components, 
where each component is specified as a list <C>[obs,sgp]</C>,  
<C>obs</C> is a subset of the objects in one of the components of <C>gpd</C>, 
and <C>sgp</C> is a subgroup of the group in that component.
<P/>
The <C>FullSubgroupoid</C> of a groupoid <C>gpd</C> 
on a subset <C>obs</C> of its objects 
contains all the elements of <C>gpd</C> with tail and head in <C>obs</C>.
<P/>
A subgroupoid is <E>discrete</E> if it is a union of groups. 
The <C>MaximalDiscreteSubgroupoid</C> of <C>gpd</C> 
is the union of all the single-object full subgroupoids of <C>gpd</C>.
<P/>
An <E>identity subgroupoid</E> has trivial object groups, 
but need not be discrete.
A connected identity groupoid is sometimes called a <E>tree groupoid</E>.
<P/>
The global function <C>Subgroupoid</C> should call the appropriate operation.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> c4d := Subgroup( d8, [ (1,2,3,4) ] );;
gap> k4d := Subgroup( d8, [ (1,2)(3,4), (1,3)(2,4) ] );;
gap> SetName( c4d, "c4d" );  SetName( k4d, "k4d" );
gap> Ud8 := Subgroupoid( Gd8, [ [[-9, k4d]], [[-8,-7], c4d] ] );;
gap> SetName( Ud8, "Ud8" );
gap> Display( Ud8 );
Perm Groupoid with 2 components:
< objects: [ -9 ]
    group: k4d = <[ (1,2)(3,4), (1,3)(2,4) ]> >
< objects: [ -8, -7 ]
    group: c4d = <[ (1,2,3,4) ]> >
gap> FullSubgroupoid( Gd8c6, [-7,-6] );
Perm Groupoid with components:
< [ -7 ], d8 >
< [ -6 ], c6 >
gap> DiscreteSubgroupoid( Gd8c6, [-9,-8], [ c4d, k4d ] );
Perm Groupoid with components:
< [ -9 ], c4d >
< [ -8 ], k4d >
gap> FullIdentitySubgroupoid( Ud8 );
Perm Groupoid with components:
< [ -9 ], id(k4d) >
< [ -8, -7 ], id(c4d) >
]]>
</Example>
</Section>



<Section><Heading>Stars, Costars and Homsets</Heading>

<ManSection>
   <Oper Name="ObjectStar"
         Arg="gpd, obj" />
   <Oper Name="ObjectCostar"
         Arg="gpd, obj" />
   <Oper Name="Homset"
         Arg="gpd, tail, head" />
<Description>
The <E>star</E> at <C>obj</C> is the set of groupoid elements 
which have <C>obj</C> as tail,
while the <E>costar</E> is the set of elements which have <C>obj</C> as head.
The <E>homset</E> from <C>obj1</C> to <C>obj2</C>
is the set of elements with the specified tail and head, 
and so is bijective with the elements of the group. 
Thus every star and every costar is a union of homsets. 
<P/>
In order not to create unneccessary long lists, 
these operations return objects of type <C>IsHomsetCosetsRep</C> 
for which an <C>Iterator</C> is provided. 
(An <C>Enumerator</C> is not yet implemented.)
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> star9 := ObjectStar( Gd8, -9 );
<star at [ -9 ] with group d8>
gap> for e in star9 do
>      if ( Order( e![1] ) = 2 ) then Print( e, "\n" ); fi;
>    od;
[(1,4,3,2) : -9 -> -9]
[(1,4,3,2) : -9 -> -8]
[(1,4,3,2) : -9 -> -7]
[(1,2,3,4) : -9 -> -9]
[(1,2,3,4) : -9 -> -8]
[(1,2,3,4) : -9 -> -7]
gap> costar6 := ObjectCostar( Gc6, -6 );
<costar at [ -6 ] with group c6>
gap> hset78 := Homset( Ud8, -7, -8 );
<homset -7 -> -8 with group c4d>
gap> for e in hset78 do  Print( e, "\n" );  od;
[() : -7 -> -8]
[(1,3)(2,4) : -7 -> -8]
[(1,4,3,2) : -7 -> -8]
[(1,2,3,4) : -7 -> -8]
]]>
</Example>

<ManSection>
   <Oper Name="IdentityElement"
         Arg="gpd, obj" />
<Description>
The identity groupoid element <C>1\_{o}</C> of <C>gpd</C> at object <C>o</C> 
is <C>[e,o,o]</C> where <C>e</C> is the identity group element in the 
object group.  
It is a left identity for the star 
and a right identity for the costar at that object.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> i7 := IdentityElement( Gd8, -7 );;
gap> i8 := IdentityElement( Gd8, -8 );;
gap> L := [ i7, i8 ];;
gap> for e in hset78 do  Add( L, i7*e*i8 = e );  od;
gap> L;
[ [() : -7 -> -7], [() : -8 -> -8], true, true, true, true ]
]]>
</Example>
</Section>



<Section><Heading>Left, right and double cosets</Heading>

<ManSection>
   <Oper Name="RightCoset"
         Arg="G, U, elt" />
   <Oper Name="RightCosetRepresentatives"
         Arg="G, U" />
   <Oper Name="RightCosetsNC"
         Arg="G, U" />
   <Oper Name="LeftCoset"
         Arg="G, U, elt" />
   <Oper Name="LeftCosetRepresentatives"
         Arg="G, U" />
   <Oper Name="LeftCosetRepresentativesFromObject"
         Arg="G, U, obj" />
   <Oper Name="LeftCosetsNC"
         Arg="G, U" />
   <Oper Name="DoubleCoset"
         Arg="G, U, elt, V" />
   <Oper Name="DoubleCosetRepresentatives"
         Arg="G, U, V" />
   <Oper Name="DoubleCosetsNC"
         Arg="G, U, V" />
<Description>
If <C>U</C> is a wide subgroupoid of <M>G</M>, 
the <E>right cosets</E> of <M>U</M> in <M>G</M>
are the equivalence classes of the relation on the elements of <M>G</M>
where  <M>g1</M> is related to <M>g2</M> if and only if <M>g2 = u*g1</M>
for some element <M>u</M> of <M>U</M>.
The right coset containing <M>g</M> is written <M>Ug</M>.
These right cosets refine the costars of <M>G</M> and, 
in particular, <M>U1\_{o}</M> is the costar of <M>U</M> at <M>o</M>, 
so that (unlike groups) <M>U</M> is itself a coset only when 
<M>G</M> has a single object.
<P/>
The <E>right coset representatives</E> for <M>U</M> in <M>G</M> 
form a list containing one groupoid element for each coset where, 
in a particular component of <M>U</M>, 
the group element chosen is the right coset representative 
of the group of <M>U</M> in the group of <M>G</M>.
<P/>
Similarly, the <E>left cosets</E> <M>gU</M> refine the stars of <M>G</M>, 
while <E>double cosets</E> are unions of left cosets and of right cosets.
The operation <C>LeftCosetRepresentativesFromObject( G, U, obj )</C> 
is used in Chapter 4, 
and returns only those representatives which have tail at <C>obj</C>. 
<P/>
As with stars and homsets, these cosets are implemented with representation 
<C>IsHomsetCosetsRep</C> and provided with an iterator.
Note that, when <M>U</M> has more than one component, 
cosets may have differing lengths.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> re2 := RightCoset( Gd8, Ud8, e2 );
RightCoset(c4d,[(1,3) : -8 -> -7])
gap> for x in re2 do Print( x, "\n" ); od;
[(1,3) : -8 -> -8]
[(1,3) : -7 -> -8]
[(2,4) : -8 -> -8]
[(2,4) : -7 -> -8]
[(1,4)(2,3) : -8 -> -8]
[(1,4)(2,3) : -7 -> -8]
[(1,2)(3,4) : -8 -> -8]
[(1,2)(3,4) : -7 -> -8]
gap> rcrd8 := RightCosetRepresentatives( Gd8, Ud8 );
[ [() : -9 -> -9], [() : -9 -> -8], [() : -9 -> -7], [(2,4) : -9 -> -9],
  [(2,4) : -9 -> -8], [(2,4) : -9 -> -7], [() : -8 -> -9], [() : -8 -> -8],
  [() : -8 -> -7], [(2,4) : -8 -> -9], [(2,4) : -8 -> -8], [(2,4) : -8 -> -7]
 ]
gap> lcr7 := LeftCosetRepresentativesFromObject( Gd8, Ud8, -7 );
[ [() : -7 -> -9], [(2,4) : -7 -> -9], [() : -7 -> -8], [(2,4) : -7 -> -8] ]
]]>
</Example>
</Section>

More examples of these operations may be found in the example file 
<F>gpd/examples/gpd.g</F>.

</Chapter>
