<!-- ------------------------------------------------------------------- -->
<!-- -->
<!-- double.xml xmod documentation Chris Wensley -->
<!-- -->
<!-- Copyright (C) 2023-2025, Chris Wensley, -->
<!-- -->
<!-- ------------------------------------------------------------------- -->
<?xml version="1.0" encoding="UTF-8"?>
<Chapter Label="chap-double">
<Heading>Double Groupoids</Heading>
A <E>double groupoid</E> is a <E>double category</E>
in which all the category structures are groupoids.
There is also a pre-crossed module associated to the double groupoid.
In a double groupoid, as well as objects and arrows we need a set of <E>squares</E>.
A square is bounded by four arrows, two horizontal and two vertical,
and there is a <E>horizontal</E> groupoid structure
and a <E>vertical</E> groupoid structure on these squares.
A square also contains an element of the source group of the
pre-crossed module, and its image under the boundary map
is equal to the boundary of the square.
When printing a square, this element is located at the centre,
<P/>
The double groupoids constructed here are special
in that all four arrows come from the same groupoid.
We call these <E>edge-symmetric</E> double groupoids.
<P/>
This material in this chapter is experimental.
It was started in 2023, in version 2.91,
and extensively revised in 2025, for version 2.95.
Further extensions are likely in due course.
<Section Label="sect-basic-double-groupoids">
<Heading>Constructions for Double Groupoids</Heading>
It is assumed in this chapter that the reader is familiar with constructions
for groupoids given in the <Package>Groupoids</Package> package,
such as <C>SinglePieceBasicDoubleGroupoid</C>.
Such groupoids are <E>basic</E>, in that there is no pre-crossed module
involvement.
In <Package>XMod</Package> the operation <C>SinglePieceDoubleGroupoid</C>
requires a groupoid and a crossed module as input parameters.
<ManSection>
<Oper Name="SinglePieceDoubleGroupoid"
Arg="gpd pxmod" />
<Description>
For an example we take for our groupoid the product of the group
<M>S_3 = \langle (7,8,9), (8,9) \rangle</M>
with the complete graph on <M>[-6 \ldots -1]</M>
and, for our pre-crossed module, the <C>X12</C>,
isomorphic to <M>(D_{12} \to S_3)</M>,
constructed using <Ref Oper="XModByCentralExtension"/>.
The source of <C>X12</C> has generating set
<M>\left\{ g = (11,12,13,14,15,16),~ h = (12,16)(13,15) \right\}</M>.
</Description>
</ManSection>
<Example>
<![CDATA[
gap> gens3 := [ (7,8,9), (8,9) ];;
gap> s3 := Group( gens3 );;
gap> SetName( s3, "s3" );
gap> Gs3 := Groupoid( s3, [-6..-1] );;
gap> SetName( Gs3, "Gs3" );
gap> g := (11,12,13,14,15,16);; h := (12,16)(13,15);;
gap> gend12 := [ g, h ];;
gap> d12 := Group( gend12 );;
gap> SetName( d12, "d12" );
gap> pr12 := GroupHomomorphismByImages( d12, s3, gend12, gens3 );;
gap> X12 := XModByCentralExtension( pr12 );;
gap> SetName( X12, "X12" );
gap> Display( X12 );
Crossed module X12 :-
: Source group d12 has generators:
[ (11,12,13,14,15,16), (12,16)(13,15) ]
: Range group s3 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 --> [ (11,12,13,14,15,16), (11,13)(14,16) ] }
(8,9) --> { source gens --> [ (11,16,15,14,13,12), (12,16)(13,15) ] }
These 2 automorphisms generate the group of automorphisms.
gap> D1 := SinglePieceDoubleGroupoid( Gs3, X12 );;
gap> D1!.groupoid;
Gs3
gap> D1!.prexmod;
X12
]]>
</Example>
<ManSection>
<Oper Name="SquareOfArrows"
Arg="bdy act"/>
<Description>
Let <M>G</M> be a groupoid with object set <M>\Omega</M>
and object group <M>g</M>.
Let <M>\Box</M> be the set of squares with objects from <M>\Omega</M>
at each corner; plus two vertical arrows and two horizontal arrows from Arr<M>(G)</M>.
Further, let <M>\calP = (\partial : S \to R)</M> be a pre-crossed module,
and let <M>m_1 \in S</M> be placed at the centre of the square.
The following picture illustrates the situation where
<M>u_1,v_1,w_1,x_1 \in \Omega</M> and <M>a_1,b_1,c_1,d_1 \in g</M>.
<Display>
<!-- \label{square1} \def\labelstyle{\textstyle} -->
<![CDATA[
\vcenter{\xymatrix @=4pc{
u_1 \ar[r]^{a_1} \ar[d]_{b_1}\ar@{}[dr] |{m_1}
& v_1 \ar[d]^{c_1} \\
w_1 \ar[r]_{d_1}
& x_1
}}
]]>
</Display>
We think of the square being <E>based</E> at the bottom, right-hand corner,
<M>x_1</M>.
The <E>boundary</E> of the square is the loop
<M>(x_1, d_1^{-1}b_1^{-1}a_1c_1,x_1) = (x_1,p_1,x_1)</M>.
The <E>boundary condition</E> which <M>m_1</M> has to satisfy
is that <M>\partial m_1 = p_1</M>.
(Beware a possible source of confusion.
In the example code it is convenient of define arrow
<C>a1 := Arrow( Gs3, (7,8), -6, -5 );</C>
whereas, in the description, <M>a_1 = (7,8)</M>.
Similarly for all the other arrows.)
</Description>
</ManSection>
<Example>
<![CDATA[
gap> a1 := Arrow( Gs3, (7,8), -6, -5 );;
gap> b1 := Arrow( Gs3, (7,9), -6, -1 );;
gap> c1 := Arrow( Gs3, (8,9), -5, -3 );;
gap> d1 := Arrow( Gs3, (7,8,9), -1, -3 );;
gap> sq1 := SquareOfArrows( D1, g*h, a1, b1, c1, d1 );
[-6] ------------- (7,8) ------------> [-5]
| |
(7,9) (11,16)(12,15)(13,14) (8,9)
V V
[-1] ------------ (7,8,9) -----------> [-3]
gap> m1 := ElementOfSquare( sq1 );
(11,16)(12,15)(13,14)
gap> UpArrow( sq1 );
[(7,8) : -6 -> -5]
gap> LeftArrow( sq1 );
[(7,9) : -6 -> -1]
gap> RightArrow( sq1 );
[(8,9) : -5 -> -3]
gap> DownArrow( sq1 );
[(7,8,9) : -1 -> -3]
gap> ## check the boundary condition:
gap> bdy1 := Boundary( D1!.prexmod );;
gap> p1:= BoundaryOfSquare( sq1 );
[(7,9) : -3 -> -3]
gap> ImageElm( bdy1, m1 );
(7,9)
]]>
</Example>
<ManSection>
<Oper Name="HorizontalProduct"
Arg="sq1 sq2" />
<Description>
When defining a <E>horizontal composition</E>, as illustrated by
<Display>
<![CDATA[
\vcenter{\xymatrix @=4pc{
u_1 \ar[r]^{a_1} \ar[d]_{b_1} \ar@{}[dr]|{m_1}
& v_1 \ar[r]^{a_2} \ar[d]^{c_1} \ar@{}[dr]|{m_2}
& v_2 \ar[d]^{c_2} \ar@{}[dr]|=
& u_1 \ar[r]^{a_1a_2} \ar[d]_{b_1} \ar@{}[dr]|{m_1^{d_2}m_2}
& v_2 \ar[d]^{c_2} \\
w_1 \ar[r]_{d_1}
& x_1 \ar[r]_{d_2}
& x_2
& w_1 \ar[r]_{d_1d_2}
& x_2
}}
]]>
</Display>
we have to move <M>m_1</M>, based at <M>x_1</M>, to the new base <M>x_2</M>,
and we do this by using the action of the pre-crossed module of
<M>d_2</M> on <M>m_1</M>.
Notice that the boundary condition for the product is satisfied,
since the first pre-crossed module axiom applies:
<Display>
\partial(m_1^{d_2}m_2)
~=~ \partial(m_1^{d_2}) (\partial m_2)
~=~ d_2^{-1}(d_1^{-1}b_1^{-1}a_1c_1)d_2(d_2^{-1}c_1^{-1}a_2c_2)
~=~ (d_1d_2)^{-1}b_1^{-1}(a_1a_2)c_2.
</Display>
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> a2 := Arrow( Gs3, (8,9), -5, -4 );;
gap> c2 := Arrow( Gs3, (7,8), -4, -4 );;
gap> d2 := Arrow( Gs3, (7,9), -3, -4 );;
gap> sq2 := SquareOfArrows( D1, g^2, a2, c1, c2, d2 );
[-5] ------------ (8,9) -----------> [-4]
| |
(8,9) (11,13,15)(12,14,16) (7,8)
V V
[-3] ------------ (7,9) -----------> [-4]
gap> m2 := ElementOfSquare( sq2 );
(11,13,15)(12,14,16)
gap> LeftArrow( sq2 ) = RightArrow( sq1 );
true
gap> sq12 := HorizontalProduct( sq1, sq2 );
[-6] ------------ (7,9,8) -----------> [-4]
| |
(7,9) (11,12)(13,16)(14,15) (7,8)
V V
[-1] ------------- (7,8) ------------> [-4]
gap> ## check the boundary condition:
gap> ed2 := ElementOfArrow( d2 );;
gap> im1d2 := ImageElmXModAction( X12, m1, ed2 );
(11,16)(12,15)(13,14)
gap> m12 := ElementOfSquare( sq12 );
(11,12)(13,16)(14,15)
gap> im1d2 * m2 = m12;
true
]]>
</Example>
<ManSection>
<Oper Name="VerticalProduct"
Arg="sq1 sq2" />
<Description>
Similarly, vertical composition is illustrated by
<Display>
<![CDATA[
\vcenter{\xymatrix @=2pc{
u_1 \ar[rr]^{a_1} \ar[dd]_{b_1} \ar@{}[ddrr]|{m_1}
&& v_1 \ar[dd]^{c_1}
& & && \\
&& & & u_1 \ar[rr]^{a_1} \ar[dd]_{b_1b_3} \ar@{}[ddrr]|{m_3m_1^{c_3}}
&& v_1 \ar[dd]^{c_1c_3} \\
w_1 \ar[rr]_{d_1} \ar[dd]_{b_3} \ar@{}[ddrr]|{m_3}
&& x_1 \ar[dd]^{c_3}
&=& && \\
&& & & w_3 \ar[rr]_{d_3}
&& x_3 \\
w_3 \ar[rr]_{d_3}
&& x_3
}}
]]>
</Display>
<P/>
Again the boundary condition is satisfied:
<Display>
\partial(m_3m_1^{c_3})
~=~ (\partial m_3) \partial(m_1^{c_3})
~=~ (d_3^{-1}b_3^{-1}d_1c_3)c_3^{-1}(d_1^{-1}b_1^{-1}a_1c_1)c_3
~=~ d_3^{-1}(b_1b_3)^{-1}a_1(c_1c_3).
</Display>
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> b3 := Arrow( Gs3, (8,9), -1, -2 );;
gap> c3 := Arrow( Gs3, (7,9,8), -3, -2 );;
gap> d3 := Arrow( Gs3, (7,9), -2, -2 );;
gap> sq3 := SquareOfArrows( D1, g, d1, b3, c3, d3 );
[-1] ------------ (7,8,9) -----------> [-3]
| |
(8,9) (11,12,13,14,15,16) (7,9,8)
V V
[-2] ------------- (7,9) ------------> [-2]
gap> m3 := ElementOfSquare( sq3 );
(11,12,13,14,15,16)
gap> UpArrow( sq3 ) = DownArrow( sq1 );
true
gap> sq13 := VerticalProduct( sq1, sq3 );
[-6] ---------- (7,8) ---------> [-5]
| |
(7,8,9) (11,13)(14,16) (7,9)
V V
[-2] ---------- (7,9) ---------> [-2]
gap> ## check the boundary condition:
gap> ec3 := ElementOfArrow( c3 );;
gap> im1c3 := ImageElmXModAction( X12, m1, ec3 );
(11,14)(12,13)(15,16)
gap> m13 := ElementOfSquare( sq13 );
(11,13)(14,16)
gap> m3 * im1c3 = m13;
true
]]>
</Example>
The <C>HorizontalProduct</C> and <C>VerticalProduct</C> commute,
so we may construct products such as:
<Display>
<![CDATA[
\vcenter{\xymatrix @=2pc{
u_1 \ar[rr]^{a_1} \ar[dd]_{b_1} \ar@{}[ddrr]|{m_1}
&& v_1 \ar[rr]^{a_2} \ar[dd]|{c_1} \ar@{}[ddrr]|{m_2}
&& v_2 \ar[dd]^{c_2}
& & &&& \\
&& && & & u_1 \ar[rrr]^{a_1a_2} \ar[dd]_{b_1b_3}
\ar@{}[ddrrr]|{m_3^{d_4}m_4\left(m_1^{d_2}m_2\right)^{c_4}}
&&& v_2 \ar[dd]^{c_1c_4} \\
w_1 \ar[rr]|{d_1} \ar[dd]_{b_3} \ar@{}[ddrr]|{m_3}
&& x_1 \ar[rr]|{d_2} \ar[dd]|{c_3} \ar@{}[ddrr]|{m_4}
&& x_2 \ar[dd]^{c_4}
&=& &&& \\
&& && & & w_3 \ar[rrr]_{d_3d_4}
&&& x_4 \\
w_3 \ar[rr]_{d_3}
&& x_3 \ar[rr]_{d_4}
&& x_4
}}
]]>
</Display>
where
<Display>
m_3^{d_4}m_4 (m_1^{d_2}m_2)^{c_4}
~=~ (m_3m_1^{c_3})^{d_4} m_4m_2^{c_4}
~=~ (d_3d_4)^{-1}(b_1b_3)^{-1}(a_1a_2)(c_3c_4).
</Display>
<P/>
Continuing with our example, we check that the two ways of computing
the product of four squares below agree.
<Display>
<![CDATA[
\vcenter{\xymatrix @=2pc{
-6 \ar[rr]^{(7,8)} \ar[dd]_{(7,9)} \ar@{}[ddrr]|{gh}
&& -5 \ar[rr]^{(8,9)} \ar[dd]|{(8,9)} \ar@{}[ddrr]|{g^2}
&& -4 \ar[dd]^{(7,8)}
& & &&& \\
&& && & & -6 \ar[rrr]^{(7,9,8)} \ar[dd]_{(7,8,9)}
\ar@{}[ddrrr]|{(11,15,13)(12,16,14)}
&&& -4 \ar[dd]^{(7,9,8)} \\
-1 \ar[rr]|{(7,8,9)} \ar[dd]_{(8,9)} \ar@{}[ddrr]|{g}
&& -3 \ar[rr]|{(7,9)} \ar[dd]|{(7,9,8)} \ar@{}[ddrr]|{h}
&& -4 \ar[dd]^{(8,9)}
&=& &&& \\
&& && & & -2 \ar[rrr]_{(7,9,8)}
&&& -3 \\
-2 \ar[rr]_{(7,9)}
&& -2 \ar[rr]_{(7,8)}
&& -3
}}
]]>
</Display>
<Example>
<![CDATA[
gap> c4 := Arrow( Gs3, (8,9), -4, -3 );;
gap> d4 := Arrow( Gs3, (7,8), -2, -3 );;
gap> sq4 := SquareOfArrows( D1, h, d2, c3, c4, d4 );;
gap> UpArrow(sq4)=DownArrow(sq2) and LeftArrow(sq4)=RightArrow(sq3);
true
gap> sq24 := VerticalProduct( sq2, sq4 );
[-5] ---------- (8,9) ---------> [-4]
| |
(7,9) (11,15)(12,14) (7,9,8)
V V
[-2] ---------- (7,8) ---------> [-3]
gap> sq34 := HorizontalProduct( sq3, sq4 );
[-1] ------------- (7,8) ------------> [-4]
| |
(8,9) (11,12)(13,16)(14,15) (8,9)
V V
[-2] ------------ (7,9,8) -----------> [-3]
gap> sq1324 := HorizontalProduct( sq13, sq24 );
[-6] ------------- (7,9,8) ------------> [-4]
| |
(7,8,9) (11,15,13)(12,16,14) (7,9,8)
V V
[-2] ------------- (7,9,8) ------------> [-3]
gap> sq1234 := VerticalProduct( sq12, sq34 );;
gap> sq1324 = sq1234;
true
]]>
</Example>
</Section>
<Section Label="sec-basic-dgpds">
<Heading>Conversion of Basic Double Groupoids</Heading>
As mentioned earlier,
double groupoids were introduced in the <Package>Groupoids</Package> package,
but these were <E>basic double groupoids</E>, without any pre-crossed module.
The element of a square was simply its boundary.
Here we introduce an operation which converts such a basic double groupoid
into the more general case considered in this package.
<ManSection>
<Oper Name="EnhancedBasicDoubleGroupoid"
Arg="bdg" />
<Description>
We need to add a pre-crossed module to the definition of a basic
double groupoid.
We choose to add <M>(G \to G)</M> where <M>G</M> is the root group of the
underlying groupoid.
(This is only valid for groupoids which are the direct product
with a complete graph.)
The example is taken from section 7.1 of the
<Package>Groupoids</Package> package,
converting basic <C>B0</C> to <C>D0</C>,
and we check that the same square is produced in each case.
</Description>
</ManSection>
<Example>
<![CDATA[
gap> g2 := (1,2,3,4);; h2 := (1,3);;
gap> gend8 := [ g2, h2 ];;
gap> d8 := Group( gend8 );;
gap> SetName( d8, "d8" );
gap> Gd8 := Groupoid( d8, [-9..-7] );;
gap> SetName( Gd8, "Gd8" );
gap> B0 := SinglePieceBasicDoubleGroupoid( Gd8 );;
gap> B0!.groupoid;
Gd8
gap> B0!.objects;
[ -9 .. -7 ]
gap> a0 := Arrow(Gd8,(),-9,-7);; b0 := Arrow(Gd8,g2,-9,-9);;
gap> c0 := Arrow(Gd8,h2,-7,-8);; d0 := Arrow(Gd8,(2,4),-9,-8);;
gap> bdy0 := d0![2]^-1 * b0![2]^-1 * a0![2] * c0![2];;
gap> bsq0 := SquareOfArrows( B0, bdy0, a0, b0, c0, d0 );
[-9] ---------- () ---------> [-7]
| |
(1,2,3,4) (1,4,3,2) (1,3)
V V
[-9] --------- (2,4) --------> [-8]
gap> D0 := EnhancedBasicDoubleGroupoid( B0 );;
gap> D0!.prexmod;
[d8->d8]
gap> bsq0 = SquareOfArrows( D0, bdy0, a0, b0, c0, d0 );
true
]]>
</Example>
</Section>
<Section Label="sec-commutative-dgpds">
<Heading>Commutative double groupoids</Heading>
A double groupoid square
<Display>
<!-- \label{square1} \def\labelstyle{\textstyle} -->
<![CDATA[
\vcenter{\xymatrix @=4pc{
u_1 \ar[r]^{a_1} \ar[d]_{b_1}\ar@{}[dr] |{m}
& v_1 \ar[d]^{c_1} \\
w_1 \ar[r]_{d_1}
& x_1
}}
]]>
</Display>
is <E>commutative</E> if <M>a_1c_1 = b_1d_1</M>,
which means that its boundary is the identity.
So a double groupoid which consists only of commutative squares
must have a pre-crossed module with zero boundary.
Commutative squares compose horizontally and vertically provided only
that they have the correct common arrow.
<ManSection>
<Oper Name="DoubleGroupoidWithZeroBoundary"
Arg="gpd src" />
<Description>
The data for a double groupoid of commutative squares therefore consists of
a groupoid and a source group.
We may use the operation <Ref Oper="PreXModWithTrivialRange"/>
to provide a pre-crossed module.
We take for our example the groupoid <C>Gd8</C> and the pre-crossed module
<C>Q16</C> of section <Ref Sect="sect-precrossed-modules"/>.
We introduce a new right arrow to construct a square which commutes.
</Description>
</ManSection>
<Example>
<![CDATA[
gap> D16 := DoubleGroupoidWithZeroBoundary( Gs3, d16 );;
gap> D16!.prexmod;
[d16->Group( [ () ] )]
gap> e16 := Arrow( Gs3, (7,9,8), -5, -3 );;
gap> sq16 := SquareOfArrows( D16, (12,18)(13,17)(14,16), a1, b1, e16, d1 );
[-6] -------------- (7,8) -------------> [-5]
| |
(7,9) (12,18)(13,17)(14,16) (7,9,8)
V V
[-1] ------------- (7,8,9) ------------> [-3]
]]>
</Example>
</Section>
</Chapter>
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|