% generated by GAPDoc2LaTeX from XML source (Frank Luebeck)
\documentclass[a4paper,11pt]{report}

\usepackage{a4wide}
\sloppy
\pagestyle{myheadings}
\usepackage{amssymb}
\usepackage[latin1]{inputenc}
\usepackage{makeidx}
\makeindex
\usepackage{color}
\definecolor{FireBrick}{rgb}{0.5812,0.0074,0.0083}
\definecolor{RoyalBlue}{rgb}{0.0236,0.0894,0.6179}
\definecolor{RoyalGreen}{rgb}{0.0236,0.6179,0.0894}
\definecolor{RoyalRed}{rgb}{0.6179,0.0236,0.0894}
\definecolor{LightBlue}{rgb}{0.8544,0.9511,1.0000}
\definecolor{Black}{rgb}{0.0,0.0,0.0}

\definecolor{linkColor}{rgb}{0.0,0.0,0.554}
\definecolor{citeColor}{rgb}{0.0,0.0,0.554}
\definecolor{fileColor}{rgb}{0.0,0.0,0.554}
\definecolor{urlColor}{rgb}{0.0,0.0,0.554}
\definecolor{promptColor}{rgb}{0.0,0.0,0.589}
\definecolor{brkpromptColor}{rgb}{0.589,0.0,0.0}
\definecolor{gapinputColor}{rgb}{0.589,0.0,0.0}
\definecolor{gapoutputColor}{rgb}{0.0,0.0,0.0}

%%  for a long time these were red and blue by default,
%%  now black, but keep variables to overwrite
\definecolor{FuncColor}{rgb}{0.0,0.0,0.0}
%% strange name because of pdflatex bug:
\definecolor{Chapter }{rgb}{0.0,0.0,0.0}
\definecolor{DarkOlive}{rgb}{0.1047,0.2412,0.0064}


\usepackage{fancyvrb}

\usepackage{mathptmx,helvet}
\usepackage[T1]{fontenc}
\usepackage{textcomp}


\usepackage[
            pdftex=true,
            bookmarks=true,        
            a4paper=true,
            pdftitle={Written with GAPDoc},
            pdfcreator={LaTeX with hyperref package / GAPDoc},
            colorlinks=true,
            backref=page,
            breaklinks=true,
            linkcolor=linkColor,
            citecolor=citeColor,
            filecolor=fileColor,
            urlcolor=urlColor,
            pdfpagemode={UseNone}, 
           ]{hyperref}

\newcommand{\maintitlesize}{\fontsize{50}{55}\selectfont}

% write page numbers to a .pnr log file for online help
\newwrite\pagenrlog
\immediate\openout\pagenrlog =\jobname.pnr
\immediate\write\pagenrlog{PAGENRS := [}
\newcommand{\logpage}[1]{\protect\write\pagenrlog{#1, \thepage,}}
%% were never documented, give conflicts with some additional packages

\newcommand{\GAP}{\textsf{GAP}}

%% nicer description environments, allows long labels
\usepackage{enumitem}
\setdescription{style=nextline}

%% depth of toc
\setcounter{tocdepth}{1}





%% command for ColorPrompt style examples
\newcommand{\gapprompt}[1]{\color{promptColor}{\bfseries #1}}
\newcommand{\gapbrkprompt}[1]{\color{brkpromptColor}{\bfseries #1}}
\newcommand{\gapinput}[1]{\color{gapinputColor}{#1}}


\begin{document}

\logpage{[ 0, 0, 0 ]}
\begin{titlepage}
\mbox{}\vfill

\begin{center}{\maintitlesize \textbf{\textsf{Gpd}\mbox{}}}\\
\vfill

\hypersetup{pdftitle=\textsf{Gpd}}
\markright{\scriptsize \mbox{}\hfill \textsf{Gpd} \hfill\mbox{}}
{\Huge \textbf{Groupoids, graphs of groups, and graphs of groupoids\mbox{}}}\\
\vfill

{\Huge Version 1.34\mbox{}}\\[1cm]
{05/06/2015\mbox{}}\\[1cm]
\mbox{}\\[2cm]
{\Large \textbf{ Emma Moore \mbox{}}}\\
{\Large \textbf{ Chris Wensley    \mbox{}}}\\
\hypersetup{pdfauthor= Emma Moore ;  Chris Wensley    }
\end{center}\vfill

\mbox{}\\
{\mbox{}\\
\small \noindent \textbf{ Chris Wensley    }  Email: \href{mailto://c.d.wensley@bangor.ac.uk} {\texttt{c.d.wensley@bangor.ac.uk}}\\
  Homepage: \href{http://pages.bangor.ac.uk/~mas023/} {\texttt{http://pages.bangor.ac.uk/\texttt{\symbol{126}}mas023/}}\\
  Address: \begin{minipage}[t]{8cm}\noindent
 School of Computer Science, Bangor University,\\
 Dean Street, Bangor, Gwynedd, LL57 1UT, U.K. \end{minipage}
}\\
\end{titlepage}

\newpage\setcounter{page}{2}
{\small 
\section*{Abstract}
\logpage{[ 0, 0, 1 ]}
 The \textsf{Gpd} package for \textsf{GAP}4 provides functions for the computation with groupoids (categories with every
arrow invertible) and their morphisms; for graphs of groups, and graphs of
groupoids. The most basic structure introduced is that of \emph{magma with objects}, followed by \emph{semigroup with objects}, then \emph{monoid with objects} and finally \emph{groupoid} which is a \emph{group with objects}. 

 It provides normal forms for Free Products with Amalgamation and for
HNN-extensions when the initial groups have rewrite systems and the subgroups
have finite index. 

 The \textsf{Gpd} package was originally implemented in 2000 (as \textsf{GraphGpd}) when the first author was studying for a Ph.D. in Bangor. 

 Version 1.07 was released in July 2011, to be tested with \textsf{GAP} 4.5. Version 1.15 came out with the first release of \textsf{GAP} 4.5 in June 2012, and was submitted for official acceptance as a \textsf{GAP} package. \textsf{Gpd} became an accepted \textsf{GAP} package in May 2015 (even though the referee's comments are still being
addressed). The latest version is 1.34 of 5th June 2015, prepared for \textsf{GAP} 4.7. 

 Recent versions implement many of the constructions described in the paper \cite{AlWe} for automorphisms of groupoids. 

 Bug reports, suggestions and comments are, of course, welcome. Please contact
the second author at \href{mailto://c.d.wensley@bangor.ac.uk} {\texttt{c.d.wensley@bangor.ac.uk}}. \mbox{}}\\[1cm]
{\small 
\section*{Copyright}
\logpage{[ 0, 0, 2 ]}
 \index{License} {\copyright} 2000-2015 Emma Moore and Chris Wensley 

 \textsf{Gpd} is free software; you can redistribute it and/or modify it under the terms of
the \href{http://www.fsf.org/licenses/gpl.html} {GNU General Public License} as published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version. \mbox{}}\\[1cm]
{\small 
\section*{Acknowledgements}
\logpage{[ 0, 0, 3 ]}
 This documentation was prepared with the \textsf{GAPDoc} package of Frank L{\"u}beck and Max Neunh{\"o}ffer. \mbox{}}\\[1cm]
\newpage

\def\contentsname{Contents\logpage{[ 0, 0, 4 ]}}

\tableofcontents
\newpage

                      
\chapter{\textcolor{Chapter }{Many-object structures}}\label{chap-mwp}
\logpage{[ 1, 0, 0 ]}
\hyperdef{L}{X8361CEA4856430C6}{}
{
  The aim of this package is to provide operations for finite groupoids. A \emph{groupoid} is constructed from a group and a set of objects. In order to provide a
sequence of categories, with increasing structure, mimicing those for groups,
we introduce in this chapter the notions of \emph{magma with objects}; \emph{semigroup with objects} and \emph{monoid with objects}. The next chapter introduces morphisms of these structures. At a first
reading of this manual, the user is advised to skip quickly through these
first two chapters, and then move on to groupoids in Chapter 3. 

 For the definitions of the standard properties of groupoids we refer to P.
Higgins' book ``Categories and Groupoids'' \cite{HiGpd} (originally published in 1971, reprinted by TAC in 2005), and to R. Brown's
book ``Topology'' \cite{BrTop}, recently revised and reissued as ``Topology and Groupoids'' \cite{BrTopGpd}. 
\section{\textcolor{Chapter }{Magmas with objects; arrows}}\label{sec-mwo}
\logpage{[ 1, 1, 0 ]}
\hyperdef{L}{X7920BF45828AE5DE}{}
{
  A \emph{magma with objects} $M$ consists of a set of \emph{objects} Ob$(M)$, and a set of \emph{arrows} Arr$(M)$ together with \emph{tail} and \emph{head} maps $t,h :$ Arr$(M) \to$ Ob$(M)$, and a \emph{partial multiplication} $* :$ Arr$(M) \to $ Arr$(M)$, with $a*b$ defined precisely when the head of $a$ coincides with the tail of $b$. We write an arrow $a$ with tail $u$ and head $v$ as $(a : u \to v)$. 

 When this multiplication is associative we obtain a \emph{semigroup with objects}. 

 A \emph{loop} is an arrow whose tail and head are the same object. An \emph{identity arrow} at object $u$ is a loop $(1_u : u \to u)$ such that $a*1_u=a$ and $1_u*b=b$ whenever $u$ is the head of $a$ and the tail of $b$. When $M$ is a semigroup with objects and every object has an identity arrow, we obtain
a \emph{monoid with objects}, which is just the usual notion of mathematical category. 

 An arrow $(a : u \to v)$ in a monoid with objects has \emph{inverse} $(a^{-1} : v \to u)$ provided $a*a^{-1} = 1_u$ and $a^{-1}*a = 1_v$. A monoid with objects in which every arrow has an inverse is a \emph{group with objects}, usually called a \emph{groupoid}. 

\subsection{\textcolor{Chapter }{MagmaWithObjects}}
\logpage{[ 1, 1, 1 ]}\nobreak
\hyperdef{L}{X7C51D7847BD23284}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{MagmaWithObjects({\mdseries\slshape args})\index{MagmaWithObjects@\texttt{MagmaWithObjects}}
\label{MagmaWithObjects}
}\hfill{\scriptsize (function)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SinglePieceMagmaWithObjects({\mdseries\slshape magma, obs})\index{SinglePieceMagmaWithObjects@\texttt{SinglePieceMagmaWithObjects}}
\label{SinglePieceMagmaWithObjects}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ObjectList({\mdseries\slshape mwo})\index{ObjectList@\texttt{ObjectList}}
\label{ObjectList}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RootObject({\mdseries\slshape mwo})\index{RootObject@\texttt{RootObject}}
\label{RootObject}
}\hfill{\scriptsize (operation)}}\\


 The simplest construction for a magma with objects $M$ is to take a magma $m$ and an ordered set $s$, and form arrows $(u,a,v)$ for every $a$ in $m$ and $u,v$ in $s$. Multiplication is defined by $(u,a,v)*(v,b,w) = (u,a*b,w)$. In this package we prefer to write $(u,a,v)$ as $(a : u \to v)$, so that the multiplication rule becomes $(a : u \to v)*(b : v \to w) = (a*b : u \to w)$. 

 Any finite, ordered set is in principle acceptable as the object list of $M$, but we find it convenient to restrict ourselves to sets of non-positive
integers. 

 This is the only construction implemented here for magmas, semigroups, and
monoids with objects, and these all have the property \texttt{IsDirectProductWithCompleteGraph}. There are other constructions implemented for groupoids. 

 The output from function \texttt{MagmaWithObjects} lies in the categories \index{IsDomainWithObjects@\texttt{IsDomainWithObjects}} \texttt{IsDomainWithObjects}, \index{IsMagmaWithObjects@\texttt{IsMagmaWithObjects}} \texttt{IsMagmaWithObjects}, \texttt{CategoryCollections(IsMultiplicativeElementWithObjects)} and \texttt{IsMagma}. The \emph{root object} of $M$ is the first element in $s$. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@tm := [[1,2,4,3],[1,2,4,3],[3,4,2,1],[3,4,2,1]];; |
  !gapprompt@gap>| !gapinput@Display( tm );|
  [ [  1,  2,  4,  3 ],
    [  1,  2,  4,  3 ],
    [  3,  4,  2,  1 ],
    [  3,  4,  2,  1 ] ]
  !gapprompt@gap>| !gapinput@m := MagmaByMultiplicationTable( tm );;  SetName( m, "m" );|
  !gapprompt@gap>| !gapinput@m1 := MagmaElement(m,1);;  m2 := MagmaElement(m,2);; |
  !gapprompt@gap>| !gapinput@m3 := MagmaElement(m,3);;  m4 := MagmaElement(m,4);; |
  !gapprompt@gap>| !gapinput@M78 := MagmaWithObjects( m, [-8,-7] ); |
  magma with objects :-
      magma = m
    objects = [ -8, -7 ]
  !gapprompt@gap>| !gapinput@SetName( M78, "M78" ); |
  !gapprompt@gap>| !gapinput@[ IsAssociative(M78), IsCommutative(M78), IsDomainWithObjects(M78) ]; |
  [ false, false, true ]
  !gapprompt@gap>| !gapinput@[ RootObject( M78 ), ObjectList( M78 ) ]; |
  [ -8, [ -8, -7 ] ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{Arrow}}
\logpage{[ 1, 1, 2 ]}\nobreak
\label{man-arrow}
\hyperdef{L}{X86247DFC8242CEBE}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Arrow({\mdseries\slshape mwo, elt, tail, head})\index{Arrow@\texttt{Arrow}}
\label{Arrow}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ElementOfArrow({\mdseries\slshape arr})\index{ElementOfArrow@\texttt{ElementOfArrow}}
\label{ElementOfArrow}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{TailOfArrow({\mdseries\slshape arr})\index{TailOfArrow@\texttt{TailOfArrow}}
\label{TailOfArrow}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HeadOfArrow({\mdseries\slshape arr})\index{HeadOfArrow@\texttt{HeadOfArrow}}
\label{HeadOfArrow}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsArrowIn({\mdseries\slshape arr, mwo})\index{IsArrowIn@\texttt{IsArrowIn}}
\label{IsArrowIn}
}\hfill{\scriptsize (operation)}}\\


 Arrows in a magma with objects lie in the category \index{IsMultiplicativeElementWithObjects@\texttt{IsMultiplicativeElementWithObjects}} \texttt{IsMultiplicativeElementWithObjects}. An attempt to multiply two arrows which do not compose resuts in \texttt{fail} being returned. Each arrow $arr = (a : u \to v)$ has three components. The magma \emph{element} $a \in m$ may be accessed by \texttt{ElementOfArrow(arr) = arr![1]}. Similarly, the \emph{tail} object $u$ and the \emph{head} object $v$ may be obtained using \texttt{TailOfArrow(arr) = arr![2]} and \texttt{HeadOfArrow(arr) = arr![3]} respectively. 

 The operation \texttt{IsArrowIn} is added due to difficulties found when attempting to write a method for \texttt{\texttt{\symbol{92}}in}. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@a78 := Arrow( M78, m2, -7, -8 ); |
  [m2 : -7 -> -8]
  !gapprompt@gap>| !gapinput@[ a78 in M78, IsArrowIn( a78, M78 ) ]; |
  [ false, true ]
  !gapprompt@gap>| !gapinput@b87 := Arrow( M78, m4, -8, -7 );;|
  !gapprompt@gap>| !gapinput@[ ElementOfArrow( b87 ), TailOfArrow( b87 ), HeadOfArrow( b87 ) ]; |
  [ m4, -8, -7 ]
  !gapprompt@gap>| !gapinput@ba := b87*a78;;  ab := a78*b87;;  [ ba, ab ];|
  [ [m4 : -8 -> -8], [m3 : -7 -> -7] ]
  !gapprompt@gap>| !gapinput@[ a78^2, ba^2, ba^3 ]; |
  [ fail, [m1 : -8 -> -8], [m3 : -8 -> -8] ]
  !gapprompt@gap>| !gapinput@## this demonstrates non-associativity:  |
  !gapprompt@gap>| !gapinput@[ a78*ba, ab*a78, a78*ba=ab*a78 ]; |
  [ [m3 : -7 -> -8], [m4 : -7 -> -8], false ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{IsSinglePiece}}
\logpage{[ 1, 1, 3 ]}\nobreak
\hyperdef{L}{X7C0911667FF90DB2}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsSinglePiece({\mdseries\slshape mwo})\index{IsSinglePiece@\texttt{IsSinglePiece}}
\label{IsSinglePiece}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsDirectProductWithCompleteGraph({\mdseries\slshape mwo})\index{IsDirectProductWithCompleteGraph@\texttt{IsDirectProductWithCompleteGraph}}
\label{IsDirectProductWithCompleteGraph}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsDiscrete({\mdseries\slshape mwo})\index{IsDiscrete@\texttt{IsDiscrete}}
\label{IsDiscrete}
}\hfill{\scriptsize (property)}}\\


 If the partial composition is forgotten, then what remains is a digraph
(usually with multiple edges and loops). Thus the notion of \emph{connected component} may be inherited by magmas with objects from digraphs. Unfortunately the terms \texttt{Component} and \texttt{Constituent} are already in considerable use elsewhere in \textsf{GAP}, so (and this may change if a more suitable word is suggested) we use the
term \texttt{IsSinglePiece} to describe a connected magma with objects. When each connected component has
a single object, and there is more than one component, the magma with objects
is \emph{discrete}. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@IsSinglePiece( M78 ); |
  true
  !gapprompt@gap>| !gapinput@IsDirectProductWithCompleteGraph( M78 );|
  true
  !gapprompt@gap>| !gapinput@IsDiscrete( M78 ); |
  false
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Semigroups with objects}}\label{sec-swo}
\logpage{[ 1, 2, 0 ]}
\hyperdef{L}{X7FDF94E8791B9BC1}{}
{
  

\subsection{\textcolor{Chapter }{SemigroupWithObjects}}
\logpage{[ 1, 2, 1 ]}\nobreak
\hyperdef{L}{X8519787D833653A7}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SemigroupWithObjects({\mdseries\slshape args})\index{SemigroupWithObjects@\texttt{SemigroupWithObjects}}
\label{SemigroupWithObjects}
}\hfill{\scriptsize (function)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SinglePieceSemigroupWithObjects({\mdseries\slshape sgp, obs})\index{SinglePieceSemigroupWithObjects@\texttt{SinglePieceSemigroupWithObjects}}
\label{SinglePieceSemigroupWithObjects}
}\hfill{\scriptsize (operation)}}\\


 When the magma is a semigroup the construction gives a \texttt{SinglePieceSemigroupWithObjects}. In the example we use a transformation semigroup and $3$ objects. 

 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@t := Transformation( [1,1,2,3] );;  s := Transformation( [2,2,3,3] );;|
  !gapprompt@gap>| !gapinput@r := Transformation( [2,3,4,4] );;  sgp := Semigroup( t, s, r );; |
  !gapprompt@gap>| !gapinput@SetName( sgp, "sgp<t,s,r>" ); |
  !gapprompt@gap>| !gapinput@S123 := SemigroupWithObjects( sgp, [-3,-2,-1] ); |
  semigroup with objects :-
      magma = sgp<t,s,r>
    objects = [ -3, -2, -1 ]
  !gapprompt@gap>| !gapinput@[ IsAssociative(S123), IsCommutative(S123) ];|
  [ true, false ]
  !gapprompt@gap>| !gapinput@t12 := Arrow( S123, t, -1, -2 );|
  [Transformation( [ 1, 1, 2, 3 ] ) : -1 -> -2]
  !gapprompt@gap>| !gapinput@s23 := Arrow( S123, s, -2, -3 );|
  [Transformation( [ 2, 2, 3, 3 ] ) : -2 -> -3]
  !gapprompt@gap>| !gapinput@r31 := Arrow( S123, r, -3, -1 );|
  [Transformation( [ 2, 3, 4, 4 ] ) : -3 -> -1]
  !gapprompt@gap>| !gapinput@ts13 := t12 * s23;|
  [Transformation( [ 2, 2, 2, 3 ] ) : -1 -> -3]
  !gapprompt@gap>| !gapinput@sr21 := s23 * r31;|
  [Transformation( [ 3, 3, 4, 4 ] ) : -2 -> -1]
  !gapprompt@gap>| !gapinput@rt32 := r31 * t12;|
  [Transformation( [ 1, 2, 3, 3 ] ) : -3 -> -2]
  !gapprompt@gap>| !gapinput@ tsr1 := ts13 * r31;|
  [Transformation( [ 3, 3, 3 ] ) : -1 -> -1]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Monoids with objects}}\label{monwo}
\logpage{[ 1, 3, 0 ]}
\hyperdef{L}{X86C32E6981557ED0}{}
{
  

\subsection{\textcolor{Chapter }{MonoidWithObjects}}
\logpage{[ 1, 3, 1 ]}\nobreak
\hyperdef{L}{X7A271B1A7F2FF245}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{MonoidWithObjects({\mdseries\slshape args})\index{MonoidWithObjects@\texttt{MonoidWithObjects}}
\label{MonoidWithObjects}
}\hfill{\scriptsize (function)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SinglePieceMonoidWithObjects({\mdseries\slshape mon, obs})\index{SinglePieceMonoidWithObjects@\texttt{SinglePieceMonoidWithObjects}}
\label{SinglePieceMonoidWithObjects}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GeneratorsOfMagmaWithObjects({\mdseries\slshape mwo})\index{GeneratorsOfMagmaWithObjects@\texttt{GeneratorsOfMagmaWithObjects}}
\label{GeneratorsOfMagmaWithObjects}
}\hfill{\scriptsize (operation)}}\\


 When the semigroup is a monoid the construction gives a \texttt{SinglePieceMonoidWithObjects}. The example uses a finitely presented monoid with $2$ generators and $2$ objects. 

 When the construction is the direct product of a monoid and the complete graph
on the objects, the generating set consists of two parts. Firstly, there is a
loop at the root object for each generator of the monoid. Secondly, for each
pair of objects $u,v$, there are arrows $(1 : u \to v)$ and $(1 : v \to u)$. 

 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@fm := FreeMonoid( 2, "f" );;|
  !gapprompt@gap>| !gapinput@em := One( fm );;|
  !gapprompt@gap>| !gapinput@gm := GeneratorsOfMonoid( fm );;|
  !gapprompt@gap>| !gapinput@mon := fm/[ [gm[1]^3,em], [gm[1]*gm[2],gm[2]] ];; |
  !gapprompt@gap>| !gapinput@M49 := MonoidWithObjects( mon, [-9,-4] ); |
  monoid with objects :-
      magma = Monoid( [ f1, f2 ] )
    objects = [ -9, -4 ]
  !gapprompt@gap>| !gapinput@ktpo := KnownTruePropertiesOfObject( M49 );|
  [ "CanEasilyCompareElements", "CanEasilySortElements", "IsDuplicateFree", 
    "IsAssociative", "IsSinglePieceDomain", 
    "IsDirectProductWithCompleteGraphDomain" ]
  !gapprompt@gap>| !gapinput@genM := GeneratorsOfMagmaWithObjects( M49 );|
  [ [<identity ...> : -9 -> -9], [f1 : -9 -> -9], [f2 : -9 -> -9],
    [<identity ...> : -9 -> -4], [<identity ...> : -4 -> -9] ]
  !gapprompt@gap>| !gapinput@g2:=genM[2];; g3:=genM[3];; g4:=genM[4];; g5:=genM[5];; |
  !gapprompt@gap>| !gapinput@[g5,g3,g2,g4];|
  [ [<identity ...> : -4 -> -9], [f2 : -9 -> -9], [f1 : -9 -> -9], 
    [<identity ...> : -9 -> -4] ]
  !gapprompt@gap>| !gapinput@g5*g3*g2*g4;|
  [f2*f1 : -4 -> -4]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Structures with one or more pieces}}\label{sec-pieces}
\logpage{[ 1, 4, 0 ]}
\hyperdef{L}{X87B3A56F8231D0F3}{}
{
  

\subsection{\textcolor{Chapter }{DomainWithSingleObject}}
\logpage{[ 1, 4, 1 ]}\nobreak
\hyperdef{L}{X788262F87EDA9816}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DomainWithSingleObject({\mdseries\slshape dom, obj})\index{DomainWithSingleObject@\texttt{DomainWithSingleObject}}
\label{DomainWithSingleObject}
}\hfill{\scriptsize (operation)}}\\


 A magma, semigroup, monoid, or group can be made into a magma with objects by
the addition of a single object. The two are algebraically isomorphic, and
there is one arrow (a loop) for each element in the group. In the example we
take the dihedral group of size $8$ at the object $0$. 

 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@d8 := Group( (1,2,3,4), (1,3) );;|
  !gapprompt@gap>| !gapinput@SetName( d8, "d8" );|
  !gapprompt@gap>| !gapinput@D0 := DomainWithSingleObject( d8, 0 );|
  single piece groupoid: < d8, [ 0 ] >
  !gapprompt@gap>| !gapinput@GeneratorsOfMagmaWithInverses( D0 );|
  [ [(1,2,3,4) : 0 -> 0], [(1,3) : 0 -> 0] ]
  !gapprompt@gap>| !gapinput@Size( D0 );|
  8
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{UnionOfPieces}}
\logpage{[ 1, 4, 2 ]}\nobreak
\hyperdef{L}{X79877FAA8556A726}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{UnionOfPieces({\mdseries\slshape pieces})\index{UnionOfPieces@\texttt{UnionOfPieces}}
\label{UnionOfPieces}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Pieces({\mdseries\slshape mwo})\index{Pieces@\texttt{Pieces}}
\label{Pieces}
}\hfill{\scriptsize (attribute)}}\\


 A magma with objects whose underlying digraph has two or more connected
components can be constructed by taking the union of two or more connected
structures. These, in turn, can be combined together. The only requirement is
that all the object lists should be disjoint. 

 Structures \texttt{S123, M49, D0} generated above have, respectively, \texttt{GeneratorsOfMagma}, \texttt{GeneratorsOfMagmaWithOne} and \texttt{GeneratorsOfMagmaWithInverses}. The generators of a structure with several pieces is the union of the
generators of the individual pieces. 

 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@N1 := UnionOfPieces( [ M78, S123 ] );;  ObjectList( N1 );|
  [ -8, -7, -3, -2, -1 ]
  !gapprompt@gap>| !gapinput@N2 := UnionOfPieces( [ M49, D0 ] );;  Pieces( N2 );|
  [ monoid with objects :-
          magma = Monoid( [ f1, f2 ] )
        objects = [ -9, -4 ]
      , single piece groupoid: < d8, [ 0 ] > ]
  !gapprompt@gap>| !gapinput@N3 := UnionOfPieces( [ N1, N2 ] );|
  magma with objects having 4 pieces :-
  1: monoid with objects :-
      magma = Monoid( [ f1, f2 ] )
    objects = [ -9, -4 ]
  2: M78
  3: semigroup with objects :-
      magma = sgp<t,s,r>
    objects = [ -3, -2, -1 ]
  4: single piece groupoid: < d8, [ 0 ] >
  !gapprompt@gap>| !gapinput@ObjectList( N3 ); |
  [ -9, -8, -7, -4, -3, -2, -1, 0 ]
  !gapprompt@gap>| !gapinput@Length( GeneratorsOfMagmaWithObjects( N3 ) ); |
  50
  !gapprompt@gap>| !gapinput@## the next command returns fail since the object sets are not disjoint: |
  !gapprompt@gap>| !gapinput@N4 := UnionOfPieces( [ S123, DomainWithSingleObject( d8, -2 ) ] );  |
  fail
  
\end{Verbatim}
 }

 }

            
\chapter{\textcolor{Chapter }{Homomorphisms of many-object structures}}\label{chap-homwo}
\logpage{[ 2, 0, 0 ]}
\hyperdef{L}{X85297B407ACAED81}{}
{
  A \emph{homomorphism} $f$ from a magma with objects $M$ to a magma with objects $N$ consists of 
\begin{itemize}
\item  a map $f_O$ from the objects of $M$ to those of $N$, 
\item  a map $f_A$ from the arrows of $M$ to those of $N$. 
\end{itemize}
 The map $f_A$ is required to be compatible with the tail and head maps and to preserve
multiplication: 
\[ f_A(a : u \to v) * f_A(b : v \to w) ~=~ f_A(a*b : u \to w) \]
 with tail $f_O(u)$ and head $f_O(w)$. 

 When $M$ is a monoid or group, the map $f_A$ is required to preserve object identities and inverses. 

 
\section{\textcolor{Chapter }{Homomorphisms of magmas with objects}}\label{sec-mwohom}
\logpage{[ 2, 1, 0 ]}
\hyperdef{L}{X82F856A086B93832}{}
{
  

\subsection{\textcolor{Chapter }{MagmaWithObjectsHomomorphism}}
\logpage{[ 2, 1, 1 ]}\nobreak
\hyperdef{L}{X86E00FEA7FF38FEA}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{MagmaWithObjectsHomomorphism({\mdseries\slshape args})\index{MagmaWithObjectsHomomorphism@\texttt{MagmaWithObjectsHomomorphism}}
\label{MagmaWithObjectsHomomorphism}
}\hfill{\scriptsize (function)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HomomorphismFromSinglePiece({\mdseries\slshape src, rng, hom, imobs})\index{HomomorphismFromSinglePiece@\texttt{HomomorphismFromSinglePiece}}
\label{HomomorphismFromSinglePiece}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HomomorphismToSinglePiece({\mdseries\slshape src, rng, images})\index{HomomorphismToSinglePiece@\texttt{HomomorphismToSinglePiece}}
\label{HomomorphismToSinglePiece}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{PieceImages({\mdseries\slshape mwohom})\index{PieceImages@\texttt{PieceImages}}
\label{PieceImages}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HomsOfMapping({\mdseries\slshape mwohom})\index{HomsOfMapping@\texttt{HomsOfMapping}}
\label{HomsOfMapping}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{PiecesOfMapping({\mdseries\slshape mwohom})\index{PiecesOfMapping@\texttt{PiecesOfMapping}}
\label{PiecesOfMapping}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsomorphismNewObjects({\mdseries\slshape src, objlist})\index{IsomorphismNewObjects@\texttt{IsomorphismNewObjects}}
\label{IsomorphismNewObjects}
}\hfill{\scriptsize (operation)}}\\


 There are a variety of homomorphism constructors. 

 The simplest construction gives a homomorphism $M \to N$ with both $M$ and $N$ connected. It is implemented as \index{IsMappingToSinglePieceRep@\texttt{IsMappingToSinglePieceRep}} \texttt{IsMappingToSinglePieceRep} with attributes \index{Source@\texttt{Source}} \texttt{Source}, \index{Range@\texttt{Range}} \texttt{Range} and \texttt{PieceImages}. The operation requires the following information: 
\begin{itemize}
\item  a magma homomorphism \texttt{f} from the underlying magma of $M$ to the underlying magma of $N$, 
\item  a list \texttt{imobs} of the images of the objects of $M$. 
\end{itemize}
 In the first example we construct endomappings of \texttt{m} and \texttt{M78}. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@tup1 := [Tuple([m1,m2]), Tuple([m2,m1]), Tuple([m3,m4]), Tuple([m4,m3])]; |
  !gapprompt@gap>| !gapinput@f1 := GeneralMappingByElements( m, m, tup1 ); |
  !gapprompt@gap>| !gapinput@IsMagmaHomomorphism( f1 ); |
  true
  !gapprompt@gap>| !gapinput@hom1 := MagmaWithObjectsHomomorphism( M78, M78, f1, [-8,-7] );; |
  !gapprompt@gap>| !gapinput@Display( hom1 );|
  homomorphism to single piece magma: M78 -> M78
  magma hom: <mapping: m -> m >, object map: [ -8, -7 ] -> [ -8, -7 ]
  !gapprompt@gap>| !gapinput@[ Source( hom1 ), Range( hom1 ) ]; |
  [ M78, M78 ]
  !gapprompt@gap>| !gapinput@b87;|
  [m4 : -8 -> -7]
  !gapprompt@gap>| !gapinput@im1 := ImageElm( hom1, b87 );|
  [m3 : -8 -> -7]
  !gapprompt@gap>| !gapinput@i56 := IsomorphismNewObjects( M78, [-5,-6] ); |
  magma with objects homomorphism : 
  [ [ IdentityMapping( m ), [ -5, -6 ] ] ]
  !gapprompt@gap>| !gapinput@M65 := Range( i56);; |
  !gapprompt@gap>| !gapinput@SetName( M65, "M65" ); |
  !gapprompt@gap>| !gapinput@j56 := InverseGeneralMapping( i56 );; |
  !gapprompt@gap>| !gapinput@ImagesOfObjects( j56 ); |
  [ -7, -8 ]
  !gapprompt@gap>| !gapinput@ib87 := ImageElm( i56, b87 );|
  [m4 : -5 -> -6]
  !gapprompt@gap>| !gapinput@comp := j56 * hom1;|
  magma with objects homomorphism : M65 -> M78
  [ [ <mapping: m -> m >, [ -7, -8 ] ] ]
  !gapprompt@gap>| !gapinput@ImageElm( comp, ib87 );|
  [m3 : -8 -> -7]
  
\end{Verbatim}
 A homomorphism \emph{to} a connected magma with objects may have a source with several pieces, and so
is a union of homomorphisms \emph{from} single pieces. 

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@M4 := UnionOfPieces( [ M78, M65 ] );;|
  !gapprompt@gap>| !gapinput@images := [ PieceImages( hom1 )[1], PieceImages( j56 )[1] ]; |
  [ [ <mapping: m -> m >, [ -8, -7 ] ], [ IdentityMapping( m ), [ -7, -8 ] ] ]
  !gapprompt@gap>| !gapinput@map4 := HomomorphismToSinglePiece( M4, M78, images ); |
  magma with objects homomorphism : 
  [ [ <mapping: m -> m >, [ -8, -7 ] ], [ IdentityMapping( m ), [ -7, -8 ] ] ]
  !gapprompt@gap>| !gapinput@ImageElm( map4, b87 );|
  [m3 : -8 -> -7]
  !gapprompt@gap>| !gapinput@ImageElm( map4, ib87 );|
  [m4 : -8 -> -7]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Homomorphisms of semigroups and monoids with objects}}\label{sec-sgphom}
\logpage{[ 2, 2, 0 ]}
\hyperdef{L}{X7C4D1AEE80D41A35}{}
{
  The next example exhibits a homomorphism between transformation semigroups
with objects. 

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@t2 := Transformation( [2,2,4,1] );; |
  !gapprompt@gap>| !gapinput@s2 := Transformation( [1,1,4,4] );;|
  !gapprompt@gap>| !gapinput@r2 := Transformation( [4,1,3,3] );; |
  !gapprompt@gap>| !gapinput@sgp2 := Semigroup( [ t2, s2, r2 ] );;|
  !gapprompt@gap>| !gapinput@SetName( sgp2, "sgp<t2,s2,r2>" );|
  !gapprompt@gap>| !gapinput@##  apparently no method for transformation semigroups available for: |
  !gapprompt@gap>| !gapinput@##  nat := NaturalHomomorphismByGenerators( sgp, sgp2 );  so we use: |
  !gapprompt@gap>| !gapinput@##  in the function flip below t is a transformation on [1..n] |
  !gapprompt@gap>| !gapinput@flip := function( t ) |
  !gapprompt@>| !gapinput@    local i, j, k, L, L2, n; |
  !gapprompt@>| !gapinput@    n := DegreeOfTransformation( t );  |
  !gapprompt@>| !gapinput@    L := ImageListOfTransformation( t ); |
  !gapprompt@>| !gapinput@    if IsOddInt(n) then n:=n+1; L1:=Concatenation(L,[n]); |
  !gapprompt@>| !gapinput@                   else L1:=L; fi; |
  !gapprompt@>| !gapinput@    L2 := ShallowCopy( L1 );|
  !gapprompt@>| !gapinput@    for i in [1..n] do |
  !gapprompt@>| !gapinput@        if IsOddInt(i) then j:=i+1; else j:=i-1; fi; |
  !gapprompt@>| !gapinput@        k := L1[j]; |
  !gapprompt@>| !gapinput@        if IsOddInt(k) then L2[i]:=k+1; else L2[i]:=k-1; fi; |
  !gapprompt@>| !gapinput@    od; |
  !gapprompt@>| !gapinput@    return( Transformation( L2 ) ); |
  !gapprompt@>| !gapinput@end;; |
  !gapprompt@gap>| !gapinput@smap := MappingByFunction( sgp, sgp2, flip );; |
  !gapprompt@gap>| !gapinput@ok := RespectsMultiplication( smap ); |
  true
  !gapprompt@gap>| !gapinput@[ t, Image( smap, t ) ]; |
  [ Transformation( [ 1, 1, 2, 3 ] ), Transformation( [ 2, 2, 4, 1 ] ) ]
  !gapprompt@gap>| !gapinput@[ s, Image( smap, s ) ]; |
  [ Transformation( [ 2, 2, 3, 3 ] ), Transformation( [ 1, 1, 4, 4 ] ) ]
  !gapprompt@gap>| !gapinput@[ r, Image( smap, r ) ]; |
  [ Transformation( [ 2, 3, 4, 4 ] ), Transformation( [ 4, 1, 3, 3 ] ) ]
  !gapprompt@gap>| !gapinput@SetName( smap, "smap" ); |
  !gapprompt@gap>| !gapinput@T123 := SemigroupWithObjects( sgp2, [-13,-12,-11] );; |
  !gapprompt@gap>| !gapinput@shom := MagmaWithObjectsHomomorphism( S123, T123, smap, [-11,-12,-13] );; |
  !gapprompt@gap>| !gapinput@it12 := ImageElm( shom, t12 );;  [ t12, it12 ]; |
  [ [Transformation( [ 1, 1, 2, 3 ] ) : -1 -> -2], 
    [Transformation( [ 2, 2, 4, 1 ] ) : -13 -> -12] ]
  !gapprompt@gap>| !gapinput@is23 := ImageElm( shom, s23 );;  [ s23, is23 ]; |
  [ [Transformation( [ 2, 2, 3, 3 ] ) : -2 -> -3], 
    [Transformation( [ 1, 1, 4, 4 ] ) : -12 -> -11] ]
  !gapprompt@gap>| !gapinput@ir31 := ImageElm( shom, r31 );;  [ r31, ir31 ]; |
  [ [Transformation( [ 2, 3, 4, 4 ] ) : -3 -> -1], 
    [Transformation( [ 4, 1, 3, 3 ] ) : -11 -> -13] ]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Homomorphisms to more than one piece}}\label{sec-hompieces}
\logpage{[ 2, 3, 0 ]}
\hyperdef{L}{X795C8DE37AED7B44}{}
{
  

\subsection{\textcolor{Chapter }{HomomorphismByUnion}}
\logpage{[ 2, 3, 1 ]}\nobreak
\hyperdef{L}{X86F313DB7EC4D9E7}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HomomorphismByUnion({\mdseries\slshape src, rng, homs})\index{HomomorphismByUnion@\texttt{HomomorphismByUnion}}
\label{HomomorphismByUnion}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsInjectiveOnObjects({\mdseries\slshape mwohom})\index{IsInjectiveOnObjects@\texttt{IsInjectiveOnObjects}}
\label{IsInjectiveOnObjects}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsSurjectiveOnObjects({\mdseries\slshape mwohom})\index{IsSurjectiveOnObjects@\texttt{IsSurjectiveOnObjects}}
\label{IsSurjectiveOnObjects}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsBijectiveOnObjects({\mdseries\slshape mwohom})\index{IsBijectiveOnObjects@\texttt{IsBijectiveOnObjects}}
\label{IsBijectiveOnObjects}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsEndomorphismWithObjects({\mdseries\slshape mwohom})\index{IsEndomorphismWithObjects@\texttt{IsEndomorphismWithObjects}}
\label{IsEndomorphismWithObjects}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsAutomorphismWithObjects({\mdseries\slshape mwohom})\index{IsAutomorphismWithObjects@\texttt{IsAutomorphismWithObjects}}
\label{IsAutomorphismWithObjects}
}\hfill{\scriptsize (property)}}\\


 When $f : M \to N$ and $N$ has more than one connected component, then $f$ is a union of homomorphisms, one for each piece in the range. }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@N4 := UnionOfPieces( [ M78, T123 ] );|
  magma with objects having 2 pieces :-
  1: semigroup with objects :-
      magma = sgp<t2,s2,r2>
    objects = [ -13, -12, -11 ]
  2: M78
  !gapprompt@gap>| !gapinput@h14 := HomomorphismByUnionNC( N1, N4, [ hom1, shom ] );|
  magma with objects homomorphism : 
  [ magma with objects homomorphism : M78 -> M78
      [ [ <mapping: m -> m >, [ -8, -7 ] ] ], magma with objects homomorphism : 
      [ [ smap, [ -11, -12, -13 ] ] ] ]
  !gapprompt@gap>| !gapinput@IsInjectiveOnObjects( h14 );|
  true
  !gapprompt@gap>| !gapinput@IsSurjectiveOnObjects( h14 );|
  true
  !gapprompt@gap>| !gapinput@IsBijectiveOnObjects( h14 ); |
  true
  !gapprompt@gap>| !gapinput@ImageElm( h14, t12 );|
  [Transformation( [ 2, 2, 4, 1 ] ) : -13 -> -12]
  !gapprompt@gap>| !gapinput@h45 := IsomorphismNewObjects( N4, [ [-103,-102,-101], [-108,-107] ] );|
  magma with objects homomorphism : 
  [ magma with objects homomorphism : 
      [ [ IdentityMapping( m ), [ -108, -107 ] ] ], 
    magma with objects homomorphism : 
      [ [ IdentityMapping( sgp<t2,s2,r2> ), [ -103, -102, -101 ] ] ] ]
  !gapprompt@gap>| !gapinput@N5 := Range( h45 );;  SetName( N5, "N5" ); |
  !gapprompt@gap>| !gapinput@h15 := h14 * h45;|
  magma with objects homomorphism : 
  [ magma with objects homomorphism : [ [ <mapping: m -> m >, [ -108, -107 ] ] ]
      , magma with objects homomorphism : [ [ smap, [ -101, -102, -103 ] ] ] ]
  !gapprompt@gap>| !gapinput@ImageElm( h15, t12 ); |
  [Transformation( [ 2, 2, 4, 1 ] ) : -103 -> -102]
  
\end{Verbatim}
 }

 }

            
\chapter{\textcolor{Chapter }{Groupoids}}\label{chap-gpd}
\logpage{[ 3, 0, 0 ]}
\hyperdef{L}{X82F6A1AB798648F4}{}
{
  A \emph{groupoid} is a (mathematical) category in which every element is invertible. It consists
of a set of \emph{pieces}, each of which is a connected groupoid. (The usual terminology is `connected
component', but in \textsf{GAP} `component' is used for `record component'.) 

 A \emph{single piece groupoid} is determined by a set of \emph{objects} \texttt{obs} and an \emph{object group} \texttt{grp}. The objects of a single piece 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. 

 A \emph{group} is a single piece groupoid with one object. 

 A \emph{groupoid} is a set of one or more single piece groupoids, its \emph{pieces}, and is represented as \texttt{IsGroupoidRep}, with attribute \texttt{PiecesOfGroupoid}. 

 A groupoid is \emph{homogeneous} if it has two of more isomorphic pieces, with identical groups. The special
case of \emph{homogeneous, discrete} groupoids, where each piece has a single object, is given its own
representation. Such a groupoid is used in the \textsf{XMod} package as the source of a crossed modules of groupoids. 

 For the definitions of the standard properties of groupoids we refer to R.
Brown's book ``Topology'' \cite{BrTop}, recently revised and reissued as ``Topology and Groupoids'' \cite{BrTopGpd}. 
\section{\textcolor{Chapter }{Groupoids: their properties and attributes}}\label{sec-gpds}
\logpage{[ 3, 1, 0 ]}
\hyperdef{L}{X7AC321DC7E3C6167}{}
{
  

\subsection{\textcolor{Chapter }{SinglePieceGroupoid}}
\logpage{[ 3, 1, 1 ]}\nobreak
\hyperdef{L}{X8406913B7ED86CFE}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SinglePieceGroupoid({\mdseries\slshape grp, obs})\index{SinglePieceGroupoid@\texttt{SinglePieceGroupoid}}
\label{SinglePieceGroupoid}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Groupoid({\mdseries\slshape args})\index{Groupoid@\texttt{Groupoid}}
\label{Groupoid}
}\hfill{\scriptsize (function)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RootObject({\mdseries\slshape gpd})\index{RootObject@\texttt{RootObject}}
\label{RootObject}
}\hfill{\scriptsize (operation)}}\\


 As for magmas with objects, the simplest construction of a groupoid is as the
direct product of a group and a complete graph. Many subgroupoids of such a
groupoid do not have this simple form, and will be considered in section \ref{sec-subgpds}. As usual, the \texttt{RootObject} is the object with least label. The global function \texttt{Groupoid} will normally find the appropriate constructor to call, the options being: 
\begin{itemize}
\item  the object group, a list of objects; 
\item  a group being converted to a groupoid, a single object; 
\item  a list of groupoids which have already been constructed. 
\end{itemize}
 

 Methods for \texttt{ViewObj}, \texttt{PrintObj} and \texttt{Display} 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. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@s4 := Group( (1,2,3,4), (3,4) );; |
  !gapprompt@gap>| !gapinput@d8 := Subgroup( s4, [ (1,2,3,4), (1,3) ] );;|
  !gapprompt@gap>| !gapinput@SetName( s4, "s4" );  SetName( d8, "d8" ); |
  !gapprompt@gap>| !gapinput@Gs4 := SinglePieceGroupoid( s4, [-15 .. -11] ); |
  single piece groupoid: < s4, [ -15 .. -11 ] >
  !gapprompt@gap>| !gapinput@RootObject( Gs4 );|
  -15
  !gapprompt@gap>| !gapinput@Gd8 := Groupoid( d8, [-9,-8,-7] );|
  single piece groupoid: < d8, [ -9, -8, -7 ] >
  !gapprompt@gap>| !gapinput@c6 := Group( (5,6,7)(8,9) );;|
  !gapprompt@gap>| !gapinput@SetName( c6, "c6" );|
  !gapprompt@gap>| !gapinput@Gc6 := DomainWithSingleObject( c6, -6 );|
  single piece groupoid: < c6, [ -6 ] >
  !gapprompt@gap>| !gapinput@SetName( Gs4, "Gs4" );  SetName( Gd8, "Gd8" );  SetName( Gc6, "Gc6" );  |
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{IsPermGroupoid}}
\logpage{[ 3, 1, 2 ]}\nobreak
\hyperdef{L}{X8511D3EE845CC930}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsPermGroupoid({\mdseries\slshape gpd})\index{IsPermGroupoid@\texttt{IsPermGroupoid}}
\label{IsPermGroupoid}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsPcGroupoid({\mdseries\slshape gpd})\index{IsPcGroupoid@\texttt{IsPcGroupoid}}
\label{IsPcGroupoid}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsFpGroupoid({\mdseries\slshape gpd})\index{IsFpGroupoid@\texttt{IsFpGroupoid}}
\label{IsFpGroupoid}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsMatrixGroupoid({\mdseries\slshape gpd})\index{IsMatrixGroupoid@\texttt{IsMatrixGroupoid}}
\label{IsMatrixGroupoid}
}\hfill{\scriptsize (property)}}\\


 A groupoid is a permutation groupoid if all its pieces have permutation
groups. Most of the examples in this chapter are permutation groupoids, but in
principle any type of group known to \textsf{GAP} may be used. In the following example \texttt{Gf2} is an fp-groupoid, \texttt{Gq8} is a pc-groupoid, and \texttt{Gsl43} is a matrix groupoid. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@f2 := FreeGroup( 2 );;|
  !gapprompt@gap>| !gapinput@Gf2 := Groupoid( f2, -22 );;|
  !gapprompt@gap>| !gapinput@SetName( f2, "f2" );  SetName( Gf2, "Gf2" ); |
  !gapprompt@gap>| !gapinput@q8 := SmallGroup( 8, 4 );;|
  !gapprompt@gap>| !gapinput@Gq8 := Groupoid( q8, [ -28, -27 ] );;|
  !gapprompt@gap>| !gapinput@SetName( q8, "q8" );  SetName( Gq8, "Gq8" );|
  !gapprompt@gap>| !gapinput@sl43 := SpecialLinearGroup( 4, 3 );;|
  !gapprompt@gap>| !gapinput@Gsl43 := SinglePieceGroupoid( sl43, [ -35..-31 ] );;|
  !gapprompt@gap>| !gapinput@SetName( sl43, "sl43" );  SetName( Gsl43, "Gsl43" );|
  !gapprompt@gap>| !gapinput@[ IsMatrixGroupoid( Gsl43 ), IsFpGroupoid( Gf2 ), |
  !gapprompt@>| !gapinput@     IsPcGroupoid( Gq8 ), IsPermGroupoid( Gs4 ) ]; |
  [ true, true, true, true ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{UnionOfPieces}}
\logpage{[ 3, 1, 3 ]}\nobreak
\hyperdef{L}{X79877FAA8556A726}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{UnionOfPieces({\mdseries\slshape pieces})\index{UnionOfPieces@\texttt{UnionOfPieces}}
\label{UnionOfPieces}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Pieces({\mdseries\slshape gpd})\index{Pieces@\texttt{Pieces}}
\label{Pieces}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Size({\mdseries\slshape gpd})\index{Size@\texttt{Size}}
\label{Size}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ReplaceOnePieceInUnion({\mdseries\slshape gpd, old{\textunderscore}piece, new{\textunderscore}piece})\index{ReplaceOnePieceInUnion@\texttt{ReplaceOnePieceInUnion}}
\label{ReplaceOnePieceInUnion}
}\hfill{\scriptsize (operation)}}\\


 When a groupoid consists of two or more pieces, we require their object lists
to be disjoint. The operation \texttt{UnionOfPieces} and the attribute \texttt{Pieces}, introduced in section \ref{sec-pieces}, are also used for groupoids. The pieces are sorted by the least object in
their object lists. The \index{ObjectList@\texttt{ObjectList}!for groupoids} \texttt{ObjectList} is the sorted concatenation of the objects in the pieces. 

 The \texttt{Size} of a groupoid is the number of its arrows which, for a single piece groupoid,
is the product of the size of the group with the square of the number of
objects. 

 One of the pieces in a groupoid may be replaced by an alternative piece using
the operation \texttt{ReplaceOnePieceInUnion}. The objects in the new piece may or may not overlap the objects in the piece
removed -- we just require that the object lists in the new union are
disjoint. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@U3 := UnionOfPieces( [ Gs4, Gd8, Gc6 ] );;|
  !gapprompt@gap>| !gapinput@Display( U3 );|
  groupoid with 3 pieces:
  < objects: [ -15 .. -11 ]
      group: s4 = <[ (1,2,3,4), (3,4) ]> >
  < objects: [ -9, -8, -7 ]
      group: d8 = <[ (1,2,3,4), (1,3) ]> >
  < objects: [ -6 ]
      group: c6 = <[ (5,6,7)(8,9) ]> >
  !gapprompt@gap>| !gapinput@Pieces( U3 );|
  [ Gs4, Gd8, Gc6 ]
  !gapprompt@gap>| !gapinput@ObjectList( U3 );|
  [ -15, -14, -13, -12, -11, -9, -8, -7, -6 ]
  !gapprompt@gap>| !gapinput@U2 := Groupoid( [ Gf2, Gq8 ] );;|
  !gapprompt@gap>| !gapinput@[ Size(Gs4), Size(Gd8), Size(Gc6), Size(U3) ];|
  [ 600, 72, 6, 678 ]
  !gapprompt@gap>| !gapinput@[ Size(Gf2), Size(Gq8), Size(U2) ];           |
  [ infinity, 32, infinity ]
  !gapprompt@gap>| !gapinput@U5 := UnionOfPieces( [ U3, Gf2, Gq8 ] );|
  groupoid with 5 pieces:
  [ Gq8, Gf2, Gs4, Gd8, Gc6 ]
  !gapprompt@gap>| !gapinput@V5 := ReplaceOnePieceInUnion( U5, 3, Gsl43 ); |
  groupoid with 5 pieces:
  [ Gsl43, Gq8, Gf2, Gd8, Gc6 ]
  !gapprompt@gap>| !gapinput@ObjectList(V5);             |
  [ -35, -34, -33, -32, -31, -28, -27, -22, -9, -8, -7, -6 ]
  !gapprompt@gap>| !gapinput@U5 = V5; |
  false
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{HomogeneousGroupoid}}
\logpage{[ 3, 1, 4 ]}\nobreak
\hyperdef{L}{X855F318181808814}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HomogeneousGroupoid({\mdseries\slshape gpd, oblist})\index{HomogeneousGroupoid@\texttt{HomogeneousGroupoid}}
\label{HomogeneousGroupoid}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HomogeneousDiscreteGroupoid({\mdseries\slshape gp, obs})\index{HomogeneousDiscreteGroupoid@\texttt{HomogeneousDiscreteGroupoid}}
\label{HomogeneousDiscreteGroupoid}
}\hfill{\scriptsize (operation)}}\\


 Special functions are provided for the case where a groupoid has more than one
connected component, and these components are identical except for their
object sets. Such groupoids are said to be \emph{homogeneous}. 

 The operation \texttt{HomogeneousGroupoid} is used when the components each contain more than one object. The arguments
consist of a single piece groupoid \texttt{gpd} and a list of lists of objects \texttt{oblist}, each of whose lists has the same length as the object list \texttt{obs} of \texttt{gpd}. Note that \texttt{gpd} is \emph{not} included as one of the pieces in the output unless \texttt{obs} is included as one of the lists in \texttt{oblist}. 

 The operation \texttt{HomogeneousDiscreteGroupoid} is used when the components each have a single object. In this case the first
argument is just a group -- the root group for each component. These groupoids
are used in the \textsf{XMod} package as the source of many crossed modules of groupoids. 

 Both types of groupoid have the property \index{IsHomogeneousDomainWithObjects@\texttt{IsHomogeneousDomainWithObjects}} \texttt{IsHomogeneousDomainWithObjects}. In the latter case a separate representation \index{IsHomogeneousDomainWithObjectsRep@\texttt{IsHomogeneousDiscreteGroupoidRep}} \texttt{IsHomogeneousDiscreteGroupoidRep} is used. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@Hd8 := HomogeneousGroupoid( Gd8, [ [-12,-11,-10], [-16,-15,-14] ] ); |
  homogeneous groupoid with 2 pieces:
  1:  single piece groupoid: < d8, [ -16, -15, -14 ] >
  2:  single piece groupoid: < d8, [ -12, -11, -10 ] >
  !gapprompt@gap>| !gapinput@IsHomogeneousDomainWithObjects(Hd8);               |
  true
  !gapprompt@gap>| !gapinput@Hc6 := HomogeneousDiscreteGroupoid( c6, [-7..-4] );|
  homogeneous, discrete groupoid: < c6, [ -7 .. -4 ] >
  !gapprompt@gap>| !gapinput@RepresentationsOfObject(Gd8);|
  [ "IsComponentObjectRep", "IsAttributeStoringRep", "IsMWOSinglePieceRep" ]
  !gapprompt@gap>| !gapinput@RepresentationsOfObject(Hd8);|
  [ "IsComponentObjectRep", "IsAttributeStoringRep", "IsPiecesRep" ]
  !gapprompt@gap>| !gapinput@RepresentationsOfObject(Hc6);|
  [ "IsComponentObjectRep", "IsAttributeStoringRep", 
    "IsHomogeneousDiscreteGroupoidRep" ]
  !gapprompt@gap>| !gapinput@KnownTruePropertiesOfObject(Hc6); |
  [ "CanEasilyCompareElements", "CanEasilySortElements", "IsDuplicateFree", 
    "IsAssociative", "IsCommutative", "IsDiscreteDomainWithObjects", 
    "IsHomogeneousDomainWithObjects" ]
  !gapprompt@gap>| !gapinput@Kd8 := UnionOfPieces( [ Gd8, Hd8 ] );|
  groupoid with 3 pieces:
  1:  single piece groupoid: < d8, [ -16, -15, -14 ] >
  2:  single piece groupoid: < d8, [ -12, -11, -10 ] >
  3:  Gd8
  !gapprompt@gap>| !gapinput@ObjectList(Kd8);|
  [ -16, -15, -14, -12, -11, -10, -9, -8, -7 ]
  !gapprompt@gap>| !gapinput@IsHomogeneousDomainWithObjects( Kd8 );|
  true
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Groupoid elements; stars; costars; homsets}}\label{sec-elements}
\logpage{[ 3, 2, 0 ]}
\hyperdef{L}{X7F23BE3F85C9BA06}{}
{
  

\subsection{\textcolor{Chapter }{Arrow}}
\logpage{[ 3, 2, 1 ]}\nobreak
\hyperdef{L}{X86247DFC8242CEBE}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Arrow({\mdseries\slshape gpd, elt, tail, head})\index{Arrow@\texttt{Arrow}}
\label{Arrow}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ElementOfArrow({\mdseries\slshape elt})\index{ElementOfArrow@\texttt{ElementOfArrow}}
\label{ElementOfArrow}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{TailOfArrow({\mdseries\slshape elt})\index{TailOfArrow@\texttt{TailOfArrow}}
\label{TailOfArrow}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HeadOfArrow({\mdseries\slshape elt})\index{HeadOfArrow@\texttt{HeadOfArrow}}
\label{HeadOfArrow}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsArrowIn({\mdseries\slshape arr, gpd})\index{IsArrowIn@\texttt{IsArrowIn}}
\label{IsArrowIn}
}\hfill{\scriptsize (operation)}}\\


 A \emph{groupoid element} is an arrow in a magma with objects, as described in subsection \ref{man-arrow}. To recapitulate, an arrow \texttt{e} consists of a group element, \texttt{ElementOfArrow(e)} or \texttt{e![1]}; the tail (source) object, \texttt{TailOfArrow(e)} or \texttt{e![2]}; and the head (target) object, \texttt{HeadOfArrow(e)} or \texttt{e![3]}. Arrows have a \emph{partial composition}: two arrows may be multiplied when the head of the first coincides with the
tail of the second. When an attempt is made to multiply arrows where this
condition does not hold, then the value \texttt{fail} is returned. (In earlier versions of the package there were functions \texttt{GroupoidElement} and \texttt{MultiplicativeElementWithObjects}, but these have now been replaced by \texttt{Arrow}.) 

 }

 \index{* for groupoid elements} 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@e1 := Arrow( Gd8, (1,2,3,4), -9, -8 );|
  [(1,2,3,4) : -9 -> -8]
  !gapprompt@gap>| !gapinput@e2 := Arrow( Gd8, (1,3), -8, -7 );|
  [(1,3) : -8 -> -7]
  !gapprompt@gap>| !gapinput@Print( [ ElementOfArrow(e2), TailOfArrow(e2), HeadOfArrow(e2) ], "\n" );|
  [ (1,3), -8, -7 ]
  !gapprompt@gap>| !gapinput@prod := e1*e2;|
  [(1,2)(3,4) : -9 -> -7]
  !gapprompt@gap>| !gapinput@e2*e1;|
  fail
  !gapprompt@gap>| !gapinput@e3 := Arrow( Gd8, (2,4), -7, -9 );;|
  !gapprompt@gap>| !gapinput@cycle := prod*e3;|
  [(1,4,3,2) : -9 -> -9]
  !gapprompt@gap>| !gapinput@cycle^2;|
  [(1,3)(2,4) : -9 -> -9]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{IdentityArrow}}
\logpage{[ 3, 2, 2 ]}\nobreak
\hyperdef{L}{X78C3228682279032}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IdentityArrow({\mdseries\slshape gpd, obj})\index{IdentityArrow@\texttt{IdentityArrow}}
\label{IdentityArrow}
}\hfill{\scriptsize (operation)}}\\


 The identity arrow $1_o$ of $G$ at object $o$ is $(e:o \to o)$ where $e$ is the identity element in the object group. The inverse $e^{-1}$ of $e = (c : p \to q)$ is $(c^{-1} : q \to p)$, so that $e*e^{-1}=1_p$ and $e^{-1}*e = 1_q$. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@i8 := IdentityArrow( Gd8, -8 );|
  [() : -8 -> -8]
  !gapprompt@gap>| !gapinput@[ e1*i8, i8*e1, e1^-1]; |
  [ [(1,2,3,4) : -9 -> -8], fail, [(1,4,3,2) : -8 -> -9] ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{Order}}
\logpage{[ 3, 2, 3 ]}\nobreak
\hyperdef{L}{X84F59A2687C62763}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Order({\mdseries\slshape arr})\index{Order@\texttt{Order}}
\label{Order}
}\hfill{\scriptsize (attribute)}}\\


 A groupoid element is a \index{loop@loop} \emph{loop} when the tail and head coincide. In this case the order of the element is
defined to be the order of its group element. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@i8; Order(i8);|
  [() : -8 -> -8]
  1
  !gapprompt@gap>| !gapinput@cycle; Order(cycle);|
  [(1,4,3,2) : -9 -> -9]
  4
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{ObjectStar}}
\logpage{[ 3, 2, 4 ]}\nobreak
\hyperdef{L}{X7B561BAE7D471C60}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ObjectStar({\mdseries\slshape gpd, obj})\index{ObjectStar@\texttt{ObjectStar}}
\label{ObjectStar}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ObjectCostar({\mdseries\slshape gpd, obj})\index{ObjectCostar@\texttt{ObjectCostar}}
\label{ObjectCostar}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Homset({\mdseries\slshape gpd, tail, head})\index{Homset@\texttt{Homset}}
\label{Homset}
}\hfill{\scriptsize (operation)}}\\


 The \emph{star} at \texttt{obj} is the set of arrows which have \texttt{obj} as tail, while the \emph{costar} is the set of arrows which have \texttt{obj} as head. The \emph{homset} from \texttt{obj1} to \texttt{obj2} is the set of arrows with the specified tail and head, and so is bijective
with the elements of the object groups. Thus every star and every costar is a
union of homsets. The identity arrow at an object is a left identity for the
star and a right identity for the costar at that object. 

 In order not to create unneccessarily long lists, these operations return
objects of type \texttt{IsHomsetCosetsRep} for which an \texttt{Iterator} is provided. (An \texttt{Enumerator} is not yet implemented.) 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@star9 := ObjectStar( Gd8, -9 );|
  <star at [ -9 ] with group d8>
  !gapprompt@gap>| !gapinput@Size( star9 ); |
  24
  !gapprompt@gap>| !gapinput@for e in star9 do|
  !gapprompt@>| !gapinput@     if ( Order( ElementOfArrow(e) ) = 4 ) then Print( e, "\n" ); fi;|
  !gapprompt@>| !gapinput@   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]
  !gapprompt@gap>| !gapinput@costar6 := ObjectCostar( Gc6, -6 );|
  <costar at [ -6 ] with group c6>
  !gapprompt@gap>| !gapinput@Size( costar6 ); |
  6
  !gapprompt@gap>| !gapinput@hsetq8 := Homset( Gq8, -28, -27 );|
  <homset -28 -> -27 with group q8>
  !gapprompt@gap>| !gapinput@for e in hsetq8 do Print(e,"\n"); od;|
  [<identity> of ... : -28 -> -27]
  [f3 : -28 -> -27]
  [f2 : -28 -> -27]
  [f2*f3 : -28 -> -27]
  [f1 : -28 -> -27]
  [f1*f3 : -28 -> -27]
  [f1*f2 : -28 -> -27]
  [f1*f2*f3 : -28 -> -27]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Subgroupoids}}\label{sec-subgpds}
\logpage{[ 3, 3, 0 ]}
\hyperdef{L}{X7BDBA72C852C4625}{}
{
  

\subsection{\textcolor{Chapter }{Subgroupoid}}
\logpage{[ 3, 3, 1 ]}\nobreak
\hyperdef{L}{X80780D287EDDB7BB}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Subgroupoid({\mdseries\slshape args})\index{Subgroupoid@\texttt{Subgroupoid}}
\label{Subgroupoid}
}\hfill{\scriptsize (function)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SubgroupoidByPieces({\mdseries\slshape gpd, obhoms})\index{SubgroupoidByPieces@\texttt{SubgroupoidByPieces}}
\label{SubgroupoidByPieces}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsSubgroupoid({\mdseries\slshape gpd, sgpd})\index{IsSubgroupoid@\texttt{IsSubgroupoid}}
\label{IsSubgroupoid}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{FullSubgroupoid({\mdseries\slshape gpd, obs})\index{FullSubgroupoid@\texttt{FullSubgroupoid}}
\label{FullSubgroupoid}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{MaximalDiscreteSubgroupoid({\mdseries\slshape gpd})\index{MaximalDiscreteSubgroupoid@\texttt{MaximalDiscreteSubgroupoid}}
\label{MaximalDiscreteSubgroupoid}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DiscreteSubgroupoid({\mdseries\slshape gpd, sgps, obs})\index{DiscreteSubgroupoid@\texttt{DiscreteSubgroupoid}}
\label{DiscreteSubgroupoid}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{FullTrivialSubgroupoid({\mdseries\slshape gpd})\index{FullTrivialSubgroupoid@\texttt{FullTrivialSubgroupoid}}
\label{FullTrivialSubgroupoid}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DiscreteTrivialSubgroupoid({\mdseries\slshape gpd})\index{DiscreteTrivialSubgroupoid@\texttt{DiscreteTrivialSubgroupoid}}
\label{DiscreteTrivialSubgroupoid}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsWide({\mdseries\slshape gpd, sgpd})\index{IsWide@\texttt{IsWide}}
\label{IsWide}
}\hfill{\scriptsize (operation)}}\\


 A \emph{subgroupoid} \texttt{sgpd} of a groupoid \texttt{gpd} has as objects some subset of the objects of \texttt{gpd}. It is \emph{wide} if all the objects are included. It is \emph{full} if, for any two objects in \texttt{sgpd}, the \texttt{Homset} is the same as that in \texttt{gpd}. The arrows of \texttt{sgpd} are a subset of those of \texttt{gpd}, closed under multiplication and with tail and head in the chosen object set. 

 There are a variety of constructors for a subgroupoid of a groupoid, and the
most general is the operation \texttt{SubgroupoidByPieces}. Its two parameters are a groupoid and a list of pieces, each piece being
specified as a list \texttt{[sgp,obs]}, where \texttt{sgp} is a subgroup of the root group in that piece, and \texttt{obs} is a subset of the objects in that piece. The \texttt{FullSubgroupoid} of a groupoid \texttt{gpd} on a subset \texttt{obs} of its objects contains all the arrows of \texttt{gpd} with tail and head in \texttt{obs}. A subgroupoid is \emph{discrete} if it is a union of groups. The \texttt{MaximalDiscreteSubgroupoid} of \texttt{gpd} is the union of all the single-object full subgroupoids of \texttt{gpd}. A \index{trivial subgroupoid@trivial subgroupoid} \emph{trivial subgroupoid} has trivial object groups, but need not be discrete. A single piece trivial
groupoid is sometimes called a \index{tree groupoid@tree groupoid} \emph{tree groupoid}. (The term \index{identity subgroupoid@identity subgroupoid} \emph{identity subgroupoid} was used in versions up to 1.14.) The global function \texttt{Subgroupoid} should call the appropriate operation. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@c4 := Subgroup( d8, [ (1,2,3,4) ] );;|
  !gapprompt@gap>| !gapinput@k4 := Subgroup( d8, [ (1,2)(3,4), (1,3)(2,4) ] );;|
  !gapprompt@gap>| !gapinput@SetName( c4, "c4" );  SetName( k4, "k4" );|
  !gapprompt@gap>| !gapinput@Ud8 := Subgroupoid( Gd8, [ [ k4, [-9] ], [ c4, [-8,-7] ] ] );;|
  !gapprompt@gap>| !gapinput@SetName( Ud8, "Ud8" );|
  !gapprompt@gap>| !gapinput@Display( Ud8 );|
  groupoid with 2 pieces:
  < objects: [ -9 ]
      group: k4 = <[ (1,2)(3,4), (1,3)(2,4) ]> >
  < objects: [ -8, -7 ]
      group: c4 = <[ (1,2,3,4) ]> >
  !gapprompt@gap>| !gapinput@[ Parent( Ud8 ), IsWide( Gd8, Ud8 ) ]; |
  [ Gd8, true ]
  !gapprompt@gap>| !gapinput@genf2b := List( GeneratorsOfGroup(f2), g -> g^2 );|
  [ f1^2, f2^2 ]
  !gapprompt@gap>| !gapinput@f2b := Subgroup( f2, genf2b );;|
  !gapprompt@gap>| !gapinput@SubgroupoidByPieces( U2, [ [q8,[-27]], [f2b,[-22]] ] );|
  groupoid with 2 pieces:
  1:  single piece groupoid: < q8, [ -27 ] >
  2:  single piece groupoid: < Group( [ f1^2, f2^2 ] ), [ -22 ] >
  !gapprompt@gap>| !gapinput@IsSubgroupoid( Gf2, Groupoid( f2b, [-22] ) );|
  true
  !gapprompt@gap>| !gapinput@FullSubgroupoid( U3, [-7,-6] );|
  groupoid with 2 pieces:
  1:  single piece groupoid: < d8, [ -7 ] >
  2:  single piece groupoid: < c6, [ -6 ] >
  !gapprompt@gap>| !gapinput@DiscreteSubgroupoid( U3, [ c4, k4 ], [-9,-7] );|
  groupoid with 2 pieces:
  1:  single piece groupoid: < c4, [ -9 ] >
  2:  single piece groupoid: < k4, [ -7 ] >
  !gapprompt@gap>| !gapinput@FullTrivialSubgroupoid( Ud8 );|
  groupoid with 2 pieces:
  1:  single piece groupoid: < id(k4), [ -9 ] >
  2:  single piece groupoid: < id(c4), [ -8, -7 ] >
  !gapprompt@gap>| !gapinput@MaximalDiscreteSubgroupoid(U2);|
  groupoid with 3 pieces:
  1:  single piece groupoid: < q8, [ -28 ] >
  2:  single piece groupoid: < q8, [ -27 ] >
  3:  single piece groupoid: < f2, [ -22 ] >
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{SubgroupoidWithRays}}
\logpage{[ 3, 3, 2 ]}\nobreak
\hyperdef{L}{X873E0914871858E8}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SubgroupoidWithRays({\mdseries\slshape gpd, sgp, rays})\index{SubgroupoidWithRays@\texttt{SubgroupoidWithRays}}
\label{SubgroupoidWithRays}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RaysOfGroupoid({\mdseries\slshape gpd})\index{RaysOfGroupoid@\texttt{RaysOfGroupoid}}
\label{RaysOfGroupoid}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RayElementsOfGroupoid({\mdseries\slshape gpd})\index{RayElementsOfGroupoid@\texttt{RayElementsOfGroupoid}}
\label{RayElementsOfGroupoid}
}\hfill{\scriptsize (operation)}}\\


 If groupoid $G$ is of type \texttt{IsDirectProductWithCompleteGraph} with group $g$ and $n$ objects, then a typical wide subgroupoid $H$ of $G$ is formed by choosing a subgroup $h$ of $g$ to be the object group at the root object $q$, and an arrow $r : q \to p$ for each of the objects $p$. The chosen loop arrow at $q$ must be the identity arrow. These $n$ arrows are called the \index{rays@rays} \emph{rays} of the subgroupoid. The arrows in the homset from $p$ to $p'$ have the form $r^{-1}xr'$ for all rays $r,r'$ and all $x$ in $h$. 

 The operation \texttt{RaysOfGroupoid} returns a list of arrows, one for each object, while the operation \texttt{RayElementsOfGroupoid} returns the list of group elements in these arrows. 

 In the following example we construct a subgroupoid with rays on four of the
five objects. It is therefore necessary to construct the full subgroupoid on
these four objects first. 

 Note that it is also possible to construct a subgroupoid with rays of a
subgroupoid with rays. 

 Note also that the function \index{Ancestor@\texttt{Ancestor}} \texttt{Ancestor} provides an iteration of \texttt{Parent}. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@Hs4 := FullSubgroupoid( Gs4, [-14,-13,-12] );; |
  !gapprompt@gap>| !gapinput@SetName( Hs4, "Hs4" ); |
  !gapprompt@gap>| !gapinput@Hd8a := SubgroupoidWithRays( Hs4, d8, [(),(2,3),(3,4)] );|
  single piece groupoid with rays: < d8, [ -14, -13, -12 ], [ (), (2,3), (3,4)
   ] >
  !gapprompt@gap>| !gapinput@hs1413 := Homset( Hd8a, -14, -13 );|
  <homset -14 -> -13 with group d8>
  !gapprompt@gap>| !gapinput@for e in hs1413 do  Print(e,", "); od;  Print( "\n");|
  [(2,3) : -14 -> -13], [(1,2,4,3) : -14 -> -13], [(1,4,2) : -14 -> -13], [
  (1,3,4) : -14 -> -13], [(2,4,3) : -14 -> -13], [(1,2,3) : -14 -> -13], [
  (1,4) : -14 -> -13], [(1,3,4,2) : -14 -> -13], 
  !gapprompt@gap>| !gapinput@Hd8b := SubgroupoidWithRays( Hs4, d8, [(),(1,2,3),(1,2,4)] );|
  single piece groupoid with rays: < d8, [ -14, -13, -12 ],
  [ (), (1,2,3), (1,2,4) ] >
  !gapprompt@gap>| !gapinput@Hd8a = Hd8b; |
  true
  !gapprompt@gap>| !gapinput@RaysOfGroupoid( Hd8b );|
  [ [() : -14 -> -14], [(1,2,3) : -14 -> -13], [(1,2,4) : -14 -> -12] ]
  !gapprompt@gap>| !gapinput@RayElementsOfGroupoid( Hd8b ); |
  [ (), (1,2,3), (1,2,4) ]
  !gapprompt@gap>| !gapinput@Parent( Hd8a );|
  Hs4
  !gapprompt@gap>| !gapinput@Ancestor( Hd8a ); |
  Gs4
  !gapprompt@gap>| !gapinput@Fd8a := FullSubgroupoid( Hd8a, [-14,-13]);|
  single piece groupoid with rays: < d8, [ -14, -13 ], [ (), (2,3) ] >
  !gapprompt@gap>| !gapinput@Fd8b := FullSubgroupoid( Hd8a, [-13,-12]);|
  single piece groupoid with rays: < Group( [ (1,3,2,4), (1,2) ] ), 
  [ -13, -12 ], [ (), (2,4,3) ] >
  !gapprompt@gap>| !gapinput@Fd8a := FullSubgroupoid( Hd8a, [-13,-12] );            |
  single piece groupoid with rays: < Group( [ (1,3,2,4), (1,2) ] ), 
  [ -13, -12 ], [ (), (2,4,3) ] >
  !gapprompt@gap>| !gapinput@Kd8a := SubgroupoidWithRays( Fd8a, k4, [ (), (1,3) ] ); |
  single piece groupoid with rays: < k4, [ -13, -12 ], [ (), (1,3) ] >
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Left, right and double cosets}}\label{sec-cosets}
\logpage{[ 3, 4, 0 ]}
\hyperdef{L}{X831AA9E8780235F2}{}
{
  

\subsection{\textcolor{Chapter }{RightCoset}}
\logpage{[ 3, 4, 1 ]}\nobreak
\hyperdef{L}{X8412ABD57986B9FC}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RightCoset({\mdseries\slshape G, U, elt})\index{RightCoset@\texttt{RightCoset}}
\label{RightCoset}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RightCosetRepresentatives({\mdseries\slshape G, U})\index{RightCosetRepresentatives@\texttt{RightCosetRepresentatives}}
\label{RightCosetRepresentatives}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{LeftCoset({\mdseries\slshape G, U, elt})\index{LeftCoset@\texttt{LeftCoset}}
\label{LeftCoset}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{LeftCosetRepresentatives({\mdseries\slshape G, U})\index{LeftCosetRepresentatives@\texttt{LeftCosetRepresentatives}}
\label{LeftCosetRepresentatives}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{LeftCosetRepresentativesFromObject({\mdseries\slshape G, U, obj})\index{LeftCosetRepresentativesFromObject@\texttt{LeftCosetRepresentativesFromObject}}
\label{LeftCosetRepresentativesFromObject}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DoubleCoset({\mdseries\slshape G, U, elt, V})\index{DoubleCoset@\texttt{DoubleCoset}}
\label{DoubleCoset}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DoubleCosetRepresentatives({\mdseries\slshape G, U, V})\index{DoubleCosetRepresentatives@\texttt{DoubleCosetRepresentatives}}
\label{DoubleCosetRepresentatives}
}\hfill{\scriptsize (operation)}}\\


 If \texttt{U} is a wide subgroupoid of $G$, the \emph{right cosets} $Ug$ of $U$ in $G$ are the equivalence classes for the relation on the arrows of $G$ where $g1$ is related to $g2$ if and only if $g2 = u*g1$ for some arrow $u$ of $U$. The right coset containing $g$ is written $Ug$. These right cosets partition the costars of $G$ and, in particular, the costar $U1\_{o}$ of $U$ at object $o$, so that (unlike groups) $U$ is itself a coset only when $G$ has a single object. 

 The \emph{right coset representatives} for $U$ in $G$ form a list containing one arrow for each coset where, in a particular piece
of $U$, the group element chosen is the right coset representative of the group of $U$ in the group of $G$. 

 Similarly, the \emph{left cosets} $gU$ refine the stars of $G$, while \emph{double cosets} are unions of left cosets and right cosets. The operation \texttt{LeftCosetRepresentativesFromObject( G, U, obj )} is used in Chapter 4, and returns only those representatives which have tail
at \texttt{obj}. 

 As with stars and homsets, these cosets are implemented with representation \texttt{IsHomsetCosetsRep} and provided with an iterator. Note that, when $U$ has more than one piece, cosets may have differing lengths. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@re2 := RightCoset( Gd8, Ud8, e2 );|
  RightCoset(single piece groupoid: < c4, [ -8, -7 ] >,[(1,3) : -8 -> -7])
  !gapprompt@gap>| !gapinput@for x in re2 do Print( x, "\n" ); od;|
  [(1,3) : -8 -> -7]
  [(1,3) : -7 -> -7]
  [(2,4) : -8 -> -7]
  [(2,4) : -7 -> -7]
  [(1,4)(2,3) : -8 -> -7]
  [(1,4)(2,3) : -7 -> -7]
  [(1,2)(3,4) : -8 -> -7]
  [(1,2)(3,4) : -7 -> -7]
  !gapprompt@gap>| !gapinput@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]
   ]
  !gapprompt@gap>| !gapinput@lcr7 := LeftCosetRepresentativesFromObject( Gd8, Ud8, -7 );|
  [ [() : -7 -> -9], [(2,4) : -7 -> -9], [() : -7 -> -8], [(2,4) : -7 -> -8] ]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Conjugation}}\label{sec-conj}
\logpage{[ 3, 5, 0 ]}
\hyperdef{L}{X8653FC9786E3209A}{}
{
  

\subsection{\textcolor{Chapter }{ConjugateArrow}}
\logpage{[ 3, 5, 1 ]}\nobreak
\hyperdef{L}{X851E390F87037421}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ConjugateArrow({\mdseries\slshape e1, e})\index{ConjugateArrow@\texttt{ConjugateArrow}}
\label{ConjugateArrow}
}\hfill{\scriptsize (operation)}}\\


 When $e = (c : p \to q)$ conjugation by $e$ is the groupoid automorphism defined as follows. There are two cases. 

 In the case $p \neq q$, 
\begin{itemize}
\item  objects $p,q$ are interchanged, and the remaining objects are fixed; 
\item  loops at $p,q$: $(b: p \to p) \mapsto (b^c : q \to q)$ and $(b: q \to q) \mapsto (b^{c^{-1}} : p \to p)$; 
\item  arrows between $p$ and $q$: $(b : p \to q) \mapsto (c^{-1}bc^{-1} : q \to p)$ and $(b : q \to p) \mapsto (cbc : p \to q)$; 
\item  costar at $p,q$: $(b : r \to p) \mapsto (bc : r \to q)$ and $(b : r \to q) \mapsto (bc^{-1} : r \to p)$; 
\item  star at $p,q$: $(b : p \to r) \mapsto (c^{-1}b : \to q)$ and $(b : q \to r) \mapsto (cb : p \to r)$; 
\item  the remaining arrows are unchanged. 
\end{itemize}
 

 In the case $p=q$, 
\begin{itemize}
\item  all the objects are fixed; 
\item  loops at $p$ are conjugated by $c$, $(b : p \to p) \mapsto (b^c : p \to p)$; 
\item  the rest of the costar and star at $p$ are permuted, $(b : r \to p) \mapsto (bc : r \to p)$ and $(b : p \to r) \mapsto (c^{-1}b : p \to r)$; 
\item  the remaining arrows are unchanged. 
\end{itemize}
 

 The details of this construction may be found in \cite{AlWe}. 

 (Note that it is more desirable to use the command \texttt{e1\texttt{\symbol{94}}e2}, but it has not yet been possible to get this to work!) }

 \index{\texttt{\symbol{92}}\texttt{\symbol{94}}\texttt{\symbol{123}}\texttt{\symbol{125}} for arrows} 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@x := Arrow( Gd8, (1,3), -9, -9 );; |
  !gapprompt@gap>| !gapinput@y := Arrow( Gd8, (1,2,3,4), -8, -9 );; |
  !gapprompt@gap>| !gapinput@z := Arrow( Gd8, (1,2)(3,4), -9, -7 );; |
  !gapprompt@gap>| !gapinput@w := Arrow( Gd8, (1,2,3,4), -7, -8 );; |
  !gapprompt@gap>| !gapinput@##  conjugation with arrows x, y, z and w in Gd8: |
  !gapprompt@gap>| !gapinput@ConjugateArrow(x,y);|
  [(2,4) : -8 -> -8]
  !gapprompt@gap>| !gapinput@ConjugateArrow(x,z);|
  [(2,4) : -7 -> -7]
  !gapprompt@gap>| !gapinput@ConjugateArrow(x,w);|
  [(1,3) : -9 -> -9]
  !gapprompt@gap>| !gapinput@ConjugateArrow(y,x);|
  [() : -8 -> -9]
  !gapprompt@gap>| !gapinput@ConjugateArrow(y,z);|
  [(2,4) : -8 -> -7]
  !gapprompt@gap>| !gapinput@ConjugateArrow(y,w);    |
  [(1,3)(2,4) : -7 -> -9]
  !gapprompt@gap>| !gapinput@ConjugateArrow(z,x);|
  [(1,4,3,2) : -9 -> -7]
  !gapprompt@gap>| !gapinput@ConjugateArrow(z,y);|
  [(2,4) : -8 -> -7]
  !gapprompt@gap>| !gapinput@ConjugateArrow(z,w);|
  [(1,3) : -9 -> -8]
  !gapprompt@gap>| !gapinput@ConjugateArrow(w,x); |
  [(1,2,3,4) : -7 -> -8]
  !gapprompt@gap>| !gapinput@ConjugateArrow(w,y);|
  [(1,3)(2,4) : -7 -> -9]
  !gapprompt@gap>| !gapinput@ConjugateArrow(w,z);|
  [(1,3) : -9 -> -8]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{SinglePieceGroupoidByGenerators}}
\logpage{[ 3, 5, 2 ]}\nobreak
\hyperdef{L}{X7C2727D285BA2EBE}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SinglePieceGroupoidByGenerators({\mdseries\slshape parent, gens})\index{SinglePieceGroupoidByGenerators@\texttt{SinglePieceGroupoidByGenerators}}
\label{SinglePieceGroupoidByGenerators}
}\hfill{\scriptsize (operation)}}\\


 A set of arrows generates a groupoid by taking all possible products and
inverses. So far, the only implementation is for the case of loops generating
a group at an object $o$ andf a set of rays from $o$, where $o$ is \emph{not} the least object. A suitably large supergroupoid, which must be a direct
product with a complete graph, should be provided. This is the case needed for \texttt{ConjugateGroupoid} in the following section. Other cases will be added as time permits. }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@u := Arrow( Gs4, (1,2,3), -15, -13 ); |
  [(1,2,3) : -15 -> -13]
  !gapprompt@gap>| !gapinput@gensa := GeneratorsOfGroupoid( Hd8a );|
  [ [(1,2,3,4) : -14 -> -14], [(1,3) : -14 -> -14], [(2,3) : -14 -> -13], 
    [(3,4) : -14 -> -12] ]
  !gapprompt@gap>| !gapinput@imsa := List( gensa, g -> ConjugateArrow( g, u ) ); |
  [ [(1,2,3,4) : -14 -> -14], [(1,3) : -14 -> -14], [(1,3) : -14 -> -15], 
    [(3,4) : -14 -> -12] ]
  !gapprompt@gap>| !gapinput@C := SinglePieceGroupoidByGenerators( Gs4, imsa ); |
  single piece groupoid with rays: < Group( [ (1,4,3,2), (1,3) ] ), 
  [ -15, -14, -12 ], [ (), (1,3), (1,4,3) ] >
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{ConjugateGroupoid}}
\logpage{[ 3, 5, 3 ]}\nobreak
\hyperdef{L}{X78218F357BFEDE82}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ConjugateGroupoid({\mdseries\slshape gpd, e})\index{ConjugateGroupoid@\texttt{ConjugateGroupoid}}
\label{ConjugateGroupoid}
}\hfill{\scriptsize (operation)}}\\


 When $H$ is a subgroupoid of a groupoid $G$ and $a$ is an arrow of $G$, then the conjugate of $H$ by $a$ is the subgroupoid generated by the conjugates of the generators of $H$. }

 \index{\texttt{\symbol{92}}\texttt{\symbol{94}}\texttt{\symbol{123}}\texttt{\symbol{125}} for groupoids} 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@ConjugateGroupoid( Hd8a, u^-1 ); |
  single piece groupoid with rays: < Group( [ (1,4,3,2), (1,3) ] ), 
  [ -15, -14, -12 ], [ (), (1,3), (1,4,3) ] >
  
\end{Verbatim}
 }

 More examples of all these operations may be found in the example file \texttt{gpd/examples/gpd.g}. }

            
\chapter{\textcolor{Chapter }{Homomorphisms of Groupoids}}\label{chap-gpdhom}
\logpage{[ 4, 0, 0 ]}
\hyperdef{L}{X879ED2A7878B5A7A}{}
{
  A \emph{homomorphism} $m$ from a groupoid $G$ to a groupoid $H$ consists of a map from the objects of $G$ to those of $H$ together with a map from the elements of $G$ to those of $H$ which is compatible with tail and head and which preserves multiplication: 
\[ m(g1 : o1 \to o2)*m(g2 : o2 \to o3) ~=~ m(g1*g2 : o1 \to o3). \]
 

 Note that when a homomorphism is not injective on objects, the image of the
source need not be a subgroupoid of the range. A simple example of this is
given by a homomorphism from the two-object, four-element groupoid with
trivial group to the free group $\langle a \rangle$ on one generator, when the image is $[1,a^n,a^{-n}]$ for some $n>0$. 
\section{\textcolor{Chapter }{Homomorphisms from a connected groupoid}}\label{sec-homsfrom}
\logpage{[ 4, 1, 0 ]}
\hyperdef{L}{X85D28690823636CD}{}
{
  

\subsection{\textcolor{Chapter }{GroupoidHomomorphismFromSinglePiece}}
\logpage{[ 4, 1, 1 ]}\nobreak
\hyperdef{L}{X870288C6803D9005}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GroupoidHomomorphismFromSinglePiece({\mdseries\slshape src, rng, hom, imobs, imrays})\index{GroupoidHomomorphismFromSinglePiece@\texttt{GroupoidHomomorphismFromSinglePiece}}
\label{GroupoidHomomorphismFromSinglePiece}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GroupoidHomomorphismByGroupHom({\mdseries\slshape src, rng, hom})\index{GroupoidHomomorphismByGroupHom@\texttt{GroupoidHomomorphismByGroupHom}}
\label{GroupoidHomomorphismByGroupHom}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GroupoidHomomorphism({\mdseries\slshape args})\index{GroupoidHomomorphism@\texttt{GroupoidHomomorphism}}
\label{GroupoidHomomorphism}
}\hfill{\scriptsize (function)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{InclusionMappingGroupoids({\mdseries\slshape gpd, sgpd})\index{InclusionMappingGroupoids@\texttt{InclusionMappingGroupoids}}
\label{InclusionMappingGroupoids}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RootObjectHomomorphism({\mdseries\slshape gpdhom})\index{RootObjectHomomorphism@\texttt{RootObjectHomomorphism}}
\label{RootObjectHomomorphism}
}\hfill{\scriptsize (attribute)}}\\


 As usual, there are various homomorphism operations. The basic construction is
a homomorphism $G \to H$ with $G$ the direct product of a group and a complete graph. The homomorphism has
attributes \texttt{Source}, \texttt{Range}, \texttt{ImagesOfObjects}, \texttt{PieceImages} and \texttt{RootObjectHomomorphism}. The input data consists of the source; the range; and 
\begin{itemize}
\item  a homomorphism \texttt{hom} from the root group of $G$ to that of $H$; 
\item  a list \texttt{imobs} of the images of the objects of $G$; 
\item  a list \texttt{imrays} of the images of the rays of $G$. 
\end{itemize}
 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@gend12 := [ (15,16,17,18,19,20), (15,20)(16,19)(17,18) ];; |
  !gapprompt@gap>| !gapinput@d12 := Group( gend12 );; |
  !gapprompt@gap>| !gapinput@Gd12 := Groupoid( d12, [-37,-36,-35,-34] );;|
  !gapprompt@gap>| !gapinput@SetName( d12, "d12" );  |
  !gapprompt@gap>| !gapinput@SetName( Gd12, "Gd12" );|
  !gapprompt@gap>| !gapinput@s3 := Subgroup( d12, [ (15,17,19)(16,18,20), (15,20)(16,19)(17,18) ] );;|
  !gapprompt@gap>| !gapinput@Gs3 := SubgroupoidByPieces( Gd12, [ [ s3, [-36,-35,-34] ] ] );;|
  !gapprompt@gap>| !gapinput@SetName( s3, "s3" );  |
  !gapprompt@gap>| !gapinput@SetName( Gs3, "Gs3" );|
  !gapprompt@gap>| !gapinput@gend8 := GeneratorsOfGroup( d8 );;|
  !gapprompt@gap>| !gapinput@imhd8 := [ ( ), (15,20)(16,19)(17,18) ];;|
  !gapprompt@gap>| !gapinput@hd8 := GroupHomomorphismByImages( d8, s3, gend8, imhd8 );;|
  !gapprompt@gap>| !gapinput@homd8 := GroupoidHomomorphismByGroupHom( Gd8, Gs3, hd8 ); |
  groupoid homomorphism : Gd8 -> Gs3
  [ [ GroupHomomorphismByImages( d8, s3, [ (1,2,3,4), (1,3) ], 
          [ (), (15,20)(16,19)(17,18) ] ), [ -36, -35, -34 ], [ (), (), () ] ] ]
  !gapprompt@gap>| !gapinput@e2; ImageElm( homd8, e2 );|
  [(1,3) : -8 -> -7]
  [(15,20)(16,19)(17,18) : -35 -> -34]
  !gapprompt@gap>| !gapinput@incGs3 := InclusionMappingGroupoids( Gd12, Gs3 );; |
  !gapprompt@gap>| !gapinput@ihomd8 := homd8 * incGs3;; |
  !gapprompt@gap>| !gapinput@IsBijectiveOnObjects( ihomd8 );|
  false
  !gapprompt@gap>| !gapinput@Display( ihomd8 );|
   groupoid mapping: [ Gd8 ] -> [ Gd12 ]
  root homomorphism: [ [ (1,2,3,4), (1,3) ], [ (), (15,20)(16,19)(17,18) ] ]
  images of objects: [ -36, -35, -34 ]
     images of rays: [ (), (), () ]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Homomorphisms to a connected groupoid}}\label{sec-homsto}
\logpage{[ 4, 2, 0 ]}
\hyperdef{L}{X7EAAB2A97E097FB6}{}
{
  

\subsection{\textcolor{Chapter }{HomomorphismToSinglePiece}}
\logpage{[ 4, 2, 1 ]}\nobreak
\hyperdef{L}{X7BE552BE7A1CA981}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HomomorphismToSinglePiece({\mdseries\slshape src, rng, pieces})\index{HomomorphismToSinglePiece@\texttt{HomomorphismToSinglePiece}}
\label{HomomorphismToSinglePiece}
}\hfill{\scriptsize (operation)}}\\


 When $G$ is made up of two or more pieces, all of which get mapped to a connected
groupoid, we have a \emph{homomorphism to a single piece}. The third input parameter in this case is a list of the \texttt{PieceImages} of the individual homomorphisms \emph{from} the single pieces. See section \ref{sec-mwohom} for the corresponding operation on homomorphisms of magmas with objects. 

 In the following example the source \texttt{V3} of \texttt{homV3} has three pieces, and one of the component homomorphisms is an \texttt{IdentityMapping} \index{IdentityMapping@\texttt{IdentityMapping}}. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@hc6 := GroupHomomorphismByImages( c6, s3, |
  !gapprompt@>| !gapinput@           [(5,6,7)(8,9)], [(15,16)(17,20)(18,19)] );;|
  !gapprompt@gap>| !gapinput@Fs3 := FullSubgroupoid( Gs3, [ -35 ] );; |
  !gapprompt@gap>| !gapinput@SetName( Fs3, "Fs3" ); |
  !gapprompt@gap>| !gapinput@homc6 := GroupoidHomomorphism( Gc6, Fs3, hc6 );;|
  !gapprompt@gap>| !gapinput@incFs3 := InclusionMappingGroupoids( Gs3, Fs3 );; |
  !gapprompt@gap>| !gapinput@ihomc6 := homc6 * incFs3; |
  groupoid homomorphism : Gc6 -> Gs3
  [ [ GroupHomomorphismByImages( c6, s3, [ (5,6,7)(8,9) ], 
          [ (15,16)(17,20)(18,19) ] ), [ -35 ], [ () ] ] ]
  !gapprompt@gap>| !gapinput@idGs3 := IdentityMapping( Gs3 );;|
  !gapprompt@gap>| !gapinput@V3 := ReplaceOnePieceInUnion( U3, 1, Gs3 ); |
  groupoid with 3 pieces:
  [ Gs3, Gd8, Gc6 ]
  !gapprompt@gap>| !gapinput@images3 := [ PieceImages( idGs3 )[1], |
  !gapprompt@>| !gapinput@                PieceImages( homd8 )[1], |
  !gapprompt@>| !gapinput@                PieceImages( ihomc6 )[1] ];; |
  !gapprompt@gap>| !gapinput@homV3 := HomomorphismToSinglePiece( V3, Gs3, images3 );; |
  !gapprompt@gap>| !gapinput@Display( homV3 );         |
  homomorphism to single piece magma with pieces:
  (1): [ Gs3 ] -> [ Gs3 ]
  magma mapping: [ [ (15,17,19)(16,18,20), (15,20)(16,19)(17,18) ], 
    [ (15,17,19)(16,18,20), (15,20)(16,19)(17,18) ] ]
     object map: [ -36, -35, -34 ] -> [ -36, -35, -34 ]
  (2): [ Gd8 ] -> [ Gs3 ]
  magma mapping: [ [ (1,2,3,4), (1,3) ], [ (), (15,20)(16,19)(17,18) ] ]
     object map: [ -9, -8, -7 ] -> [ -36, -35, -34 ]
  (3): [ Gc6 ] -> [ Gs3 ]
  magma mapping: [ [ (5,6,7)(8,9) ], [ (15,16)(17,20)(18,19) ] ]
     object map: [ -6 ] -> [ -35 ]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Homomorphisms with more than one piece}}\label{sec-genhoms}
\logpage{[ 4, 3, 0 ]}
\hyperdef{L}{X78658D9282AB7137}{}
{
  

\subsection{\textcolor{Chapter }{HomomorphismByUnion}}
\logpage{[ 4, 3, 1 ]}\nobreak
\hyperdef{L}{X86F313DB7EC4D9E7}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HomomorphismByUnion({\mdseries\slshape src, rng, homs})\index{HomomorphismByUnion@\texttt{HomomorphismByUnion}}
\label{HomomorphismByUnion}
}\hfill{\scriptsize (operation)}}\\


 As in section \ref{sec-hompieces}, when the range $H$ has more than one connected component, a homomorphism is a union of
homomorphisms, one for each piece. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@isoq8 := IsomorphismNewObjects( Gq8, [-38,-37] ); |
  groupoid homomorphism : 
  [ 
    [ IdentityMapping( q8 ), [ -38, -37 ], 
        [ <identity> of ..., <identity> of ... ] ] ]
  !gapprompt@gap>| !gapinput@Gq8b := Range( isoq8 );; |
  !gapprompt@gap>| !gapinput@SetName( Gq8b, "Gq8b" ); |
  !gapprompt@gap>| !gapinput@V4 := UnionOfPieces( [ V3, Gq8 ] ); |
  groupoid with 4 pieces:
  [ Gs3, Gq8, Gd8, Gc6 ]
  !gapprompt@gap>| !gapinput@SetName( V4, "V4" ); |
  !gapprompt@gap>| !gapinput@Vs3q8b := UnionOfPieces( [ Gs3, Gq8b ] ); |
  !gapprompt@gap>| !gapinput@SetName( Vs3q8b, "Vs3q8b" ); |
  !gapprompt@gap>| !gapinput@hom4 := HomomorphismByUnion( V4, Vs3q8b, [ homV3, isoq8 ] );; |
  !gapprompt@gap>| !gapinput@PiecesOfMapping( hom4 );|
  [ groupoid homomorphism : Gq8 -> Gq8b
      [ [ IdentityMapping( q8 ), [ -38, -37 ], 
            [ <identity> of ..., <identity> of ... ] ] ], 
    groupoid homomorphism : 
      [ [ IdentityMapping( s3 ), [ -36, -35, -34 ], [ (), (), () ] ], 
        [ GroupHomomorphismByImages( d8, s3, [ (1,2,3,4), (1,3) ], 
              [ (), (15,20)(16,19)(17,18) ] ), [ -36, -35, -34 ], 
            [ (), (), () ] ], 
        [ GroupHomomorphismByImages( c6, s3, [ (5,6,7)(8,9) ], 
              [ (15,16)(17,20)(18,19) ] ), [ -35 ], [ () ] ] ] ]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Groupoid automorphisms}}\label{sec-autos}
\logpage{[ 4, 4, 0 ]}
\hyperdef{L}{X7DE9C2D384323239}{}
{
  

\subsection{\textcolor{Chapter }{GroupoidAutomorphismByObjectPerm}}
\logpage{[ 4, 4, 1 ]}\nobreak
\hyperdef{L}{X79DA704A8051CB72}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GroupoidAutomorphismByObjectPerm({\mdseries\slshape gpd, imobs})\index{GroupoidAutomorphismByObjectPerm@\texttt{GroupoidAutomorphismByObjectPerm}}
\label{GroupoidAutomorphismByObjectPerm}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GroupoidAutomorphismByGroupAuto({\mdseries\slshape gpd, gpauto})\index{GroupoidAutomorphismByGroupAuto@\texttt{GroupoidAutomorphismByGroupAuto}}
\label{GroupoidAutomorphismByGroupAuto}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GroupoidAutomorphismByRayImages({\mdseries\slshape gpd, imrays})\index{GroupoidAutomorphismByRayImages@\texttt{GroupoidAutomorphismByRayImages}}
\label{GroupoidAutomorphismByRayImages}
}\hfill{\scriptsize (operation)}}\\


 We first describe automorphisms $a$ of a groupoid $G$ where $G$ is the direct product of a group $g$ and a complete graph. The group of automorphisms is generated by three types
of automorphism: 
\begin{itemize}
\item  a permutation of the $n$ objects; 
\item  an automorphism of the root group $g$; 
\item  a choice of image for each ray: $a(1 : o_1 \to o_i) = (g_i : o_1 \to o_i)$ for $i \ne 1$. 
\end{itemize}
 

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@a4 := Subgroup( s4, [(1,2,3),(2,3,4)] );; |
  !gapprompt@gap>| !gapinput@SetName( a4, "a4" ); |
  !gapprompt@gap>| !gapinput@gensa4 := GeneratorsOfGroup( a4 );; |
  !gapprompt@gap>| !gapinput@Ga4 := SubgroupoidByPieces( Gs4, [ [a4, [-15,-13,-11]] ] ); |
  single piece groupoid: < a4, [ -15, -13, -11 ] >
  !gapprompt@gap>| !gapinput@SetName( Ga4, "Ga4" ); |
  !gapprompt@gap>| !gapinput@aut1 := GroupoidAutomorphismByObjectPerm( Ga4, [-13,-11,-15] );; |
  !gapprompt@gap>| !gapinput@Display( aut1 ); |
   groupoid mapping: [ Ga4 ] -> [ Ga4 ]
  root homomorphism: [ [ (1,2,3), (2,3,4) ], [ (1,2,3), (2,3,4) ] ]
  images of objects: [ -13, -11, -15 ]
     images of rays: [ (), (), () ]
  !gapprompt@gap>| !gapinput@h2 := GroupHomomorphismByImages( a4, a4, gensa4, [(2,3,4), (1,3,4)] );; |
  !gapprompt@gap>| !gapinput@aut2 := GroupoidAutomorphismByGroupAuto( Ga4, h2 );; |
  !gapprompt@gap>| !gapinput@Display( aut2 ); |
   groupoid mapping: [ Ga4 ] -> [ Ga4 ]
  root homomorphism: [ [ (1,2,3), (2,3,4) ], [ (2,3,4), (1,3,4) ] ]
  images of objects: [ -15, -13, -11 ]
     images of rays: [ (), (), () ]
  !gapprompt@gap>| !gapinput@im3 := [(), (1,3,2), (2,4,3)];; |
  !gapprompt@gap>| !gapinput@aut3 := GroupoidAutomorphismByRayImages( Ga4, im3 );; |
  !gapprompt@gap>| !gapinput@Display( aut3 ); |
   groupoid mapping: [ Ga4 ] -> [ Ga4 ]
  root homomorphism: [ [ (1,2,3), (2,3,4) ], [ (1,2,3), (2,3,4) ] ]
  images of objects: [ -15, -13, -11 ]
     images of rays: [ (), (1,3,2), (2,4,3) ]
  !gapprompt@gap>| !gapinput@aut123 := aut1*aut2*aut3;; |
  !gapprompt@gap>| !gapinput@Display( aut123 ); |
   groupoid mapping: [ Ga4 ] -> [ Ga4 ]
  root homomorphism: [ [ (1,2,3), (2,3,4) ], [ (2,3,4), (1,3,4) ] ]
  images of objects: [ -13, -11, -15 ]
     images of rays: [ (), (1,4,3), (1,2,3) ]
  !gapprompt@gap>| !gapinput@inv123 := InverseGeneralMapping( aut123 );; |
  !gapprompt@gap>| !gapinput@Display( inv123 ); |
   groupoid mapping: [ Ga4 ] -> [ Ga4 ]
  root homomorphism: [ [ (2,3,4), (1,3,4) ], [ (1,2,3), (2,3,4) ] ]
  images of objects: [ -11, -15, -13 ]
     images of rays: [ (), (1,2,4), (1,3,4) ]
  !gapprompt@gap>| !gapinput@id123 := aut123 * inv123;; |
  !gapprompt@gap>| !gapinput@id123 = IdentityMapping( Ga4 ); |
  true
  
\end{Verbatim}
 

 The \index{AutomorphismGroup@\texttt{AutomorphismGroup}} \texttt{AutomorphismGroup} of $G$ is isomorphic to the quotient of $S_n \times A \times g^n$ by a subgroup isomorphic to $g$, where $A$ is the automorphism group of $g$ and $S_n$ is the symmetric group on the $n$ objects. This is one of the main topics in \cite{AlWe}. 

 The current implementation is experimental, producing a \emph{nice monomorphism} from the automorphism group to a pc-group, if one is available. However \texttt{ImageElm} at present only works on generating elements. 

 }

 
\begin{Verbatim}[commandchars=@|D,fontsize=\small,frame=single,label=Example]
  
  @gapprompt|gap>D @gapinput|AGa4 := AutomorphismGroup( Ga4 ); D
  <group with 10 generators>
  @gapprompt|gap>D @gapinput|NGa4 := NiceObject( AGa4 ); D
  Group([ f6, f3, f11*f12, f12, f2, f1, f4*f9, f4^2, f5*f9*f10*f11*f12, f5^2 ])
  @gapprompt|gap>D @gapinput|MGa4 := NiceMonomorphism( AGa4 );; D
  @gapprompt|gap>D @gapinput|Size( AGa4 ); D
  20736
  @gapprompt|gap>D @gapinput|SetName( AGa4, "AGa4" ); D
  @gapprompt|gap>D @gapinput|SetName( NGa4, "NGa4" ); D
  @gapprompt|gap>D @gapinput|Print( MGa4, "\n" ); D
  GroupHomomorphismByImages( AGa4, Group( [ f1, f2, f3, f4, f5, f6, f7, f8, f9, 
    f10, f11, f12 ] ), [ magma with objects homomorphism : Ga4 -> Ga4
      [ [ InnerAutomorphism( a4, (2,4,3) ), [ -15, -13, -11 ], [ (), (), () ] ] 
       ]
      , magma with objects homomorphism : Ga4 -> Ga4
      [ [ ConjugatorAutomorphism( a4, (3,4) ), [ -15, -13, -11 ], 
            [ (), (), () ] ] ]
      , magma with objects homomorphism : Ga4 -> Ga4
      [ [ InnerAutomorphism( a4, (1,2)(3,4) ), [ -15, -13, -11 ], 
            [ (), (), () ] ] ]
      , magma with objects homomorphism : Ga4 -> Ga4
      [ [ InnerAutomorphism( a4, (1,4)(2,3) ), [ -15, -13, -11 ], 
            [ (), (), () ] ] ]
      , magma with objects homomorphism : Ga4 -> Ga4
      [ [ GroupHomomorphismByImages( a4, a4, [ (1,2,3), (2,3,4) ], 
              [ (1,2,3), (2,3,4) ] ), [ -13, -11, -15 ], [ (), (), () ] ] ]
      , magma with objects homomorphism : Ga4 -> Ga4
      [ [ GroupHomomorphismByImages( a4, a4, [ (1,2,3), (2,3,4) ], 
              [ (1,2,3), (2,3,4) ] ), [ -13, -15, -11 ], [ (), (), () ] ] ]
      , magma with objects homomorphism : Ga4 -> Ga4
      [ [ IdentityMapping( a4 ), [ -15, -13, -11 ], [ (), (1,2,3), () ] ] ]
      , magma with objects homomorphism : Ga4 -> Ga4
      [ [ IdentityMapping( a4 ), [ -15, -13, -11 ], [ (), (2,3,4), () ] ] ]
      , magma with objects homomorphism : Ga4 -> Ga4
      [ [ IdentityMapping( a4 ), [ -15, -13, -11 ], [ (), (), (1,2,3) ] ] ]
      , magma with objects homomorphism : Ga4 -> Ga4
      [ [ IdentityMapping( a4 ), [ -15, -13, -11 ], [ (), (), (2,3,4) ] ] ]
       ], [ f6, f3, f11*f12, f12, f2, f1, f4*f9, f4^2, f5*f9*f10*f11*f12, f5^2 
   ] )
  @gapprompt|gap>D @gapinput|##  Now do some tests!D
  @gapprompt|gap>D @gapinput|mgi := MappingGeneratorsImages( MGa4 );; D
  @gapprompt|gap>D @gapinput|autgen := mgi[1];; D
  @gapprompt|gap>D @gapinput|pcgen := mgi[2];;D
  @gapprompt|gap>D @gapinput|ngen := Length( autgen );; D
  @gapprompt|gap>D @gapinput|ForAll( [1..ngen], i -> Order(autgen[i]) = Order(pcgen[i]) ); D
  true 
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{GroupoidAutomorphismByGroupAutos}}
\logpage{[ 4, 4, 2 ]}\nobreak
\hyperdef{L}{X80F9594481CA9FDE}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GroupoidAutomorphismByGroupAutos({\mdseries\slshape gpd, auts})\index{GroupoidAutomorphismByGroupAutos@\texttt{GroupoidAutomorphismByGroupAutos}}
\label{GroupoidAutomorphismByGroupAutos}
}\hfill{\scriptsize (operation)}}\\


 Homogeneous, discrete groupoids are the second type of groupoid for which a
method is provided for \texttt{AutomorphismGroup( gpd )}. This is used in the \textsf{XMod} package for constructing crossed modules of groupoids. The two types of
generating automorphism are \texttt{GroupoidAutomorphismByGroupAutos}, which requires a list of group automorphisms, one for each object group, and \texttt{GroupoidAutomorphismByObjectPerm}, which permutes the objects. 

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@Hs3 := HomogeneousDiscreteGroupoid( s3, [ -13..-10] ); |
  homogeneous, discrete groupoid: < s3, [ -13 .. -10 ] >
  !gapprompt@gap>| !gapinput@aut4 := GroupoidAutomorphismByObjectPerm( Hs3, [-12,-10,-11,-13] ); |
  morphism from a homogeneous discrete groupoid:
  [ -13, -12, -11, -10 ] -> [ -12, -10, -11, -13 ]
  object homomorphisms:
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  
  !gapprompt@gap>| !gapinput@gens3 := GeneratorsOfGroup( s3 );; |
  !gapprompt@gap>| !gapinput@g1 := gens3[1];; |
  !gapprompt@gap>| !gapinput@g2 := gens3[2];; |
  !gapprompt@gap>| !gapinput@b1 := GroupHomomorphismByImages( s3, s3, gens3, [ g1, g2^g1 ] );; |
  !gapprompt@gap>| !gapinput@b2 := GroupHomomorphismByImages( s3, s3, gens3, [ g1^g2, g2 ] );; |
  !gapprompt@gap>| !gapinput@b3 := GroupHomomorphismByImages( s3, s3, gens3, [ g1^g2, g2^(g1*g2) ] );; |
  !gapprompt@gap>| !gapinput@b4 := GroupHomomorphismByImages( s3, s3, gens3, [ g1^(g2*g1), g2^g1 ] );; |
  !gapprompt@gap>| !gapinput@aut5 := GroupoidAutomorphismByGroupAutos( Hs3, [b1,b2,b3,b4] ); |
  morphism from a homogeneous discrete groupoid:
  [ -13, -12, -11, -10 ] -> [ -13, -12, -11, -10 ]
  object homomorphisms:
  GroupHomomorphismByImages( s3, s3, 
  [ (15,17,19)(16,18,20), (15,20)(16,19)(17,18) ], 
  [ (15,17,19)(16,18,20), (15,18)(16,17)(19,20) ] )
  GroupHomomorphismByImages( s3, s3, 
  [ (15,17,19)(16,18,20), (15,20)(16,19)(17,18) ], 
  [ (15,19,17)(16,20,18), (15,20)(16,19)(17,18) ] )
  GroupHomomorphismByImages( s3, s3, 
  [ (15,17,19)(16,18,20), (15,20)(16,19)(17,18) ], 
  [ (15,19,17)(16,20,18), (15,16)(17,20)(18,19) ] )
  GroupHomomorphismByImages( s3, s3, 
  [ (15,17,19)(16,18,20), (15,20)(16,19)(17,18) ], 
  [ (15,19,17)(16,20,18), (15,18)(16,17)(19,20) ] )
  
  !gapprompt@gap>| !gapinput@AHs3 := AutomorphismGroup( Hs3 );;  Size( AHs3 ); |
  31104
  !gapprompt@gap>| !gapinput@for z in GeneratorsOfGroup(AHs3) do Print(z); od;  |
  morphism from a homogeneous discrete groupoid:
  [ -13, -12, -11, -10 ] -> [ -13, -12, -11, -10 ]
  object homomorphisms:
  InnerAutomorphism( s3, (15,20)(16,19)(17,18) )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  morphism from a homogeneous discrete groupoid:
  [ -13, -12, -11, -10 ] -> [ -13, -12, -11, -10 ]
  object homomorphisms:
  InnerAutomorphism( s3, (15,19,17)(16,20,18) )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  morphism from a homogeneous discrete groupoid:
  [ -13, -12, -11, -10 ] -> [ -12, -11, -10, -13 ]
  object homomorphisms:
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  morphism from a homogeneous discrete groupoid:
  [ -13, -12, -11, -10 ] -> [ -12, -13, -11, -10 ]
  object homomorphisms:
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  IdentityMapping( s3 )
  
\end{Verbatim}
 

 }

 }

 }

            
\chapter{\textcolor{Chapter }{Graphs of Groups and Groupoids}}\label{chap-ggraph}
\logpage{[ 5, 0, 0 ]}
\hyperdef{L}{X78063DC8847554B4}{}
{
  This package was originally designed to implement \emph{graphs of groups}, a notion introduced by Serre in \cite{Serre}. It was only when this was extended to \emph{graphs of groupoids} that the functions for groupoids, described in the previous chapters, were
required. The methods described here are based on Philip Higgins' paper \cite{HiJLMS}. For further details see Chapter 2 of \cite{emma-thesis}. Since a graph of groups involves a directed graph, with a group associated
to each vertex and arc, we first define digraphs with edges weighted by the
generators of a free group. 
\section{\textcolor{Chapter }{Digraphs}}\label{sec-dgph}
\logpage{[ 5, 1, 0 ]}
\hyperdef{L}{X7D554C5D7FDC3D02}{}
{
  

\subsection{\textcolor{Chapter }{FpWeightedDigraph}}
\logpage{[ 5, 1, 1 ]}\nobreak
\hyperdef{L}{X85BD6D2584D8A22F}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{FpWeightedDigraph({\mdseries\slshape verts, arcs})\index{FpWeightedDigraph@\texttt{FpWeightedDigraph}}
\label{FpWeightedDigraph}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsFpWeightedDigraph({\mdseries\slshape dig})\index{IsFpWeightedDigraph@\texttt{IsFpWeightedDigraph}}
\label{IsFpWeightedDigraph}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{InvolutoryArcs({\mdseries\slshape dig})\index{InvolutoryArcs@\texttt{InvolutoryArcs}}
\label{InvolutoryArcs}
}\hfill{\scriptsize (attribute)}}\\


 A \emph{weighted digraph} is a record with two components: \emph{vertices}, which are usually taken to be positive integers (to distinguish them from
the objects in a groupoid); and \emph{arcs}, which take the form of 3-element lists \texttt{[weight,tail,head]}. The \emph{tail} and \emph{head} are the two vertices of the arc. The \emph{weight} is taken to be an element of a finitely presented group, so as to produce
digraphs of type \texttt{IsFpWeightedDigraph}. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@V1 := [ 5, 6 ];;|
  !gapprompt@gap>| !gapinput@fg1 := FreeGroup( "y" );;|
  !gapprompt@gap>| !gapinput@y := fg1.1;;|
  !gapprompt@gap>| !gapinput@A1 := [ [ y, 5, 6 ], [ y^-1, 6, 5 ] ];|
  !gapprompt@gap>| !gapinput@D1 := FpWeightedDigraph( fg1, V1, A1 );|
  weighted digraph with vertices: [ 5, 6 ]
  and arcs: [ [ y, 5, 6 ], [ y^-1, 6, 5 ] ]
  !gapprompt@gap>| !gapinput@inv1 := InvolutoryArcs( D1 );|
  [ 2, 1 ]
  
\end{Verbatim}
 The example illustrates the fact that we require arcs to be defined in
involutory pairs, as though they were inverse elements in a groupoid. We may
in future decide just to give \texttt{[y,5,6]} as the data and get the function to construct the reverse edge. The attribute \texttt{InvolutoryArcs} returns a list of the positions of each inverse arc in the list of arcs. In
the second example the graph is a complete digraph on three vertices. 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@fg3 := FreeGroup( 3, "z" );;|
  !gapprompt@gap>| !gapinput@z1 := fg3.1;;  z2 := fg3.2;;  z3 := fg3.3;;|
  !gapprompt@gap>| !gapinput@V3 := [ 7, 8, 9 ];;|
  !gapprompt@gap>| !gapinput@A3 := [[z1,7,8],[z2,8,9],[z3,9,7],[z1^-1,8,7],[z2^-1,9,8],[z3^-1,7,9]];;|
  !gapprompt@gap>| !gapinput@D3 := FpWeightedDigraph( fg3, V3, A3 );|
  weighted digraph with vertices: [ 7, 8, 9 ]
  and arcs: [ [ z1, 7, 8 ], [ z2, 8, 9 ], [ z3, 9, 7 ], [ z1^-1, 8, 7 ],
    [ z2^-1, 9, 8 ], [ z3^-1, 7, 9 ] ]
  [gap> inv3 := InvolutoryArcs( D3 );
  [ 4, 5, 6, 1, 2, 3 ]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Graphs of Groups}}\label{sec-gphgps}
\logpage{[ 5, 2, 0 ]}
\hyperdef{L}{X7BAFCA3680E478AE}{}
{
  

\subsection{\textcolor{Chapter }{GraphOfGroups}}
\logpage{[ 5, 2, 1 ]}\nobreak
\hyperdef{L}{X8130246E854BC5D9}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GraphOfGroups({\mdseries\slshape dig, gps, isos})\index{GraphOfGroups@\texttt{GraphOfGroups}}
\label{GraphOfGroups}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DigraphOfGraphOfGroups({\mdseries\slshape gg})\index{DigraphOfGraphOfGroups@\texttt{DigraphOfGraphOfGroups}}
\label{DigraphOfGraphOfGroups}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GroupsOfGraphOfGroups({\mdseries\slshape gg})\index{GroupsOfGraphOfGroups@\texttt{GroupsOfGraphOfGroups}}
\label{GroupsOfGraphOfGroups}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsomorphismsOfGraphOfGroups({\mdseries\slshape gg})\index{IsomorphismsOfGraphOfGroups@\texttt{IsomorphismsOfGraphOfGroups}}
\label{IsomorphismsOfGraphOfGroups}
}\hfill{\scriptsize (attribute)}}\\


 A graph of groups is traditionally defined as consisting of: 
\begin{itemize}
\item  a digraph with involutory pairs of arcs; 
\item  a \emph{vertex group} associated to each vertex; 
\item  a group associated to each pair of arcs; 
\item  an injective homomorphism from each arc group to the group at the head of the
arc. 
\end{itemize}
 We have found it more convenient to associate to each arc: 
\begin{itemize}
\item  a subgroup of the vertex group at the tail; 
\item  a subgroup of the vertex group at the head; 
\item  an isomorphism between these subgroups, such that each involutory pair of arcs
determines inverse isomorphisms. 
\end{itemize}
 These two viewpoints are clearly equivalent. 

 In this implementation we require that all subgroups are of finite index in
the vertex groups. 

 The three attributes provide a means of calling the three items of data in the
construction of a graph of groups. 

 We shall be representing free products with amalgamation of groups and HNN
extensions of groups, so we take as our first example the trefoil group with
generators $a,b$ and relation $a^3=b^2$. For this we take digraph \texttt{D1} above with an infinite cyclic group at each vertex, generated by $a$ and $b$ respectively. The two subgroups will be generated by $a^3$ and $b^2$ with the obvious isomorphisms. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@## free vertex group at 5|
  !gapprompt@gap>| !gapinput@fa := FreeGroup( "a" );;|
  !gapprompt@gap>| !gapinput@a := fa.1;;|
  !gapprompt@gap>| !gapinput@SetName( fa, "fa" );|
  !gapprompt@gap>| !gapinput@hy := Subgroup( fa, [a^3] );;|
  !gapprompt@gap>| !gapinput@SetName( hy, "hy" );|
  !gapprompt@gap>| !gapinput@## free vertex group at 6|
  !gapprompt@gap>| !gapinput@fb := FreeGroup( "b" );;|
  !gapprompt@gap>| !gapinput@b := fb.1;;|
  !gapprompt@gap>| !gapinput@SetName( fb, "fb" );|
  !gapprompt@gap>| !gapinput@hybar := Subgroup( fb, [b^2] );;|
  !gapprompt@gap>| !gapinput@SetName( hybar, "hybar" );|
  !gapprompt@gap>| !gapinput@## isomorphisms between subgroups|
  !gapprompt@gap>| !gapinput@homy := GroupHomomorphismByImagesNC( hy, hybar, [a^3], [b^2] );;|
  !gapprompt@gap>| !gapinput@homybar := GroupHomomorphismByImagesNC( hybar, hy, [b^2], [a^3] );;|
  !gapprompt@gap>| !gapinput@## defining graph of groups G1|
  !gapprompt@gap>| !gapinput@G1 := GraphOfGroups( D1, [fa,fb], [homy,homybar] );|
  Graph of Groups: 2 vertices; 2 arcs; groups [ fa, fb ]
  !gapprompt@gap>| !gapinput@Display( G1 );|
  Graph of Groups with :-
      vertices: [ 5, 6 ]
          arcs: [ [ y, 5, 6 ], [ y^-1, 6, 5 ] ]
        groups: [ fa, fb ]
  isomorphisms: [ [ [ a^3 ], [ b^2 ] ], [ [ b^2 ], [ a^3 ] ] ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{IsGraphOfFpGroups}}
\logpage{[ 5, 2, 2 ]}\nobreak
\hyperdef{L}{X847464677F641527}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsGraphOfFpGroups({\mdseries\slshape gg})\index{IsGraphOfFpGroups@\texttt{IsGraphOfFpGroups}}
\label{IsGraphOfFpGroups}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsGraphOfPcGroups({\mdseries\slshape gg})\index{IsGraphOfPcGroups@\texttt{IsGraphOfPcGroups}}
\label{IsGraphOfPcGroups}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsGraphOfPermGroups({\mdseries\slshape gg})\index{IsGraphOfPermGroups@\texttt{IsGraphOfPermGroups}}
\label{IsGraphOfPermGroups}
}\hfill{\scriptsize (property)}}\\


 This is a list of properties to be expected of a graph of groups. In principle
any type of group known to \textsf{GAP} may be used as vertex groups, though these types are not normally mixed in a
single structure. }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@IsGraphOfFpGroups( G1 );|
  true
  !gapprompt@gap>| !gapinput@IsomorphismsOfGraphOfGroups( G1 );|
  [ GroupHomomorphismByImages( hy, hybar, [ a^3 ], [ b^2 ] ), 
    GroupHomomorphismByImages( hybar, hy, [ b^2 ], [ a^3 ] ) ]
  
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{RightTransversalsOfGraphOfGroups}}
\logpage{[ 5, 2, 3 ]}\nobreak
\hyperdef{L}{X7B036C2B84E48BB1}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RightTransversalsOfGraphOfGroups({\mdseries\slshape gg})\index{RightTransversalsOfGraphOfGroups@\texttt{RightTransversalsOfGraphOfGroups}}
\label{RightTransversalsOfGraphOfGroups}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{LeftTransversalsOfGraphOfGroups({\mdseries\slshape gg})\index{LeftTransversalsOfGraphOfGroups@\texttt{LeftTransversalsOfGraphOfGroups}}
\label{LeftTransversalsOfGraphOfGroups}
}\hfill{\scriptsize (attribute)}}\\


 Computation with graph of groups words will require, for each arc subgroup \texttt{ha}, a set of representatives for the left cosets of \texttt{ha} in the tail vertex group. As already pointed out, we require subgroups of
finite index. Since \textsf{GAP} prefers to provide right cosets, we obtain the right representatives first,
and then invert them. 

 When the vertex groups are of type \texttt{FpGroup} we shall require normal forms for these groups, so we assume that such vertex
groups are provided with Knuth Bendix rewriting systems using functions from
the main \textsf{GAP} library, (e.g. \texttt{IsomorphismFpSemigroup}). 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@RTG1 := RightTransversalsOfGraphOfGroups( G1 );|
  [ [ <identity ...>, a, a^2 ], [ <identity ...>, b ] ]
  !gapprompt@gap>| !gapinput@LTG1 := LeftTransversalsOfGraphOfGroups( G1 );|
  [ [ <identity ...>, a^-1, a^-2 ], [ <identity ...>, b^-1 ] ] 
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Words in a Graph of Groups and their normal forms}}\label{sec-words}
\logpage{[ 5, 3, 0 ]}
\hyperdef{L}{X7BD9DCF87FB3E0AF}{}
{
  

\subsection{\textcolor{Chapter }{GraphOfGroupsWord}}
\logpage{[ 5, 3, 1 ]}\nobreak
\hyperdef{L}{X87937AE47C5B1018}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GraphOfGroupsWord({\mdseries\slshape gg, tv, list})\index{GraphOfGroupsWord@\texttt{GraphOfGroupsWord}}
\label{GraphOfGroupsWord}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsGraphOfGroupsWord({\mdseries\slshape w})\index{IsGraphOfGroupsWord@\texttt{IsGraphOfGroupsWord}}
\label{IsGraphOfGroupsWord}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GraphOfGroupsOfWord({\mdseries\slshape w})\index{GraphOfGroupsOfWord@\texttt{GraphOfGroupsOfWord}}
\label{GraphOfGroupsOfWord}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{WordOfGraphOfGroupsWord({\mdseries\slshape w})\index{WordOfGraphOfGroupsWord@\texttt{WordOfGraphOfGroupsWord}}
\label{WordOfGraphOfGroupsWord}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GGTail({\mdseries\slshape w})\index{GGTail@\texttt{GGTail}}
\label{GGTail}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GGHead({\mdseries\slshape w})\index{GGHead@\texttt{GGHead}}
\label{GGHead}
}\hfill{\scriptsize (attribute)}}\\


 If \texttt{G} is a graph of groups with underlying digraph \texttt{D}, the following groupoids may be considered. First there is the free groupoid
or path groupoid on \texttt{D}. Since we want each involutory pair of arcs to represent inverse elements in
the groupoid, we quotient out by the relations \texttt{y\texttt{\symbol{92}}\texttt{\symbol{94}}\texttt{\symbol{123}}\texttt{\symbol{125}}-1
= ybar} to obtain \texttt{PG(D)}. Secondly, there is the discrete groupoid \texttt{VG(D)}, namely the union of all the vertex groups. Since these two groupoids have
the same object set (the vertices of \texttt{D}) we can form \texttt{A(G)}, the free product of \texttt{PG(D)} and \texttt{VG(D)} amalgamated over the vertices. For further details of this universal groupoid
construction see \cite{emma-thesis}. (Note that these groupoids are not implemented in this package.) 

 An element of \texttt{A(G)} is a graph of groups word which may be represented by a list of the form $w = [g_1,y_1,g_2,y_2,...,g_n,y_n,g_{n+1}]$. Here each $y_i$ is an arc of \texttt{D}; the head of $y_{i-1}$ is a vertex $v_i$ which is also the tail of $y_i$; and $g_i$ is an element of the vertex group at $v_i$. 

 The attributes \texttt{GGTail} and \texttt{GGHead} are \emph{temporary} names for the tail and head of a graph of groups word, and are likely to be
replaced in future versions. 

 So a graph of groups word requires as data the graph of groups; the tail
vertex for the word; and a list of arcs and group elements. We may specify
each arc by its position in the list of arcs. 

 In the following example, where \texttt{gw1} is a word in the trefoil graph of groups, the $y_i$ are specified by their positions in \texttt{A1}. Both arcs are traversed twice, so the resulting word is a loop at vertex $5$. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@L1 := [ a^7, 1, b^-6, 2, a^-11, 1, b^9, 2, a^7 ];;|
  !gapprompt@gap>| !gapinput@gw1 := GraphOfGroupsWord( G1, 5, L1 );|
  (5)a^7.y.b^-6.y^-1.a^-11.y.b^9.y^-1.a^7(5)
  !gapprompt@gap>| !gapinput@IsGraphOfGroupsWord( gw1 );|
  true
  !gapprompt@gap>| !gapinput@[ GGTail(gw1), GGHead(gw1) ];|
  [ 5, 5 ]
  !gapprompt@gap>| !gapinput@GraphOfGroupsOfWord(gw1);|
  Graph of Groups: 2 vertices; 2 arcs; groups [ fa, fb ]
  !gapprompt@gap>| !gapinput@WordOfGraphOfGroupsWord( gw1 );|
  [ a^7, 1, b^-6, 2, a^-11, 1, b^9, 2, a^7 ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{ReducedGraphOfGroupsWord}}
\logpage{[ 5, 3, 2 ]}\nobreak
\hyperdef{L}{X78FA7C3F831AA6E4}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ReducedGraphOfGroupsWord({\mdseries\slshape w})\index{ReducedGraphOfGroupsWord@\texttt{ReducedGraphOfGroupsWord}}
\label{ReducedGraphOfGroupsWord}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsReducedGraphOfGroupsWord({\mdseries\slshape w})\index{IsReducedGraphOfGroupsWord@\texttt{IsReducedGraphOfGroupsWord}}
\label{IsReducedGraphOfGroupsWord}
}\hfill{\scriptsize (property)}}\\


 A graph of groups word may be reduced in two ways, to give a normal form.
Firstly, if part of the word has the form \texttt{[yi, identity, yibar]} then this subword may be omitted. This is known as a length reduction.
Secondly there are coset reductions. Working from the left-hand end of the
word, subwords of the form $[g_i,y_i,g_{i+1}]$ are replaced by $[t_i,y_i,m_i(h_i)*g_{i+1}]$ where $g_i = t_i*h_i$ is the unique factorisation of $g_i$ as a left coset representative times an element of the arc subgroup, and $m_i$ is the isomorphism associated to $y_i$. Thus we may consider a coset reduction as passing a subgroup element along
an arc. The resulting normal form (if no length reductions have taken place)
is then $[t_1,y_1,t_2,y_2,...,t_n,y_n,k]$ for some $k$ in the head group of $y_n$. For further details see Section 2.2 of \cite{emma-thesis}. 

 The reduction of the word \texttt{gw1} in our example includes one length reduction. The four stages of the reduction
are as follows: 
\[ a^7b^{-6}a^{-11}b^9a^7 ~\mapsto~ a^{-2}b^0a^{-11}b^9a^7 ~\mapsto~
a^{-13}b^9a^7 ~\mapsto~ a^{-1}b^{-8}b^9a^7 ~\mapsto~ a^{-1}b^{-1}a^{10}. \]
 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@nw1 := ReducedGraphOfGroupsWord( gw1 );|
  (5)a^-1.y.b^-1.y^-1.a^10(5)
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Free products with amalgamation and HNN extensions}}\label{sec-fpahnn}
\logpage{[ 5, 4, 0 ]}
\hyperdef{L}{X7D99A7B37B36BAA8}{}
{
  

\subsection{\textcolor{Chapter }{FreeProductWithAmalgamation}}
\logpage{[ 5, 4, 1 ]}\nobreak
\hyperdef{L}{X795AB71F7E370119}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{FreeProductWithAmalgamation({\mdseries\slshape gp1, gp2, iso})\index{FreeProductWithAmalgamation@\texttt{FreeProductWithAmalgamation}}
\label{FreeProductWithAmalgamation}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsFpaGroup({\mdseries\slshape fpa})\index{IsFpaGroup@\texttt{IsFpaGroup}}
\label{IsFpaGroup}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GraphOfGroupsRewritingSystem({\mdseries\slshape fpa})\index{GraphOfGroupsRewritingSystem@\texttt{GraphOfGroupsRewritingSystem}}
\label{GraphOfGroupsRewritingSystem}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{NormalFormGGRWS({\mdseries\slshape fpa, word})\index{NormalFormGGRWS@\texttt{NormalFormGGRWS}}
\label{NormalFormGGRWS}
}\hfill{\scriptsize (attribute)}}\\


 As we have seen with the trefoil group example, graphs of groups can be used
to obtain a normal form for free products with amalgamation $G_1 *_H G_2$ when $G_1, G_2$ both have rewrite systems, and $H$ is of finite index in both $G_1$ and $G_2$. 

 When \texttt{gp1} and \texttt{gp2} are fp-groups, the operation \texttt{FreeProductWithAmalgamation} constructs the required fp-group. When the two groups are permutation groups,
the \texttt{IsomorphismFpGroup} operation is called on both \texttt{gp1} and \texttt{gp2}, and the resulting isomorphism is transported to one between the two new
subgroups. 

 The attribute \texttt{GraphOfGroupsRewritingSystem} of \texttt{fpa} is the graph of groups which has underlying digraph \texttt{D1}, with two vertices and two arcs; the two groups as vertex groups; and the
specified isomorphisms on the arcs. Despite the name, graphs of groups
constructed in this way \emph{do not} belong to the category \texttt{IsRewritingSystem}. This anomaly may be dealt with when time permits. 

 The example below shows a computation in the the free product of the symmetric \texttt{s3} and the alternating \texttt{a4}, amalgamated over a cyclic subgroup \texttt{c3}. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@## set up the first group s3 and a subgroup c3=<a1>|
  !gapprompt@gap>| !gapinput@fg2 := FreeGroup( 2, "a" );;|
  !gapprompt@gap>| !gapinput@rel1 := [ fg2.1^3, fg2.2^2, (fg2.1*fg2.2)^2 ];;|
  !gapprompt@gap>| !gapinput@s3 := fg2/rel1;;|
  !gapprompt@gap>| !gapinput@gs3 := GeneratorsOfGroup(s3);;|
  !gapprompt@gap>| !gapinput@SetName( s3, "s3" );|
  !gapprompt@gap>| !gapinput@a1 := gs3[1];;  a2 := gs3[2];;|
  !gapprompt@gap>| !gapinput@H1 := Subgroup(s3,[a1]);;|
  !gapprompt@gap>| !gapinput@## then the second group a4 and subgroup c3=<b1>|
  !gapprompt@gap>| !gapinput@f2 := FreeGroup( 2, "b" );;|
  !gapprompt@gap>| !gapinput@rel2 := [ f2.1^3, f2.2^3, (f2.1*f2.2)^2 ];;|
  !gapprompt@gap>| !gapinput@a4 := f2/rel2;;|
  !gapprompt@gap>| !gapinput@ga4 := GeneratorsOfGroup(a4);;|
  !gapprompt@gap>| !gapinput@SetName( a4, "a4" );|
  !gapprompt@gap>| !gapinput@b1 := ga4[1];  b2 := ga4[2];;|
  !gapprompt@gap>| !gapinput@H2 := Subgroup(a4,[b1]);;|
  !gapprompt@gap>| !gapinput@## form the isomorphism and the fpa group|
  !gapprompt@gap>| !gapinput@iso := GroupHomomorphismByImages(H1,H2,[a1],[b1]);;|
  !gapprompt@gap>| !gapinput@fpa := FreeProductWithAmalgamation( s3, a4, iso );|
  <fp group on the generators [ fa1, fa2, fa3, fa4 ]>
  !gapprompt@gap>| !gapinput@RelatorsOfFpGroup( fpa );|
  [ fa1^3, fa2^2, (fa1*fa2)^2, fa3^3, fa4^3, (fa3*fa4)^2, fa1*fa3^-1 ]
  !gapprompt@gap>| !gapinput@gg1 := GraphOfGroupsRewritingSystem( fpa );;|
  !gapprompt@gap>| !gapinput@Display( gg1 );|
  Graph of Groups with :-
      vertices: [ 5, 6 ]
          arcs: [ [ y, 5, 6 ], [ y^-1, 6, 5 ] ]
        groups: [ s3, a4 ]
  isomorphisms: [ [ [ a1 ], [ b1 ] ], [ [ b1 ], [ a1 ] ] ]
  !gapprompt@gap>| !gapinput@LeftTransversalsOfGraphOfGroups( gg1 );|
  [ [ <identity ..>, a2^-1 ], [ <identity ..>, b2^-1, b1^-1*b2^-1, b1*b2^-1 ] ]
  !gapprompt@gap>| !gapinput@## choose a word in fpa and find its normal form |
  !gapprompt@gap>| !gapinput@gfpa := GeneratorsOfGroup( fpa );;|
  !gapprompt@gap>| !gapinput@w2 := (gfpa[1]*gfpa[2]*gfpa[3]^gfpa[4])^3;|
  (fa1*fa2*fa4^-1*fa3*fa4)^3
  !gapprompt@gap>| !gapinput@n2 := NormalFormGGRWS( fpa, w2 );|
  fa2*fa3*(fa4^-1*fa2)^2*fa4^-1*fa3
  
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{HnnExtension}}
\logpage{[ 5, 4, 2 ]}\nobreak
\hyperdef{L}{X7CB0F120804A8DED}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HnnExtension({\mdseries\slshape gp, iso})\index{HnnExtension@\texttt{HnnExtension}}
\label{HnnExtension}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsHnnGroup({\mdseries\slshape hnn})\index{IsHnnGroup@\texttt{IsHnnGroup}}
\label{IsHnnGroup}
}\hfill{\scriptsize (property)}}\\


 For \emph{HNN extensions}, the appropriate graph of groups has underlying digraph with just one vertex
and one pair of loops, weighted with \texttt{FpGroup} generators $z,z^{-1}$. There is one vertex group \texttt{G}, two isomorphic subgroups \texttt{H1,H2} of \texttt{G}, with the isomorphism and its inverse on the loops. The presentation of the
extension has one more generator than that of \texttt{G} and corresponds to the generator $z$. 

 The functions \texttt{GraphOfGroupsRewritingSystem} and \texttt{NormalFormGGRWS} may be applied to hnn-groups as well as to fpa-groups. 

 In the example we take \texttt{G=a4} and the two subgroups are cyclic groups of order 3. }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@H3 := Subgroup(a4,[b2]);;|
  !gapprompt@gap>| !gapinput@i23 := GroupHomomorphismByImages( H2, H3, [b1], [b2] );;|
  !gapprompt@gap>| !gapinput@hnn := HnnExtension( a4, i23 );|
  <fp group on the generators [ fe1, fe2, fe3 ]> 
  !gapprompt@gap>| !gapinput@phnn := PresentationFpGroup( hnn );;|
  !gapprompt@gap>| !gapinput@TzPrint( phnn );|
  #I  generators: [ fe1, fe2, fe3 ]
  #I  relators:
  #I  1.  3  [ 1, 1, 1 ]
  #I  2.  3  [ 2, 2, 2 ]
  #I  3.  4  [ 1, 2, 1, 2 ]
  #I  4.  4  [ -3, 1, 3, -2 ] 
  !gapprompt@gap>| !gapinput@gg2 := GraphOfGroupsRewritingSystem( hnn );|
  Graph of Groups: 1 vertices; 2 arcs; groups [ a4 ]
  !gapprompt@gap>| !gapinput@LeftTransversalsOfGraphOfGroups( gg2 );|
  [ [ <identity ...>, b2^-1, b1^-1*b2^-1, b1*b2^-1 ],
    [ <identity ...>, b1^-1, b1, b2^-1*b1 ] ]
  !gapprompt@gap>| !gapinput@gh := GeneratorsOfGroup( hnn );;|
  !gapprompt@gap>| !gapinput@w3 := (gh[1]^gh[2])*gh[3]^-1*(gh[1]*gh[3]*gh[2]^2)^2*gh[3]*gh[2];|
  fe2^-1*fe1*fe2*fe3^-1*(fe1*fe3*fe2^2)^2*fe3*fe2
  !gapprompt@gap>| !gapinput@n3 := NormalFormGGRWS( hnn, w3 );|
  (fe2*fe1*fe3)^2
  
\end{Verbatim}
 Both fpa-groups and hnn-groups are provided with a record attribute, \texttt{FpaInfo(fpa)} and \texttt{HnnInfo(hnn)} respectively, storing the groups and isomorphisms involved in their
construction. 

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@fpainfo := FpaInfo( fpa );|
  rec( groups := [ s3, a4 ], positions := [ [ 1, 2 ], [ 3, 4 ] ],
    isomorphism := [ a1 ] -> [ b1 ] )
  !gapprompt@gap>| !gapinput@hnninfo := HnnInfo( hnn );|
  rec( group := a4, isomorphism := [ b1 ] -> [ b2 ] )
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{GraphsOfGroupoids and their Words}}\label{sec-gphgpds}
\logpage{[ 5, 5, 0 ]}
\hyperdef{L}{X78108FB4814AE887}{}
{
  

\subsection{\textcolor{Chapter }{GraphOfGroupoids}}
\logpage{[ 5, 5, 1 ]}\nobreak
\hyperdef{L}{X8739267678808E85}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GraphOfGroupoids({\mdseries\slshape dig, gpds, subgpds, isos})\index{GraphOfGroupoids@\texttt{GraphOfGroupoids}}
\label{GraphOfGroupoids}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsGraphOfPermGroupoids({\mdseries\slshape gg})\index{IsGraphOfPermGroupoids@\texttt{IsGraphOfPermGroupoids}}
\label{IsGraphOfPermGroupoids}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsGraphOfFpGroupoids({\mdseries\slshape gg})\index{IsGraphOfFpGroupoids@\texttt{IsGraphOfFpGroupoids}}
\label{IsGraphOfFpGroupoids}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GroupoidsOfGraphOfGroupoids({\mdseries\slshape gg})\index{GroupoidsOfGraphOfGroupoids@\texttt{GroupoidsOfGraphOfGroupoids}}
\label{GroupoidsOfGraphOfGroupoids}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DigraphOfGraphOfGroupoids({\mdseries\slshape gg})\index{DigraphOfGraphOfGroupoids@\texttt{DigraphOfGraphOfGroupoids}}
\label{DigraphOfGraphOfGroupoids}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SubgroupoidsOfGraphOfGroupoids({\mdseries\slshape gg})\index{SubgroupoidsOfGraphOfGroupoids@\texttt{SubgroupoidsOfGraphOfGroupoids}}
\label{SubgroupoidsOfGraphOfGroupoids}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsomorphismsOfGraphOfGroupoids({\mdseries\slshape gg})\index{IsomorphismsOfGraphOfGroupoids@\texttt{IsomorphismsOfGraphOfGroupoids}}
\label{IsomorphismsOfGraphOfGroupoids}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RightTransversalsOfGraphOfGroupoids({\mdseries\slshape gg})\index{RightTransversalsOfGraphOfGroupoids@\texttt{RightTransversalsOfGraphOfGroupoids}}
\label{RightTransversalsOfGraphOfGroupoids}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{LeftTransversalsOfGraphOfGroupoids({\mdseries\slshape gg})\index{LeftTransversalsOfGraphOfGroupoids@\texttt{LeftTransversalsOfGraphOfGroupoids}}
\label{LeftTransversalsOfGraphOfGroupoids}
}\hfill{\scriptsize (attribute)}}\\


 Graphs of groups generalise naturally to graphs of groupoids, forming the
class \texttt{IsGraphOfGroupoids}. There is now a groupoid at each vertex and the isomorphism on an arc
identifies wide subgroupoids at the tail and at the head. Since all
subgroupoids are wide, every groupoid in a connected constituent of the graph
has the same number of objects, but there is no requirement that the object
sets are all the same. 

 The example below generalises the trefoil group example in subsection 4.4.1,
taking at each vertex of \texttt{D1} a two-object groupoid with a free group on one generator, and full
subgroupoids with groups $\langle a^3 \rangle$ and $\langle b^2 \rangle$. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@Gfa := SinglePieceGroupoid( fa, [-2,-1] );;|
  !gapprompt@gap>| !gapinput@ofa := One( fa );;|
  !gapprompt@gap>| !gapinput@SetName( Gfa, "Gfa" );|
  !gapprompt@gap>| !gapinput@Uhy := Subgroupoid( Gfa, [ [[-2,-1], hy ] ] );;|
  !gapprompt@gap>| !gapinput@SetName( Uhy, "Uhy" );|
  !gapprompt@gap>| !gapinput@Gfb := SinglePieceGroupoid( fb, [-4,-3] );;|
  !gapprompt@gap>| !gapinput@ofb := One( fb );;|
  !gapprompt@gap>| !gapinput@SetName( Gfb, "Gfb" );|
  !gapprompt@gap>| !gapinput@Uhybar := Subgroupoid( Gfb, [ [[-4,-3], hybar ] ] );;|
  !gapprompt@gap>| !gapinput@SetName( Uhybar, "Uhybar" );|
  !gapprompt@gap>| !gapinput@mory := GroupoidMappingOfSinglePieces( |
  !gapprompt@gap>| !gapinput@     Uhy, Uhybar, homy, [-4,-3], [ofb,ofb] );;|
  !gapprompt@gap>| !gapinput@morybar := GroupoidMappingOfSinglePieces( |
  !gapprompt@gap>| !gapinput@     Uhybar, Uhy, homybar, [-2,-1], [ofa,ofa] );;|
  !gapprompt@gap>| !gapinput@gg3 := GraphOfGroupoids( D1, [Gfa,Gfb], [Uhy,Uhybar], [mory,morybar] );;|
  !gapprompt@gap>| !gapinput@Display( gg3 );|
  Graph of Groupoids with :- 
      vertices: [ 5, 6 ]
          arcs: [ [ y, 5, 6 ], [ y^-1, 6, 5 ] ]
     groupoids: 
  fp single piece groupoid: Gfa
    objects: [ -2, -1 ]
      group: fa = <[ a ]>
  fp single piece groupoid: Gfb
    objects: [ -4, -3 ]
      group: fb = <[ b ]>
  subgroupoids: single piece groupoid: Uhy
    objects: [ -2, -1 ]
      group: hy = <[ a^3 ]>
  single piece groupoid: Uhybar
    objects: [ -4, -3 ]
      group: hybar = <[ b^2 ]>
  isomorphisms: [ groupoid homomorphism : Uhy -> Uhybar
      [ [ GroupHomomorphismByImages( hy, hybar, [ a^3 ], [ b^2 ] ), [ -4, -3 ], 
            [ <identity ...>, <identity ...> ] ] ], 
    groupoid homomorphism : Uhybar -> Uhy
      [ [ GroupHomomorphismByImages( hybar, hy, [ b^2 ], [ a^3 ] ), [ -2, -1 ], 
            [ <identity ...>, <identity ...> ] ] ] ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{GraphOfGroupoidsWord}}
\logpage{[ 5, 5, 2 ]}\nobreak
\hyperdef{L}{X7EC1A9067FC91255}{}
{\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GraphOfGroupoidsWord({\mdseries\slshape gg, tv, list})\index{GraphOfGroupoidsWord@\texttt{GraphOfGroupoidsWord}}
\label{GraphOfGroupoidsWord}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsGraphOfGroupoidsWord({\mdseries\slshape w})\index{IsGraphOfGroupoidsWord@\texttt{IsGraphOfGroupoidsWord}}
\label{IsGraphOfGroupoidsWord}
}\hfill{\scriptsize (property)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GraphOfGroupoidsOfWord({\mdseries\slshape w})\index{GraphOfGroupoidsOfWord@\texttt{GraphOfGroupoidsOfWord}}
\label{GraphOfGroupoidsOfWord}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{WordOfGraphOfGroupoidsWord({\mdseries\slshape w})\index{WordOfGraphOfGroupoidsWord@\texttt{WordOfGraphOfGroupoidsWord}}
\label{WordOfGraphOfGroupoidsWord}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ReducedGraphOfGroupoidsWord({\mdseries\slshape w})\index{ReducedGraphOfGroupoidsWord@\texttt{ReducedGraphOfGroupoidsWord}}
\label{ReducedGraphOfGroupoidsWord}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsReducedGraphOfGroupoidsWord({\mdseries\slshape w})\index{IsReducedGraphOfGroupoidsWord@\texttt{IsReducedGraphOfGroupoidsWord}}
\label{IsReducedGraphOfGroupoidsWord}
}\hfill{\scriptsize (property)}}\\


 Having produced the graph of groupoids \texttt{gg3}, we may construct left coset representatives; choose a graph of groupoids
word; and reduce this to normal form. Compare the \texttt{nw3} below with the normal form \texttt{nw1} in subsection 4.3.2. 

 }

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@f1 := Arrow( Gfa, a^7, -1, -2);;|
  !gapprompt@gap>| !gapinput@f2 := Arrow( Gfb, b^-6, -4, -4 );;|
  !gapprompt@gap>| !gapinput@f3 := Arrow( Gfa, a^-11, -2, -1 );;|
  !gapprompt@gap>| !gapinput@f4 := Arrow( Gfb, b^9, -3, -4 );;|
  !gapprompt@gap>| !gapinput@f5 := Arrow( Gfa, a^7, -2, -1 );;|
  !gapprompt@gap>| !gapinput@L3 := [ f1, 1, f2, 2, f3, 1, f4, 2, f5 ];|
  [ [a^7 : -1 -> -2], 1, [b^-6 : -4 -> -4], 2, [a^-11 : -2 -> -1], 1, 
    [b^9 : -3 -> -4], 2, [a^7 : -2 -> -1] ]
  !gapprompt@gap>| !gapinput@gw3 := GraphOfGroupoidsWord( gg3, 5, L3);|
  (5)[a^7 : -1 -> -2].y.[b^-6 : -4 -> -4].y^-1.[a^-11 : -2 -> -1].y.[b^9 : 
  -3 -> -4].y^-1.[a^7 : -2 -> -1](5)
  !gapprompt@gap>| !gapinput@nw3 := ReducedGraphOfGroupoidsWord( gw3 );|
  (5)[a^-1 : -1 -> -2].y.[b^-1 : -4 -> -4].y^-1.[a^10 : -2 -> -1](5)
  
\end{Verbatim}
 }

 More examples of these operations may be found in the example file \texttt{gpd/examples/ggraph.g}. }

            
\chapter{\textcolor{Chapter }{Technical Notes}}\label{chap-tecnotes}
\logpage{[ 6, 0, 0 ]}
\hyperdef{L}{X7F2BA6DC7AD84FBC}{}
{
  This short chapter is included for the benefit of anyone wishing to implement
some other variety of many-object structures, for example \emph{ringoids}, which are rings with many objects; \emph{Lie groupoids}, which are Lie groups with many objects; and so on. 
\section{\textcolor{Chapter }{Many object structures}}\label{sec-tec-mwo}
\logpage{[ 6, 1, 0 ]}
\hyperdef{L}{X7C5B725A7AED3C8D}{}
{
  Structures with many objects, and their elements, are defined in a manner
similar to the single object case. For elements we have: 
\begin{itemize}
\item  \texttt{DeclareCategory( "IsMultiplicativeElementWithObjects", IsMultiplicativeElement
); } 
\item  \texttt{DeclareCategory( "IsMultiplicativeElementWithObjectsAndOnes",
IsMultiplicativeElementWithObjects ); } 
\item  \texttt{DeclareCategory( "IsMultiplicativeElementWithObjectsAndInverses",
IsMultiplicativeElementWithObjectsAndOnes ); } 
\item  \texttt{DeclareCategory( "IsGroupoidElement", } 

 \texttt{IsMultiplicativeElementWithObjectsAndInverses ); } 
\end{itemize}
 as well as various category collections. For the various structures we have: 
\begin{itemize}
\item  \texttt{DeclareCategory( "IsDomainWithObjects", IsDomain ); } 
\item  \texttt{DeclareCategory( "IsMagmaWithObjects", IsDomainWithObjects and IsMagma and
IsMultiplicativeElementWithObjectsCollection );} 
\item  \texttt{DeclareCategory( "IsMagmaWithObjectsAndOnes", IsMagmaWithObjects and
IsMultiplicativeElementWithObjectsAndOnesCollection ); } 
\item  \texttt{DeclareCategory( "IsMagmaWithObjectsAndInverses", IsMagmaWithObjectsAndOnes
and } 

 \texttt{IsMultiplicativeElementWithObjectsAndInversesCollection ); } 
\item  \texttt{DeclareCategory( "IsGroupoid", IsMagmaWithObjectsAndInverses and
IsGroupoidElementCollection ); } 
\end{itemize}
 Some of the groupoids constructed earlier are the single piece \texttt{Gd8} and the five component union \texttt{U5}: 

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@CategoriesOfObject( Gd8 );|
  [ "IsListOrCollection", "IsCollection", "IsExtLElement", 
    "CategoryCollections(IsExtLElement)", "IsExtRElement", 
    "CategoryCollections(IsExtRElement)", 
    "CategoryCollections(IsMultiplicativeElement)", "IsGeneralizedDomain", 
    "IsMagma", "IsDomainWithObjects", 
    "CategoryCollections(IsMultiplicativeElementWithObjects)", 
    "CategoryCollections(IsMultiplicativeElementWithObjectsAndOnes)", 
    "CategoryCollections(IsMultiplicativeElementWithObjectsAndInverses)\
  ", "CategoryCollections(IsGroupoidElement)", "IsMagmaWithObjects", 
    "IsMagmaWithObjectsAndOnes", "IsMagmaWithObjectsAndInverses", 
    "IsGroupoid" ]
  !gapprompt@gap>| !gapinput@FamilyObj( Gd8 );     ## these numbers vary from one run to another|
  NewFamily( "GroupoidFamily", [ 2722 ], [ 53, 54, 79, 80, 81, 82, 92, 93, 116, 
    117, 119, 120, 123, 205, 501, 2690, 2703, 2707, 2711, 2715, 2718, 2720, 
    2721, 2722 ] )
  !gapprompt@gap>| !gapinput@KnownAttributesOfObject( Gd8 ); |
  [ "Name", "Size", "GeneratorsOfMagmaWithInverses", "ObjectList", "Pieces" ]
  !gapprompt@gap>| !gapinput@KnownTruePropertiesOfObject( Gd8 ); |
  [ "IsNonTrivial", "IsFinite", "CanEasilyCompareElements", 
    "CanEasilySortElements", "IsDuplicateFree", "IsAssociative", 
    "IsSinglePieceDomain", "IsDirectProductWithCompleteGraphDomain" ]
  !gapprompt@gap>| !gapinput@RepresentationsOfObject( Gd8 );|
  [ "IsComponentObjectRep", "IsAttributeStoringRep", "IsMWOSinglePieceRep" ]
  !gapprompt@gap>| !gapinput@RepresentationsOfObject( U5 ); |
  [ "IsComponentObjectRep", "IsAttributeStoringRep", "IsPiecesRep" ]
  
\end{Verbatim}
 Similarly, for arrows, we have: 

 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@[ a78, e2 ];|
  [ [m2 : -7 -> -8], [(1,3) : -8 -> -7] ]
  !gapprompt@gap>| !gapinput@CategoriesOfObject(a78);|
  [ "IsExtLElement", "IsExtRElement", "IsMultiplicativeElement", 
    "IsMultiplicativeElementWithObjects" ]
  !gapprompt@gap>| !gapinput@FamilyObj( a78 );     ## again these numbers vary|
  NewFamily( "MultiplicativeElementWithObjectsFamily", [ 2702 ], 
  [ 79, 80, 81, 82, 116, 119, 122, 2702 ] )
  !gapprompt@gap>| !gapinput@CategoriesOfObject(e2); |
  [ "IsExtLElement", "IsExtRElement", "IsMultiplicativeElement", 
    "IsMultiplicativeElementWithObjects", 
    "IsMultiplicativeElementWithObjectsAndOnes", 
    "IsMultiplicativeElementWithObjectsAndInverses", 
    "IsGroupoidElement" ]
  !gapprompt@gap>| !gapinput@FamilyObj( e2 );        |
  NewFamily( "GroupoidElementFamily", [ 2714 ], 
  [ 79, 80, 81, 82, 116, 119, 122, 2702, 2706, 2710, 2714 ] )
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Many object homomorphisms}}\label{sec-tec-mwohom}
\logpage{[ 6, 2, 0 ]}
\hyperdef{L}{X7A4760E887C9C968}{}
{
  Homomorphisms of structures with many objects have a similar heirarchy. A few
examples: 
\begin{itemize}
\item  \texttt{DeclareCategory( "IsGeneralMappingWithObjects", IsGeneralMapping ); } 
\item  \texttt{DeclareSynonymAttr( "IsMagmaWithObjectsGeneralMapping",
IsGeneralMappingWithObjects and RespectsMultiplication ); } 
\item  \texttt{DeclareSynonymAttr( "IsMagmaWithObjectsHomomorphism",
IsMagmaWithObjectsGeneralMapping and IsMapping ); } 
\item  \texttt{DeclareCategory("IsGroupoidHomomorphism",IsMagmaWithObjectsHomomorphism); } 
\end{itemize}
 

 Two forms of representation are used: for mappings to a single piece; and for
unions of such mappings: 
\begin{itemize}
\item  \texttt{DeclareRepresentation( "IsMappingToSinglePieceRep",
IsMagmaWithObjectsHomomorphism and IsAttributeStoringRep and IsGeneralMapping,
[ "Source", "Range", "PieceImages" ] ); } 
\item  \texttt{DeclareRepresentation( "IsMappingWithObjectsRep",
IsMagmaWithObjectsHomomorphism and IsAttributeStoringRep and IsGeneralMapping,
[ "Source", "Range", "PiecesOfMapping" ] ); } 
\end{itemize}
 

 In previous chapters, \texttt{hom1} was an endofunction on \texttt{M78}; \texttt{homd8} was a homomorphism from \texttt{Gd8} to \texttt{Gs3}; and \texttt{aut3} was an automorphism of \texttt{Ga4}. All homomorphisms have family \texttt{GeneralMappingWithObjectsFamily}. Perhaps it would be better to have separate families for each structure? 
\begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example]
  
  !gapprompt@gap>| !gapinput@FamilyObj(hom1);|
  NewFamily( "GeneralMappingWithObjectsFamily", [ 2726 ], 
  [ 79, 80, 81, 82, 116, 119, 122, 126, 130, 149, 412, 2726 ] )
  !gapprompt@gap>| !gapinput@KnownAttributesOfObject( hom1 );|
  [ "Range", "Source", "PieceImages" ]
  !gapprompt@gap>| !gapinput@KnownTruePropertiesOfObject( hom1 );|
  [ "CanEasilyCompareElements", "CanEasilySortElements", "IsTotal", 
    "IsSingleValued", "RespectsMultiplication", "IsGeneralMappingToSinglePiece",
    "IsGeneralMappingFromSinglePiece", "IsInjectiveOnObjects", 
    "IsSurjectiveOnObjects" ]
  !gapprompt@gap>| !gapinput@CategoriesOfObject( homd8 );|
  [ "IsExtLElement", "IsExtRElement", "IsMultiplicativeElement", 
    "IsMultiplicativeElementWithOne", "IsMultiplicativeElementWithInverse", 
    "IsAssociativeElement", "IsGeneralMapping", "IsGeneralMappingWithObjects", 
    "IsGroupoidHomomorphism" ]
  !gapprompt@gap>| !gapinput@KnownAttributesOfObject( homd8 );|
  [ "Range", "Source", "PieceImages", "ImagesOfObjects", "ImagesOfRays", 
    "ObjectTransformationOfGroupoidHomomorphism", "RootObjectHomomorphism" ]
  !gapprompt@gap>| !gapinput@KnownAttributesOfObject( aut3 );|
  [ "Order", "Range", "Source", "PieceImages", "ImagesOfObjects", 
    "ImagesOfRays", "ObjectTransformationOfGroupoidHomomorphism", 
    "RootObjectHomomorphism" ]
  
\end{Verbatim}
 }

 }

            
\chapter{\textcolor{Chapter }{Development History}}\label{chap-history}
\logpage{[ 7, 0, 0 ]}
\hyperdef{L}{X810C43BC7F63C4B4}{}
{
  
\section{\textcolor{Chapter }{Versions of the Package}}\label{sec-versions}
\logpage{[ 7, 1, 0 ]}
\hyperdef{L}{X8192EA4C7B7CC5CD}{}
{
  The first version, \textsf{GraphGpd} 1.001, formed part of Emma Moore's thesis \cite{emma-thesis} in December 2000, but was not made generally available. 

 Version 1.002 of \textsf{GraphGpd} was prepared to run under \textsf{GAP} 4.4 in January 2004; was submitted to the \textsf{GAP} council to be considered as an accepted package; but suggestions from the
referee were not followed up. 

 In April 2006 the manual was converted to \textsf{GAPDoc} format. Variables \texttt{Star}, \texttt{Costar} and \texttt{CoveringGroup} were found to conflict with usage in other packages, and were renamed \texttt{VertexStar}, \texttt{VertexCostar} and \texttt{CoveringGroupOfGroupoid} respectively. Similarly, the \texttt{Vertices} and \texttt{Arcs} of an \texttt{FpWeightedDigraph} were changed from attributes to record components. 

 In the spring of 2006 the package was extensively rewritten and renamed \textsf{Gpd}. Version 1.01 was submitted as a deposited package in June 2006. Version
1.03, of October 2007, fixed some file protections, and introduced the test
file \texttt{gpd{\textunderscore}manual.tst}. 

 Version 1.05, of November 2008, was released when the website at Bangor
changed. 

 Since then, the package has been rewritten again, introducing magmas with
objects and their mappings. Functions to implement constructions contained in \cite{AlWe} have been added, but this is ongoing work. 

 Versions 1.09 to 1.15 were prepared for the anticipated release of \textsf{GAP} 4.5 in June 2012. 

 \textsf{Gpd} became an accepted \textsf{GAP} package in May 2015. 

 The latest version is 1.34 of 5th June 2015, for \textsf{GAP} 4.7. }

 
\section{\textcolor{Chapter }{What needs to be done next?}}\label{sec-whatnext}
\logpage{[ 7, 2, 0 ]}
\hyperdef{L}{X82148FB77CC3CCC0}{}
{
  Computationally, there are three types of connected groupoid: 
\begin{itemize}
\item  those with identical object groups, 
\item  those with object groups conjugate in some supergroup, 
\item  those with object groups which are simply isomorphic. 
\end{itemize}
 \textsf{GraphGpd} attempted to implement the second case, while \textsf{Gpd} 1.01 and 1.03 considered only the first case, and \textsf{Gpd} 1.05 extended 1.03 to the second case. 

 The third case has not yet been considered for implementation, and there does
not appear to be much need to do so. 

 Here are some other immediate requirements: 
\begin{itemize}
\item  more work on automorphism groups of groupoids; 
\item  normal subgroupoids and quotient groupoids; 
\item  more methods for morphisms of groupoids, particularly when the range is not
connected; 
\item  \texttt{ImageElm} and \texttt{ImagesSource} for the cases of groupoid morphisms not yet covered; 
\item  \texttt{Enumerator} for \texttt{IsHomsetCosetsRep}; 
\item  free groupoid on a graph; 
\item  methods for \texttt{FreeProductWithAmalgamation} and \texttt{HnnEntension} for pc-groups; 
\item  convert \texttt{GraphOfGroupsRewritingSystem} to the category \texttt{IsRewritingSystem}; 
\item  in \textsf{XMod}, implement crossed modules over groupoids (a start has been made). 
\end{itemize}
 }

 }

 \def\bibname{References\logpage{[ "Bib", 0, 0 ]}
\hyperdef{L}{X7A6F98FD85F02BFE}{}
}

\bibliographystyle{alpha}
\bibliography{gpdbib.xml}

\addcontentsline{toc}{chapter}{References}

\def\indexname{Index\logpage{[ "Ind", 0, 0 ]}
\hyperdef{L}{X83A0356F839C696F}{}
}

\cleardoublepage
\phantomsection
\addcontentsline{toc}{chapter}{Index}


\printindex

\newpage
\immediate\write\pagenrlog{["End"], \arabic{page}];}
\immediate\closeout\pagenrlog
\end{document}
