% generated by GAPDoc2LaTeX from XML source (Frank Luebeck)
\documentclass[11pt]{report}
\usepackage{a4wide}
\sloppy
\pagestyle{myheadings}
\usepackage{amssymb}
\usepackage[latin1]{inputenc}
\usepackage{makeidx}
\makeindex
\usepackage{color}
\definecolor{DarkOlive}{rgb}{0.1047,0.2412,0.0064}
\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{FuncColor}{rgb}{1.0,0.0,0.0}
%% strange name because of pdflatex bug:
\definecolor{Chapter }{rgb}{0.0,0.0,1.0}

\usepackage{fancyvrb}

\usepackage{pslatex}

\usepackage[
        a4paper=true,bookmarks=false,pdftitle={Written with GAPDoc},
        pdfcreator={LaTeX with hyperref package / GAPDoc},
        colorlinks=true,backref=page,breaklinks=true,linkcolor=RoyalBlue,
        citecolor=RoyalGreen,filecolor=RoyalRed,
        urlcolor=RoyalRed,pagecolor=RoyalBlue]{hyperref}

% 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,}}
\newcommand{\Q}{\mathbb{Q}}
\newcommand{\R}{\mathbb{R}}
\newcommand{\C}{\mathbb{C}}
\newcommand{\Z}{\mathbb{Z}}
\newcommand{\N}{\mathbb{N}}
\newcommand{\F}{\mathbb{F}}

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

\newsavebox{\backslashbox}
\sbox{\backslashbox}{\texttt{\symbol{92}}}
\newcommand{\bs}{\usebox{\backslashbox}}

\begin{document}

\logpage{[ 0, 0, 0 ]}
\begin{titlepage}
\begin{center}{\Huge \textbf{\textsf{IdRel}}}\\[1cm]
\hypersetup{pdftitle=\textsf{IdRel}}
\markright{\scriptsize \mbox{}\hfill \textsf{IdRel} \hfill\mbox{}}
{\Large \textbf{A package for Identities among Relators}}\\[1cm]
{Version 2.02}\\[1cm]
{June 2006}\\[1cm]
\mbox{}\\[2cm]
{\large \textbf{ Anne Heyworth   }}\\
{\large \textbf{ Chris Wensley    }}\\
\hypersetup{pdfauthor= Anne Heyworth   ;  Chris Wensley    }
\end{center}\vfill

\mbox{}\\
{\mbox{}\\
\small \noindent \textbf{ Anne Heyworth   } --- Email: \href{mailto://a.heyworth@mcs.le.ac.uk}{\texttt{a.heyworth@mcs.le.ac.uk}}\\
 --- Address: \begin{minipage}[t]{8cm}\noindent
 University of Leicester. \end{minipage}
}\\
{\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://www.informatics.bangor.ac.uk/~cwensley/}{\texttt{http://www.informatics.bangor.ac.uk/\~{}cwensley/}}\\
 --- Address: \begin{minipage}[t]{8cm}\noindent
 School of Informatics, University of Wales Bangor,\\
 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{IdRel} package was originally implemented in 1999 using the \textsf{GAP}3 language, when the first author was studying for a Ph.D. in Bangor, and has
since been converted to \textsf{GAP}4. 

 This package is designed to compute a minimal set of generators for the module
of the identities among relations of a group presentation. It does this using 
\begin{itemize}
\item  rewriting and logged rewriting: a self-contained implementation of the
Knuth-Bendix process using the monoid presentation associated to the group
presentation; 
\item  monoid polynomials: an implementation of the monoid ring; 
\item  module polynomials: an implementation of the right module over this monoid
generated by the relators. 
\item  Y-sequences: used as a \emph{rewriting} way of representing elements of a free crossed module (products of conjugates
of group relators and inverse relators). 
\end{itemize}
 

 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}}. }\\[1cm]
{\small 
\section*{Copyright}
\logpage{[ 0, 0, 2 ]}
 {\copyright} 1999-2006 by Anne Heyworth and Chris Wensley 

 We adopt the copyright regulations of \textsf{GAP} as detailed in the copyright notice in the \textsf{GAP} manual. }\\[1cm]
\newpage

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

\tableofcontents
\newpage

           
\chapter{\textcolor{Chapter }{Introduction}}\label{intro}
\logpage{[ 1, 0, 0 ]}
{
  This manual describes the \textsf{IdRel} (version 2.02) \textsf{GAP} share package for computing the identities among relations of a group
presentation using rewriting, logged rewriting, monoid polynomials, module
polynomials and $Y$-sequences. 

 The theoretical background for these computations is contained in Brown and
Huebschumann \cite{BrHu}, Brown and Razak Salleh \cite{BrSa} and is surveyed in \cite{anne-thesis}. 

 \textsf{IdRel} is primarily designed for the computation of a minimal set of generators for
the module of identities among relations. It also contains functions which
compute logged rewrite systems for group presentations (and complete them
where possible), functions for operations involving elements of monoid rings
and functions for operations with elements of right modules over monoid rings.
The $Y$-sequences are used as a \emph{rewriting} way of representing elements of a free crossed module (products of conjugates
of group relators and inverse relators). The package is written entirely in \textsf{GAP}4, and requires no compilation. 

 The package is loaded into \textsf{GAP} with the \texttt{LoadPackage} command, and on-line help is available in the usual way. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> LoadPackage( "idrel" ); 
  gap> ?idrel
  
\end{Verbatim}
 The usual dvi, pdf and PostScript versions of the \textsf{IdRel} manual are available (as \texttt{manual.dvi}, \texttt{manual.pdf} and \texttt{manual.ps} respectively) in the \texttt{doc} directory of the home directory of \textsf{IdRel}. The information parameter \texttt{InfoIdRel} has default value \texttt{0}. When raised to a higher value, additional information is printed out. \textsf{IdRel} was originally developed in 1999 using \textsf{GAP}3, partially supported by a University of Wales Research Assistantship for the
first author, Anne Heyworth. If you use \textsf{IdRel} to solve a problem then please send a short email to the second author, to
whom bug reports, suggestions and other comments should also be sent. You may
reference the package by mentioning \cite{HeWe1} and \cite{anne-thesis}. }

           
\chapter{\textcolor{Chapter }{Rewriting Systems}}\label{chap-rws}
\logpage{[ 2, 0, 0 ]}
{
  This chapter describes functions to construct rewriting systems for finitely
presented groups which store rewriting information. The example used is a
presentation of the quaternion group \texttt{q8} with generators $a,b$ and relators $[a^4, b^4, abab^{-1}, a^2b^2]$. 
\section{\textcolor{Chapter }{Identity Y-sequences}}\logpage{[ 2, 1, 0 ]}
{
 A typical input for \textsf{IdRel} is an fp-group presentation. This requires a free group \texttt{F} on a set of generators and a set of relators \texttt{R} (words in the free group). The module of identities among relations for this
presentation has as its elements the Peiffer equivalence classes of all
products of conjugates of relators which represent the identity in the free
group. 

 In this package the identities among relations are represented by Y-sequences,
which are lists $[[r_1, u_1],\ldots,[r_k,u_k]]$ where $r_1,\ldots,r_k$ are the group relators or their inverses, and $u_1,\ldots,u_k$ are words in the free group \texttt{F}. A Y-sequence is evaluated in \texttt{F} as the product $(u_1^{-1}r_1u_1)\ldots(u_k^{-1}r_ku_k)$ and is an identity Y-sequence if it evaluates to the identity in \texttt{F}. An identity Y-sequence represents an identity among the relators of the
group presentation. The main function of the package is to produce a set of
Y-sequences which generated the module of identites among relations, and
further, that this set be minimal in the sense that every element in it is
needed to generate the module. 

 We now give a simple example to illustrate the use of \textsf{IdRel}. All the functions used are described in detail in this manual. We compute a
reduced set of identities among relations for the presentation of the
symmetric group \texttt{s3} with generators $a,b$ and relators $[a^3 , b^2, (ab)^2]$. 

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> F := FreeGroup( 2 );
  <free group on the generators [ fl, f2]>
  gap> a := F.l;; b:= F.2;;
  gap> rels := [ a^3 , b^2, a*b*a*b];
  [ fl^3 , f2^2, fl*f2*fl*f2] 
  gap> s3 := F/rels;
  <fp group on the generators [ fl, f2 ]> 
  gap> idrels3 := IdentitiesAmongRelators( s3 );;
  gap> Display( idrels3 );
  [ [ ( FY4*( <identity ...>, FR1*( mon1 - <identity ...> ), 
      ( FY8*( <identity ...>, FR2*( mon2 - <identity ...> ), 
      ( FY7*( mon2*mon1), FR3*( mon2 - mon1) ), 
      ( FY6*( -<identity ...>, FR1*( -mon2*mon1 - mon1) + FR2*( -mon1*mon2 - mo\ 
  nl - <identity ...> + FR3 *( mon3 + mon2 + <identity ...> ) ],
    [ ( FY4*( <identity ...>, FR1*( mon1 - <identity ...> ), 
      ( FY8*( <identity ...>, FR2*( mon2 - <identity ...> ), 
      ( FY7*( mon2*mon1), FR3 *( mon2 - mon1) ), 
      ( FY4*( -mon2*mon1 + <identity ...> + FY6*( -<identity ...> + FY7*( -mon\ 
  2*mon1) + FY8*( mon3 ) , FR1*( -mon2 - <identity ...> + FR2*( -mon3 - mon1 - <i
  dentity ...> + FR3*( mon3 + mon1 + <identity ...>) ) ] ]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Monoid Presentations of FpGroups}}\logpage{[ 2, 2, 0 ]}
{
 

\subsection{\textcolor{Chapter }{FreeRelatorGroup}}
\logpage{[ 2, 2, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{FreeRelatorGroup( grp )\index{FreeRelatorGroup@\texttt{FreeRelatorGroup}}
\label{FreeRelatorGroup}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{FreeRelatorHomomorphism( grp )\index{FreeRelatorHomomorphism@\texttt{FreeRelatorHomomorphism}}
\label{FreeRelatorHomomorphism}
}\hfill{\scriptsize (attribute)}}\\


 The function \texttt{FreeRelatorGroup} returns a free group on the set of relators of the given fp-group \texttt{G}. If \texttt{HasName(G)} is \texttt{true} then a name is automatically assigned to the free group. 

 The function \texttt{FreeRelatorHomomorphism} returns the group homomorphism from the free group on the relators to the free
group on the generators of \texttt{G}, mapping each generator to the corresponding word. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> F := FreeGroup( 2 );;
  gap> a := F.1;; b:= F.2;;
  gap> rels := [ a^4, b^4, a*b*a*b^-1, a^2*b^2];
  [ f1^4, f2^4, f1*f2*f1*f2^-1, f1^2*f2^2] 
  gap> q8 := F/rels;;
  gap> SetName( q8, "q8" );
  gap> frq8 := FreeRelatorGroup( q8 );
  q8_R 
  gap> GeneratorsOfGroup( frq8 );
  [ q8_R1, q8_R2, q8_R3, q8_R4]
  gap> frhomq8 := FreeRelatorHomomorphism( q8 );
  [ q8_R1, q8_R2, q8_R3, q8_R4] -> [ f1^4, f2^4, f1*f2*f1*f2^-1, f1^2*f2^2]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{MonoidPresentationFpGroup}}
\logpage{[ 2, 2, 2 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{MonoidPresentationFpGroup( grp )\index{MonoidPresentationFpGroup@\texttt{MonoidPresentationFpGroup}}
\label{MonoidPresentationFpGroup}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{FreeGroupOfPresentation( mon )\index{FreeGroupOfPresentation@\texttt{FreeGroupOfPresentation}}
\label{FreeGroupOfPresentation}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{GroupRelatorsOfPresentation( mon )\index{GroupRelatorsOfPresentation@\texttt{GroupRelatorsOfPresentation}}
\label{GroupRelatorsOfPresentation}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{InverseRelatorsOfPresentation( mon )\index{InverseRelatorsOfPresentation@\texttt{InverseRelatorsOfPresentation}}
\label{InverseRelatorsOfPresentation}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{HomomorphismOfPresentation( mon )\index{HomomorphismOfPresentation@\texttt{HomomorphismOfPresentation}}
\label{HomomorphismOfPresentation}
}\hfill{\scriptsize (attribute)}}\\


 A monoid presentation for a finitely presented group \texttt{G} has two monoid generators $g^+,g^-$ for each group generator $g$. The relators of the monoid presentation comprise the group relators, and
relators $g^+g^-$ specifying the inverses. The function \texttt{MonoidPresentationFpGroup} returns the monoid presentation derived in this way from an fp-presentation.
(Note: this function should always be followed by a double semicolon -- \texttt{MonoidPresentationFpGroup(G);;} -- because an error occurs in attempting to display the results on the screen:
the \texttt{ElementsFamily} needs to be fixed.) 

 The function \texttt{FreeGroupOfPresentation} returns the free group on the monoid generators. 

 The function \texttt{GroupRelatorsOfPresentation} returns those relators of the monoid which correspond to the relators of the
group. All negative powers in the group relators are converted to positive
powers of the $g^-$. 

 The function \texttt{InverseRelatorsOfPresentation} returns relators which specify the inverse pairs of the monoid generators. 

 The function \texttt{HomomorphismOfPresentation} returns the homomorphism from the free group of the monoid presentation to the
free group of the group presentation. 

 In the example below, the four monoid generators $a^+, b^+, a^-, b^-$ are named \texttt{q8\_M1, q8\_M2, q8\_M3, q8\_M4}. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> mon := MonoidPresentationFpgroup( q8 );; 
  gap> fgmon := FreeGroupOfPresentation( mon);
  <free group on the generators [ q8_Ml, q8_M2, q8_M3, q8_M4]> 
  gap> genfgmon := GeneratorsOfGroup( fgmon);
  [ q8_Ml, q8_M2, q8_M3, q8_M4] 
  gap> gprels := GroupRelatorsOfPresentation( mon );
  [ q8_Ml^4, q8_M2^4, q8_Ml*q8_M2*q8_Ml*q8_M4, q8_Ml^2*q8_M2^2] 
  gap> invrels := InverseRelatorsOfPresentation( mon);
  [ q8_Ml*q8_M3, q8_M2*q8_M4, q8_M3*q8_Ml, q8_M4*q8_M2] 
  gap> hompres := HomomorphismOfPresentation( mon );
  [ q8_Ml, q8_M2, q8_M3, q8_M4] -> [ fl, f2, fl^-l, f2^-1 ]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Rewriting systems for FpGroups}}\logpage{[ 2, 3, 0 ]}
{
 These functions duplicate the standard Knuth Bendix functions which are
available in the \textsf{GAP} library. There are two reasons for this: (1) these functions were first
written before the standard functions were available; (2) we require logged
versions of the functions, and these are most conveniently extended versions
of the non-logged code. 

\subsection{\textcolor{Chapter }{RewritingSystemFpGroup}}
\logpage{[ 2, 3, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{RewritingSystemFpGroup( grp )\index{RewritingSystemFpGroup@\texttt{RewritingSystemFpGroup}}
\label{RewritingSystemFpGroup}
}\hfill{\scriptsize (attribute)}}\\


 This function attempts to return a complete rewrite system for the group \texttt{G} obtained from the monoid presentation \texttt{mon}, with a length-lexicographical ordering on the words in \texttt{fgmon}, by applying Knuth-Bendix completion. Such a rewrite system can be obtained
for all finite groups. The rewrite rules are (partially) ordered, starting
with the inverse relators, followed by the rules which reduce the word length
the most. 

 In our \texttt{q8} example there are 16 rewrite rules. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> rws := RewritingSystemFpGroup( q8 );
  [ [q8_Ml*q8_M3, <identity ...>], [ q8_M2*q8_M4, <identity ...> ], 
    [q8_M3*q8_Ml, <identity ...>], [ q8_M4*q8_M2, <identity ...> ], 
    [q8_M1^2*q8_M4, q8_M2], [q8_Ml^2*q8_M2, q8_M4], [ q8_Ml^3, q8_M3 ], 
    [ q8_M4^2, q8_Ml^2], [ q8_M4*q8_M3, q8_Ml*q8_M4], 
    [ q8_M4*q8_Ml, q8_Ml*q8_M2], [q8_M3*q8_M4, q8_Ml*q8_M2], 
    [ q8_M3^2, q8_Ml^2], [q8_M3*q8_M2, q8_Ml*q8_M4], 
    [ q8_M2*q8_M3, q8_Ml*q8_M2], [q8_M2^2, q8_Ml^2], 
    [ q8_M2*q8_Ml, q8_Ml*q8_M4] ]
  
\end{Verbatim}
 The functions called by \texttt{RewritingSystemFpGroup} are as follows. 

\subsection{\textcolor{Chapter }{OnePassReduceWord}}
\logpage{[ 2, 3, 2 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{OnePassReduceWord( word, rules )\index{OnePassReduceWord@\texttt{OnePassReduceWord}}
\label{OnePassReduceWord}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{ReduceWordKB( word, rules )\index{ReduceWordKB@\texttt{ReduceWordKB}}
\label{ReduceWordKB}
}\hfill{\scriptsize (operation)}}\\


 Assuming that \texttt{word} is an element of a free monoid and \texttt{rules} is a list of ordered pairs of such words, the function \texttt{OnePassReduceWord} searches the list of rules until it finds that the left-hand side of a \texttt{rule} is a \texttt{subword} of \texttt{word}, whereupon it replaces that \texttt{subword} with the right-hand side of the matching rule. The search is continued from
the next \texttt{rule} in \texttt{rules}, but using the new \texttt{word}. When the end of \texttt{rules} is reached, one pass is considered to have been made and the reduced \texttt{word} is returned. If no matches are found then the original \texttt{word} is returned. 

 The function \texttt{ReduceWordKB} repeatedly applies the function \texttt{OnePassReduceWord} until the \texttt{word} remaining contains no left-hand side of a \texttt{rule} as a \texttt{subword}. If \texttt{rules} is a complete rewrite system, then the irreducible \texttt{word} that is returned is unique, otherwise the order of the rules in \texttt{rules} will determine which irreducible word is returned. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> monrels := Concatenation( gprels, invrels );
  [ q8_Ml^4, q8_M2^4, q8_Ml*q8_M2*q8_Ml*q8_M4, q8_Ml^2*q8_M2^2, q8_Ml*q8_M3, 
    q8_M2*q8_M4, q8_M3*q8_Ml, q8_M4*q8_M2] 
  gap> id := One( monrels[l] );;
  gap> r0 := List( monrels, r -> [ r, id ] );
  [ [ q8_Ml^4, <identity ...> ], [ q8_M2^4, <identity. ..> ], 
    [ q8_Ml*q8_M2*q8_Ml*q8_M4, <identity ...> ], 
    [ q8_Ml^2*q8_M2^2, <identity. ..>], [ q8_Ml*q8_M3, <identity ...> ], 
    [ q8_M2*q8_M4, <identity ...> ], [ q8_M3*q8_Ml, <identity. ..>], 
    [ q8_M4*q8_M2, <identity ...> ] ] 
  gap> ap := genfgmon[l];; bp := genfgmon[2];;   ## p for plus
  gap> am := genfgmon[3];; bm := genfgmon[4];;   ## m for minus
  gap> w0 := (ap^3 * bp^3)^3;
  q8_Ml^3*q8_M2^3*q8_Ml^3*q8_M2^3*q8_Ml^3*q8_M2^3 
  gap> w1 := OnePassReduceWord( w0, r0 );
  q8_Ml*q8_M2*q8_Ml^3*q8_M2^3*q8_Ml^3*q8_M2^3 
  gap> w2 := ReduceWordKB( w0, r0 );
  q8_Ml*q8_M2*q8_Ml*q8_M2*q8_Ml*q8_M2
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{OnePassKB}}
\logpage{[ 2, 3, 3 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{OnePassKB( rules )\index{OnePassKB@\texttt{OnePassKB}}
\label{OnePassKB}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{RewriteReduce( rules )\index{RewriteReduce@\texttt{RewriteReduce}}
\label{RewriteReduce}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{KnuthBendix( rules )\index{KnuthBendix@\texttt{KnuthBendix}}
\label{KnuthBendix}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{ShorterRule( rule1, rule2 )\index{ShorterRule@\texttt{ShorterRule}}
\label{ShorterRule}
}\hfill{\scriptsize (operation)}}\\


 The function \texttt{OnePassKB} implements the main loop of the Knuth-Bendix completion algorithm. Rules are
compared with each other; all critical pairs are calculated; and the
irreducible critical pairs are orientated with respect to the
length-lexicographical ordering and added to the rewrite system. 

 The function \texttt{RewriteReduce} will remove unnecessary rules from a rewrite system. A rule is deemed to be
unnecessary if it is implied by the other rules, i.e. if both sides can be
reduced to the same thing by the remaining rules. 

 The function \texttt{KnuthBendix} implements the Knuth-Bendix algorithm, attempting to complete a rewrite system
with respect to a length-lexicographic ordering. It calls first \texttt{OnePassKB}, which adds rules, and then (for efficiency) \texttt{RewriteReduce} which removes any unnecessary ones. This procedure is repeated until \texttt{OnePassKB} adds no more rules. It will not always terminate, but for many examples (all
finite groups) it will be successful. The rewrite system returned is complete,
that is: it will rewrite any given word in the free monoid to a unique
irreducible; there is one irreducible for each element of the quotient monoid;
and any two elements of the free monoid which are in the same class will
rewrite to the same irreducible. 

 The function \texttt{ShorterRule} gives an ordering on rules. Rules $(g_lg_2,id)$ that identify two generators (or one generator with the inverse of another)
are considered to be the best. Otherwise one rule is considered to be better
than another if it reduces the length of a word by a greater amount. 

 One pass of this procedure for our \texttt{q8} example adds 13 relators to the original 8, and these 21 are then reduced to
9. A second pass and reduction gives a list of 16 rules which forms a complete
rewrite system for the group. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> r1 := OnePassKB( r0 );
  [ [ q8_Ml^4, <identity ...> ], [ q8_M2^4, <identity ...> ], 
    [ q8_Ml*q8_M2*q8_Ml*q8_M4, <identity ...> ], 
    [ q8_Ml^2*q8_M2^2, <identity. ..> ], [ q8_Ml*q8_M3, <identity ...> ], 
    [ q8_M2*q8_M4, <identity ...> ], [ q8_M3*q8_Ml, <identity ...> ], 
    [ q8_M4*q8_M2, <identity ...> ], [ q8_M2*q8_Ml*q8_M4, q8_Ml^3], 
    [ q8_Ml*q8_M2^2, q8_Ml^3 ], [ q8_M2^2, q8_Ml^2 ], [q8_Ml^3, q8_M3 ], 
    [ q8_M2^3, q8_M4 ], [ q8_Ml*q8_M2*q8_Ml, q8_M2], 
    [ q8_M2^3, q8_Ml^2*q8_M2], [ q8_M2^2, q8_Ml^2 ], [q8_Ml^2*q8_M2, q8_M4 ], 
    [ q8_Ml^3, q8_M3 ], [ q8_M2*q8_Ml*q8_M4, q8_M3 ], [q8_Ml*q8_M2^2, q8_M3 ], 
    [ q8_M2^3, q8_M4 ] ] 
  gap> r1 := RewriteReduce( r1 );
  [ [ q8_Ml*q8_M3, <identity ...> ], [ q8_M2^2, q8_Ml^2 ], 
    [ q8_M2*q8_M4, <identity ...> ], [ q8_M3*q8_Ml, <identity ...> ], 
    [ q8_M4*q8_M2, <identity ...> ], [ q8_Ml^3, q8_M3 ], 
    [ q8_Ml^2*q8_M2, q8_M4 ], [ q8_Ml*q8_M2*q8_Ml, q8_M2 ], 
    [ q8_M2*q8_Ml*q8_M4, q8_M3 ] ] 
  gap> Length( r1 );
  9 
  gap> r2 := KnuthBendix( r1 );
  [ [ q8_Ml*q8_M3, <identity ...> ], [ q8_M2*q8_Ml, q8_Ml*q8_M4 ], 
    [ q8_M2^2, q8_Ml^2], [ q8_M2*q8_M3, q8_Ml*q8_M2 ], 
    [ q8_M2*q8_M4, <identity ...> ], [ q8_M3*q8_Ml, <identity ...> ], 
    [ q8_M3*q8_M2, q8_Ml*q8_M4 ], [ q8_M3^2, q8_Ml^2 ], 
    [ q8_M3*q8_M4, q8_Ml*q8_M2 ], [ q8_M4*q8_Ml, q8_Ml*q8_M2 ], 
    [ q8_M4*q8_M2, <identity ...> ], [ q8_M4*q8_M3, q8_Ml*q8_M4 ], 
    [ q8_M4^2, q8_Ml^2], [ q8_Ml^3, q8_M3 ], [q8_Ml^2*q8_M2, q8_M4 ], 
    [ q8_Ml^2*q8_M4, q8_M2 ] ]
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Enumerating elements}}\logpage{[ 2, 4, 0 ]}
{
 

\subsection{\textcolor{Chapter }{ElementsOfMonoidPresentation}}
\logpage{[ 2, 4, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{ElementsOfMonoidPresentation( mon )\index{ElementsOfMonoidPresentation@\texttt{ElementsOfMonoidPresentation}}
\label{ElementsOfMonoidPresentation}
}\hfill{\scriptsize (attribute)}}\\


 The function \texttt{ElementsOfMonoidPresentation} returns a list of normal forms for the elements of the group given by the
monoid presentation \texttt{mon}. The normal forms are in fact the least elements in each equivalence class
(with respect to the length-lex order). The function \texttt{EnumerateKB} builds up a catalogue of irreducible words in the generators of a monoid with
respect to a set of rules. When \texttt{rules} is a complete rewrite system for \texttt{G} the list returned is a set of normal forms for the group elements. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> elq8 := Elements( q8 );
  [ <identity .. .>, fl, f2, fl^2, fl*f2, fl^3*f2, fl^3, fl^2*f2 ] 
  gap> elmonq8 := ElementsOfMonoidPresentation( monq8 );
  [ <identity. ..>, q8_Ml, q8_M2, q8_M3, q8_M4, q8_Ml^2, q8_Ml*q8_M2, 
    q8_Ml*q8_M4 ]
  
\end{Verbatim}
 }

 }

           
\chapter{\textcolor{Chapter }{Logged Rewriting Systems}}\label{chap-rws}
\logpage{[ 3, 0, 0 ]}
{
  A logged rewrite system is associated with a group presentation. Each logged
rewrite rule contains, in addition to the standard rewrite rule, a record or
log component which express the rule in terms of the original relators of the
group. Here a logged rewrite rule is represented by a triple \texttt{[ u, [L1,L2,..,Lk], v]}, where \texttt{[u,v]} is a rewrite rule and $L_i = [n_i,w_i]$ where $n_i$ is a group relator and $w_i$ is a word. These three components obey the identity $u = n_1^{w_1} \ldots n_k^{w_k} v$. 

 Rules of the form $g^+g^-$ are relevant to the monoid presentation, but not to the group presentation, so
are not included in the logging. 
\section{\textcolor{Chapter }{Logged Knuth-Bendix Completion}}\logpage{[ 3, 1, 0 ]}
{
 The functions in this section are the logged versions of those in the previous
chapter. 

\subsection{\textcolor{Chapter }{LoggedOnePassKB}}
\logpage{[ 3, 1, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LoggedOnePassKB( loggedrules )\index{LoggedOnePassKB@\texttt{LoggedOnePassKB}}
\label{LoggedOnePassKB}
}\hfill{\scriptsize (operation)}}\\


 Given a logged rewrite system, this function finds all the rules that would be
added to complete the rewrite system in \texttt{OnePassKB}, and also the logs which relate the new rules to the originals. The result of
applying this function to loggedrules is to add new logged rules to the system
without changing the monoid it defines. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> l0 := ListWithIdenticalEntries( 8, 0 );;
  gap> for j in [1..8] do 
           r := r0[j];
           if ( j<5 ) then
              l0[j] := [ r[1], [ [j,id] ], r[2] ];
           else
              l0[j] := [ r[1], [ ], r[2] ];
           fi;
       od;
  gap> l0;
  [ [ q8_M1^4, [ [ 1, <identity ...>] ], <identity. ..> ], 
    [ q8_M2^4, [ [ 2, <identity ...>] ], <identity ...> ], 
    [ q8_M1*q8_M2*q8_M1*q8_M4, [ [ 3, <identity ...> ] ], <identity ...> ],   
    [ q8_M1^2*q8_M2^2, [ [ 4, <identity ...> ] ], <identity ...> ], 
    [ q8_M1*q8_M3, [ ], <identity ...> ], 
    [ q8_M2*q8_M4, [ ], <identity ...> ], 
    [ q8_M3*q8_M1, [ ], <identity ...> ], 
    [ q8_M4*q8_M2, [ ], <identity ...> ] ] 
  gap> l1 := LoggedOnePassKB( l0 );
  [ [ q8_M1^4, [ [ 1, <identity. ..> ] ], <identity ...> ], 
    [ q8_M2^4, [ [ 2, <identity ...> ] ], <identity ...> ], 
    [ q8_M1*q8_M2*q8_M1*q8_M4, [ [ 3, <identity ...> ] ], <identity ...> ], 
    [ q8_M1^2*q8_M2^2, [ [ 4, <identity ...>] ], <identity ...> ], 
    [ q8_M1*q8_M3, [ ], <identity ...> ], [ q8_M2*q8_M4, [ ], <identity ...> ], 
    [ q8_M3*q8_M1, [ ], <identity ...> ], [ q8_M4*q8_M2, [ ], <identity ...> ], 
    [ q8_M2*q8_M1*q8_M4, [ [ -1, <identity. ..> ], [ 3, q8_M1^-3] ], q8_M1^3], 
    [ q8_M1*q8_M2^2, [ [ -1, <identity ...> ], [ 4, q8_M1^-3] ], q8_M1^3], 
    [ q8_M2^2, [ [ -1, <identity ...> ], [ 4, q8_M1^-2] ], q8_M1^2], 
    [ q8_M1^3, [ [ 1, <identity ...>] ], q8_M3], 
    [ q8_M2^3, [ [ 2, <identity ...>] ], q8_M4], 
    [ q8_M1*q8_M2*q8_M1, [ [ 3, <identity ...> ] ], q8_M2 ], 
    [ q8_M2^3, [ [ -4, <identity ...> ], [ 2, q8_M2^-1*q8_M1^-2] ], 
        q8_M1^2*q8_M2], 
    [ q8_M2^2, [ [ -4, <identity ...> ], [ 2, q8_M1^-2] ], q8_M1^2], 
    [ q8_M1^2*q8_M2, [ [ 4, <identity ...>] ], q8_M4], 
    [ q8_M1^3, [ [ 1, q8_M3^-1 ] ], q8_M3], 
    [ q8_M2*q8_M1*q8_M4, [ [ 3, q8_M3^-1 ] ], q8_M3 ], 
    [ q8_M1*q8_M2^2, [ [ 4, q8_M3^-1 ] ], q8_M3 ], 
    [ q8_M2^3, [ [ 2, q8_M4^-1 ] ], q8_M4] ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{LoggedKnuthBendix}}
\logpage{[ 3, 1, 2 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LoggedKnuthBendix( loggedrules )\index{LoggedKnuthBendix@\texttt{LoggedKnuthBendix}}
\label{LoggedKnuthBendix}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LoggedRewriteReduce( loggedrules )\index{LoggedRewriteReduce@\texttt{LoggedRewriteReduce}}
\label{LoggedRewriteReduce}
}\hfill{\scriptsize (operation)}}\\


 The function \texttt{LoggedRewriteReduce} removes unnecessary rules from a logged rewrite system. It works on the same
principle as \texttt{RewriteReduce}. 

 The function \texttt{LoggedKnuthBendix} repeatedly applies \texttt{LoggedOnePassKB} and \texttt{LoggedRewriteReduce} until no new rules are added and no unnecessary ones are included. The output
is a reduced complete logged rewrite system. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> l1 := LoggedRewriteReduce( l1 );
  [ [ q8_M1*q8_M3, [ ], <identity ...> ], 
    [ q8_M2^2, [ [ -4, <identity ...> ], [ 2, q8_M1^-2 ] ], q8_M1^2 ], 
    [ q8_M2*q8_M4, [ ], <identity ...> ], [ q8_M3*q8_M1, [ ], <identity ...> ], 
        [ q8_M4*q8_M2, [ ], <identity ...> ], 
    [ q8_M1^3, [ [ 1, <identity. ..> ] ], q8_M3 ], 
    [ q8_M1^2*q8_M2, [ [ 4, <identity. ..> ] ], q8_M4 ], 
    [ q8_M1*q8_M2*q8_M1, [ [ 3, <identity ...> ] ], q8_M2 ], 
    [ q8_M2*q8_M1*q8_M4, [ [ 3, q8_M3^-1 ] ], q8_M3] ]
  gap> l2 := LoggedKnuthBendix( l1 );
  [ [ q8_M1*q8_M3, [ ], <identity ...> ], 
    [ q8_M2*q8_M1, [ [ 3, q8_M3^-1 ], [-1, <identity. ..> ], [ 4, q8_M1^-1 ] ], 
        q8_M1*q8_M4 ], 
    [ q8_M2^2, [ [ -4, <identity ...> ], [2, q8_M1^-2] ], q8_M1^2 ], 
    [ q8_M2*q8_M3, [ [ -3, <identity ...> ] ], q8_M1*q8_M2 ], 
    [ q8_M2*q8_M4, [ ], <identity ...> ], [ q8_M3*q8_M1, [ ], <identity ...> ], 
    [ q8_M3*q8_M2, [ [ -1, <identity ...>], [4, q8_M1^-1 ] ], q8_M1*q8_M4 ],
    [ q8_M3^2, [ [ -1, <identity ...>] ], q8_M1^2 ], 
    [ q8_M3*q8_M4, [ [ -1, <identity ...>], [ -2, q8_M1^-2], 
          [ 4, <identity ...> ], [ 3, q8_M3^-1*q8_M2^-1 ], 
          [ -3, <identity. ..> ] ], q8_M1*q8_M2 ], 
    [ q8_M4*q8_M1, [ [ -4, <identity ...> ], [ 3, q8_M1^-1 ] ], q8_M1*q8_M2 ], 
    [ q8_M4*q8_M2, [ ], <identity ...> ], 
    [ q8_M4*q8_M3, [ [ -3, q8_M3^-1*q8_M4^-1] ], q8_M1*q8_M4 ], 
    [ q8_M4^2, [ [ -4, <identity. ..> ] ], q8_M1^2 ], 
    [ q8_M1^3, [ [ 1, <identity ...> ] ], q8_M3 ], 
    [ q8_M1^2*q8_M2, [ [4, <identity. ..> ] ], q8_M4 ], 
    [ q8_M1^2*q8_M4, [ [ -4, q8_M1^-2], [ 1, <identity ...> ] ], q8_M2 ] ] 
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Logged reduction of a word}}\logpage{[ 3, 2, 0 ]}
{
 

\subsection{\textcolor{Chapter }{LoggedReduceWordKB}}
\logpage{[ 3, 2, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LoggedReduceWordKB( loggedrules )\index{LoggedReduceWordKB@\texttt{LoggedReduceWordKB}}
\label{LoggedReduceWordKB}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LoggedOnePassReduceWord( word, loggedrules )\index{LoggedOnePassReduceWord@\texttt{LoggedOnePassReduceWord}}
\label{LoggedOnePassReduceWord}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{ShorterLoggedRule( logrule1, logrule2 )\index{ShorterLoggedRule@\texttt{ShorterLoggedRule}}
\label{ShorterLoggedRule}
}\hfill{\scriptsize (operation)}}\\


 Given a word and a logged rewrite system, the function \texttt{LoggedOnePassReduceWord} makes one reduction of the word (as in \texttt{OnePassReduceWord}) and records this, using the log part of the rule used and the position in
the original word of the replaced part. 

 The function \texttt{LoggedReduceWordKB} repeatedly applies \texttt{OnePassLoggedReduceWord} until the word can no longer be reduced. Each step of the reduction is logged,
showing how the original word can be expressed in terms of the original
relators and the irreducible word. When \texttt{loggedrules} is complete the reduced word is a unique normal form for that group element.
The log of the reduction however has no uniqueness but depends on the order in
which the rules are applied and on the non-unique logs of the rules
themselves. 

 The function \texttt{Shorterloggedrule} decides whether one logged rule is better than another, using the same
criteria as \texttt{ShorterRule}. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> w0;
  q8_M1^3*q8_M2^3*q8_M1^3*q8_M2^3*q8_M1^3*q8_M2^3
  gap> lw1 := LoggedOnePassReduceWord( w0, l2 );
  [ [ [ 3, q8_M3^-1*q8_M2^-2*q8_M1^-3 ], [ -1, q8_M2^-2*q8_M1^-3 ],
        [ 4, q8_M1^-1*q8_M2^-2*q8_M1^-3 ], [ -4, q8_M1^-3 ], [ 2, q8_M1^-5 ],
        [ -4, q8_M1^-6 ], [ 3, q8_M1^-7 ], [ 1, <identity ...> ],
        [ 4, q8_M1^-2*q8_M3^-1 ], [ -4, q8_M1^-2*q8_M3^-1 ], [ 1, q8_M3^-1 ] ],
    q8_M3*q8_M2*q8_M1*q8_M2^3*q8_M1^3*q8_M2^3 ]
  gap> lw2 := LoggedReduceWordKB( w0, l2 );
  [ [ [ 3, q8_M3^-1*q8_M2^-2*q8_M1^-3 ], [ -1, q8_M2^-2*q8_M1^-3 ],
        [ 4, q8_M1^-1*q8_M2^-2*q8_M1^-3 ], [ -4, q8_M1^-3 ], [ 2, q8_M1^-5 ],
        [ -4, q8_M1^-6 ], [ 3, q8_M1^-7 ], [ 1, <identity ...> ],
        [ 4, q8_M1^-2*q8_M3^-1 ], [ -4, q8_M1^-2*q8_M3^-1 ], [ 1, q8_M3^-1 ],
        [ 3, q8_M3^-2 ], [ -1, q8_M3^-1 ], [ 4, q8_M1^-1*q8_M3^-1 ],
        [ -4, q8_M4^-1*q8_M1^-1*q8_M3^-1 ],
        [ 2, q8_M1^-2*q8_M4^-1*q8_M1^-1*q8_M3^-1 ], [ -4, <identity ...> ],
        [ 3, q8_M1^-1 ], [ 1, q8_M2^-1*q8_M1^-1*q8_M2^-1*q8_M1^-1 ],
        [ 3, q8_M3^-1*q8_M1^-1 ], [ -1, q8_M1^-1 ], [ 4, q8_M1^-2 ],
        [ -4, q8_M3^-1*q8_M2^-1*q8_M4^-1*q8_M1^-2 ],
        [ 2, q8_M1^-2*q8_M3^-1*q8_M2^-1*q8_M4^-1*q8_M1^-2 ],
        [ -3, q8_M4^-1*q8_M1^-2 ], [ -4, q8_M1^-2 ], [ 3, q8_M1^-3 ],
        [ 1, <identity ...> ], [ 4, q8_M2^-2*q8_M3^-1 ], [ -4, q8_M3^-1 ],
        [ 2, q8_M1^-2*q8_M3^-1 ] ], q8_M1*q8_M4 ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{LoggedRewritingSystemFpGroup}}
\logpage{[ 3, 2, 2 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LoggedRewritingSystemFpGroup( loggedrules )\index{LoggedRewritingSystemFpGroup@\texttt{LoggedRewritingSystemFpGroup}}
\label{LoggedRewritingSystemFpGroup}
}\hfill{\scriptsize (attribute)}}\\


 Given a group presentation, the function \texttt{LoggedRewritingSystemFpGroup} determines a logged rewrite system based on the relators. The initial logged
rewrite system associated with a group presentation consists of two types of
rule. These are logged versions of the two types of rule in the monoid
presentation. For each relator \texttt{rel} of the group there is a logged rule \texttt{[ rel, [ [ 1, rel] ], id]}. For each inverse relator there is a logged rule \texttt{[gen*inv, [], id ]}. It then attempts a completion of the logged rewrite system. The rules in the
final system are partially ordered by the function \texttt{ShorterLoggedRule}. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> LoggedRewritingSystemFpGroup( q8 );
  [ [ q8_M4*q8_M2, [ ], <identity ...> ], [ q8_M3*q8_Ml, [ ], <identity ...> ], 
      [ q8_M2*q8_M4, [ ], <identity ...> ], 
    [ q8_Ml*q8_M3, [ ], <identity ...> ], 
    [ q8_Ml^2*q8_M4, [ [ -8, q8_Ml^-2 ], [ 5, <identity ...> ] ], q8_M2 ], 
    [ q8_Ml^2*q8_M2, [ [ 8, <identity ...> ] ], q8_M4 ], 
    [ q8_Ml^3, [ [ 5, <identity ...> ] ], q8_M3 ], 
    [ q8_M4^2, [ [ -8, <identity ...> ] ], q8_Ml^2 ], 
    [ q8_M4*q8_M3, [ [ -7, q8_M3^-1*q8_M4^-1 ] ], q8_Ml*q8_M4 ], 
    [ q8_M4*q8_Ml, [ [ -8, <identity. ..> ], [ 7, q8_Ml^-1 ] ], q8_Ml*q8_M2 ], 
    [ q8_M3*q8_M4, 
        [ [ -5, <identity ...>], [ -6, q8_Ml^-2 ], [ 8, <identity ...> ], 
            [ 7, q8_M3^-1*q8_M2^-1 ], [ -7, <identity. ..> ] ], q8_Ml*q8_M2 ], 
    [ q8_M3^2, [ [ -5, <identity ...>] ], q8_Ml^2 ], 
    [ q8_M3*q8_M2, [ [ -5, <identity. ..> ], [ 8, q8_Ml^-1 ] ], q8_Ml*q8_M4 ], 
    [ q8_M2*q8_M3, [ [ -7, <identity ...> ] ], q8_M1*q8_M2 ], 
    [ q8_M2^2, [ [ -a, <identity ...> ], [ 6, q8_M1^-2 ] ], q8_M1^2 ], 
    [ q8_M2*q8_M1, [ [ 7, q8_M3^-1 ], [ -5, <identity ...> ], [ a, q8_M1^-1 ] ], 
        q8_M1*q8_M4 ] ] 
  
\end{Verbatim}
 }

 }

           
\chapter{\textcolor{Chapter }{Monoid Polynomials}}\label{chap-rws}
\logpage{[ 4, 0, 0 ]}
{
  This chapter describes functions to compute with elements of a free
noncommutative algebra. The elements of the algebra are sums of rational
multiples of words in a free monoid. These will be called monoid polynomials,
and are stored as lists of pairs \texttt{[coefficient, word]}. 
\section{\textcolor{Chapter }{Construction of monoid polynomials}}\logpage{[ 4, 1, 0 ]}
{
 

\subsection{\textcolor{Chapter }{MonoidPolyFromCoeffsWords}}
\logpage{[ 4, 1, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{MonoidPolyFromCoeffsWords( coeffs, words )\index{MonoidPolyFromCoeffsWords@\texttt{MonoidPolyFromCoeffsWords}}
\label{MonoidPolyFromCoeffsWords}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{MonoidPoly( terms )\index{MonoidPoly@\texttt{MonoidPoly}}
\label{MonoidPoly}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{ZeroMonoidPoly( F )\index{ZeroMonoidPoly@\texttt{ZeroMonoidPoly}}
\label{ZeroMonoidPoly}
}\hfill{\scriptsize (operation)}}\\


 There are two possible ways to input a monoid polynomial. The first is by
listing the coefficients and then the words; the second is by listing the
terms as a list of pairs \texttt{[coefficient, word]}. Note that if a word occurs more than once in the input list, the
coefficients will be added so that the terms of the monoid polynomial recorded
do not contain any duplicates. The zero monoid polynomial is the polynomial
with no terms. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> rels := RelatorsOfFpGroup( q8 );
  [ f1^4, f2^4, f1*f2*f1*f2^-1, f1^2*f2^2 ] 
  gap> freeq8 := FreeGroupOfFpGroup( q8 ); 
  Group( [f1, f2] )
  gap> gens := GeneratorsOfGroup( freeq8 );;
  gap> famfree := ElementsFamily( FamilyObj( freeq8 ) );
  NewFamily( "FreeGroupElementsFamily", [ 125, 144, 989 ], 
  [ 76, 77, 78, 79, 111, 114, 117, 121, 125, 144, 989 ] )
  gap> famfree!.monoidPolyFam := MonoidPolyFam;
  NewFamily( "MonoidPolyFam", [ 2416 ], [ 111, 114, 117, 2416 ] )
  gap> cg := [6,7];
  [ 6, 7 ]
  gap> cr := [3,4,-5,-2];
  [ 3, 4, -5, -2 ]
  gap> pg := MonoidPolyFromCoeffsWords( cg, gens );
  <monpoly> 
  gap> Print( pg );
  7*f2 + 6*f1 
  gap> pr := MonoidPolyFromCoeffsWords( cr, rels );
  <monpoly> 
  gap> Print( pr );
  4*f2^4 - 5*f1*f2*f1*f2^-1 - 2*f1^2*f2^2 + 3*f1^4
  gap> zeromp := ZeroMonoidPoly( freeq8 );
  <monpoly> 
  gap> Print( zeromp);
  zero monpoly 
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Components of a polynomial}}\logpage{[ 4, 2, 0 ]}
{
 

\subsection{\textcolor{Chapter }{Terms}}
\logpage{[ 4, 2, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{Terms( poly )\index{Terms@\texttt{Terms}}
\label{Terms}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{Coeffs( poly )\index{Coeffs@\texttt{Coeffs}}
\label{Coeffs}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{Words( poly )\index{Words@\texttt{Words}}
\label{Words}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LeadTerm( poly )\index{LeadTerm@\texttt{LeadTerm}}
\label{LeadTerm}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LeadCoeffMonoidPoly( poly )\index{LeadCoeffMonoidPoly@\texttt{LeadCoeffMonoidPoly}}
\label{LeadCoeffMonoidPoly}
}\hfill{\scriptsize (attribute)}}\\


 The function \texttt{Terms} returns the terms of a polynomial as a list of pairs of the form \texttt{[word, coefficient]}. The function \texttt{Coeffs} returns the coefficients of a polynomial as a list, and the function \texttt{Words} returns the words of a polynomial as a list. The function \texttt{LeadTerm} returns the term of the polynomial whose word component is the largest with
respect to the length-lexicographical ordering. The function \texttt{LeadCoeffMonoidPoly} returns the coefficient of the leading term of a polynomial. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> Coeffs( pr );
  [ 4, -5, -2, 3 ]
  gap> Terms( pr );
  [ [ 4, f2^4 ], [ -5, f1*f2*f1*f2^-1 ], [ -2, f1^2*f2^2 ], [ 3, f1^4 ] ]
  gap> Words( pr );
  [ f2^4, f1*f2*f1*f2^-1, f1^2*f2^2, f1^4 ]
  gap> LeadTerm( pr );
  [ 4, f2^4]
  gap> LeadCoeffMonoidPoly( pr );
  4
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{Monic}}
\logpage{[ 4, 2, 2 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{Monic( poly )\index{Monic@\texttt{Monic}}
\label{Monic}
}\hfill{\scriptsize (operation)}}\\


 A monoid polynomial is called \emph{monic} if the coefficient of its leading polynomial is one. The function \texttt{Monic} converts a polynomial into a monic polynomial by dividing all the coefficients
by the leading coefficient. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> mpr := Monic( pr );;
  gap> Print( mpr );
  f2^4 - 5/4*f1*f2*f1*f2^-1 - 1/2*f1^2*f2^2 + 3/4*f1^4
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{AddTermMonoidPoly}}
\logpage{[ 4, 2, 3 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{AddTermMonoidPoly( poly, coeff, word )\index{AddTermMonoidPoly@\texttt{AddTermMonoidPoly}}
\label{AddTermMonoidPoly}
}\hfill{\scriptsize (operation)}}\\


 The function \texttt{AddTermMonoidPoly} adds a new term, given by its coeffiecient and word, to an existing
polynomial. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> w := gens[1]^gens[2];
  f2^-1*f1*f2
  gap> cw := 3/4;;
  gap> wpg:= AddTermMonoidPoly( pg, cw, w);
  <monpoly> 
  gap> Print( wpg );
  3/4*f2^-1*f1*f2 + 7*f2 + 6*f1
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Monoid Polynomial Operations}}\logpage{[ 4, 3, 0 ]}
{
 \index{=,+,* for monoid polynomials} Tests for equality and arithmetic operations are performed in the usual way. 

 The operation \texttt{poly1 = poly2} returns \texttt{true} if the monoid polynomials have the same terms, and \texttt{false} otherwise. Multiplication of a monoid polynomial (on the left or right) by a
coefficient; the addition or subtraction of two monoid polynomials;
multiplication (on the right) of a monoid polynomial by a word; and
multiplication of two monoid polynomials; are all implemented. 

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> pg = pg;
  true 
  gap> pg = pr;
  false 
  gap> prcw := pr*cw;
  3*f2^4 - 15/4*f1*f2*f1*f2^-1 - 3/2*f1^2*f2^2 + 9/4*f1^4
  gap> cwpr := cw*pr;
  3*f2^4 - 15/4*f1*f2*f1*f2^-1 - 3/2*f1^2*f2^2 + 9/4*f1^4
  gap> pr = prcw;
  false 
  gap> prcw = cwpr;
  true 
  gap> Print( pg + pr );
  4*f2^4 - 5*f1*f2*f1*f2^-1 - 2*f1^2*f2^2 + 3*f1^4 + 7*f2 + 6*f1 
  gap> Print( pg - pr );
  - 4*f2^4 + 5*f1*f2*f1*f2^-1 + 2*f1^2*f2^2 - 3*f1^4 + 7*f2 + 6*f1
  gap> Print( pg * w );
  6*f1*f2^-1*f1*f2 + 7*f1*f2 
  gap> Print( pg * pr );
  28*f2^5 - 35*f2*f1*f2*f1*f2^-1 - 14*f2*f1^2*f2^2 + 21*f2*f1^4 
  + 24*f1*f2^4 - 30*f1^2*f2*f1*f2^-1 - 12*f1^3*f2^2 + 18*f1^5 
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{Length}}
\logpage{[ 4, 3, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{Length( poly )\index{Length@\texttt{Length}}
\label{Length}
}\hfill{\scriptsize (attribute)}}\\


 This function returns the number of distinct terms in the monoid polynomial. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> Length( pr );
  4
  
\end{Verbatim}
 }

 The boolean function \texttt{poly1 > poly2} returns \texttt{true} if the first polynomial has more terms than the second. If the polynomials are
the same length it will compare their leading terms. If the leading word of
the first is lengthlexicographically greater than the leading word of the
second, or if the words are equal but the coefficient of the first is greater
than the coefficient of the second then true is returned. If the leading terms
are equal then the next terms are compared in the same way. If all terms are
the same then \texttt{false} is returned. 

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> pol > 3*pol;
  false 
  gap> pol > redpol;
  true
  
\end{Verbatim}
 
\section{\textcolor{Chapter }{Reduction of a Monoid Polynomial}}\logpage{[ 4, 4, 0 ]}
{
 

\subsection{\textcolor{Chapter }{ReduceMonoidPoly}}
\logpage{[ 4, 4, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{ReduceMonoidPoly( poly, rules )\index{ReduceMonoidPoly@\texttt{ReduceMonoidPoly}}
\label{ReduceMonoidPoly}
}\hfill{\scriptsize (operation)}}\\


 Recall that the words of a monoid polynomial are elements of a free monoid.
Given a rewrite system (set of rules) on the free monoid the words can be
reduced. This allows us to simulate calculation in monoid rings where the
monid is given by a complete presentation. This function reduces the words of
the polynomial (elements of the free monoid) with respect to the complete
rewrite system. The words of the reduced polynomial are normal forms for the
elements of the monoid presented by that rewite system. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> M := genfgmon;
  [ q8_Ml, q8_M2, q8_M3, q8_M4 ] 
  gap> r2;
  [ q8_Ml*q8_M3, <identity ...>], [ q8_M2*q8_Ml, q8_Ml*q8_M4 ], 
    [ q8_M2^2, q8_Ml^2], [ q8_M2*q8_M3, q8_Ml*q8_M2 ], 
    [ q8_M2*q8_M4, <identity ...> ], [ q8_M3*q8_Ml, <identity ...> ], 
    [ q8_M3*q8_M2, q8_Ml*q8_M4], [ q8_M3^2, q8_Ml^2 ], 
    [ q8_M3*q8_M4, q8_Ml*q8_M2], [ q8_M4*q8_Ml, q8_Ml*q8_M2 ], 
    [ q8_M4*q8_M2, <identity ...> ], [ q8_M4*q8_M3, q8_Ml*q8_M4 ], 
    [ q8_M4^2, q8_Ml^2 ], [ q8_Ml^3, q8_M3], [ q8_Ml^2*q8_M2, q8_M4 ], 
    [ q8_Ml^2*q8_M4, q8_M2 ] ] 
  gap> pol := MonoidPolyFromCoeffsWords([3,2,-5], [M[1]*M[3] ,M[2]-4,M[1]]);
  <monpoly> 
  gap> Print( pol );
  2*q8_M2^4 + 3*q8_Ml*q8_M3 - 5*q8_Ml 
  gap> redpol := ReduceMonoidPoly( pol, KBrules );
  <monpoly> 
  gap> Print( redpol );
  - 5*q8_Ml + 5*<identity ...>
  
\end{Verbatim}
 }

 }

           
\chapter{\textcolor{Chapter }{Module Polynomials}}\label{chap-rws}
\logpage{[ 5, 0, 0 ]}
{
  In this chapter we consider finitely generated modules over the monoid rings
considered previously. We call an element of this module a \emph{module polynomial}, and we describe functions to construct module polynomials and the standard
algebraic operations for such polynomials. 

 A module polynomial \texttt{modpoly} is recorded as a list of pairs, \texttt{[ gen, monpoly ]}, where \texttt{gen} is a module generator (basis element), and \texttt{monpoly} is a monoid polynomial. The module polynomial is printed as the formal sum of
monoid polynomial multiples of the generators. Note that the monoid
polynomials are the coefficients of the module polynomials and appear to the
right of the generator, as we choose to work with right modules. 

 The examples we are aiming for are the identities among the relators of a
finitely presented group (see section \textsc{5.4}). 
\section{\textcolor{Chapter }{Construction of module polynomials}}\logpage{[ 5, 1, 0 ]}
{
 

\subsection{\textcolor{Chapter }{ModulePoly}}
\logpage{[ 5, 1, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{ModulePoly( gens, monpolys )\index{ModulePoly@\texttt{ModulePoly}}
\label{ModulePoly}
}\hfill{\scriptsize (operation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{ModulePoly( args )\index{ModulePoly@\texttt{ModulePoly}}
\label{ModulePoly}
}\hfill{\scriptsize (operation)}}\\


 This function returns a module polynomial. The terms of the polynomial maybe
input as a list of generators followed by a list of monoid polynomials or as
one list of \texttt{[generator, monoid polynomial]} pairs. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> frq8 := FreeRelatorGroup( q8 );
  q8_R 
  gap> genfrq8 := GeneratorsOfGroup( frq8 );
  [ q8_R1, q8_R2, q8_R3, q8_R4 ] 
  gap> mp1 := MonoidPolyFromCoeffsWords( [3,2,-5], [M[1]*M[3], M[2]^4, M[1] ] );
  <monpoly> 
  gap> Print( mp1 );
  2*q8_M2^4 + 3*q8_M1*q8_M3 _ 5*q8_M1 
  gap> mp2 := MonoidPolyFromCoeffsWords( [1,-4,-1,2], 
         [ M[2]*M[3]*M[1], M[3]^3, M[1]*M[2], M[4] ] 
  <monpoly> 
  gap> Print( mp2 );
  - 4*q8_M3^3 + q8_M2*q8_M3*q8_M1 - q8_M1*q8_M2 + 2*q8_M4 
  gap> s1 := ModulePoly( [ genfrq8[4] , genfrq8[1] ], [mp1, mp2 ] );
  <modpoly> 
  gap> Print( s1 );
  q8_R1*( - 4*q8_M3^3 + q8_M2*q8_M3*q8_M1 - q8_M1*q8_M2 + 2*q8_M4) 
    + q8_R4*( 2*q8_M2^4 + 3*q8_M1*q8_M3 - 5*q8_M1) 
  gap> s2 := ModulePoly( [ genfrq8[3], genfrq8[2], genfrq8[1] ], [3*mp1, -1*mp2,\
   (mp1+mp2) ] );
  <modpoly> 
  gap> Print( s2 );
  q8_R1*(2*q8_M2^4 - 4*q8_M3^3 + q8_M2*q8_M3*q8_M1  + 3*q8_M1*q8_M3 
    - q8_M1*q8_M2 + 2*q8_M4 - 5*q8_M1) + q8_R2*(4*q8_M3^3 - q8_M2*q8_M3*q8_M1 
    + q8_M1*q8_M2 - 2*q8_M4) + q8_R3*(6*q8_M2^4 + 9*q8_M1*q8_M3 - 15*q8_M1) 
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Components of a module polynomial}}\logpage{[ 5, 2, 0 ]}
{
 

\subsection{\textcolor{Chapter }{Terms}}
\logpage{[ 5, 2, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{Terms( modpoly )\index{Terms@\texttt{Terms}}
\label{Terms}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LeadTerm( modpoly )\index{LeadTerm@\texttt{LeadTerm}}
\label{LeadTerm}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{LeadMonoidPoly( modpoly )\index{LeadMonoidPoly@\texttt{LeadMonoidPoly}}
\label{LeadMonoidPoly}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{One( modpoly )\index{One@\texttt{One}}
\label{One}
}\hfill{\scriptsize (attribute)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{Length( modpoly )\index{Length@\texttt{Length}}
\label{Length}
}\hfill{\scriptsize (attribute)}}\\


 The first function counts the number of module generators which occur in \texttt{modpoly} (a generator occurs in a polynomial if it has nonzero coefficient). The
function \texttt{One} returns the identity in the free group on the generators. 

 The function \texttt{Terms} returns the terms of a module polynomial as a list of pairs. In \texttt{LeadTerm}, the generators are ordered, and the term of \texttt{modpoly} with the highest value generator is defined to be the leading term. The monoid
polynomial (coefficient) part of the leading term is returned by the function \texttt{LeadMonoidPoly}. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> Length(s1);
  2 
  gap> Length(s2);
  3
  gap> One( s1 ); 
  <identity ...>
  gap> Terms( s1 );
  [ [ q8_R1,  - 4*q8_M3^3 + q8_M2*q8_M3*q8_M1 - q8_M1*q8_M2 + 2*q8_M4 ],
    [ q8_R4, 2*q8_M2^4 + 3*q8_M1*q8_M3 - 5*q8_M1 ] ]
  gap> Terms( s2 );
  [ [ q8_R1, 2*q8_M2^4 - 4*q8_M3^3 + q8_M2*q8_M3*q8_M1 + 3*q8_M1*q8_M3 - q8_M1*q8_M\
  2 + 2*q8_M4 - 5*q8_M1 ],
    [ q8_R2, 4*q8_M3^3 - q8_M2*q8_M3*q8_M1 + q8_M1*q8_M2 - 2*q8_M4 ],
    [ q8_R3, 6*q8_M2^4 + 9*q8_M1*q8_M3 - 15*q8_M1 ] ]
  gap> LeadTerm( s1 ); 
  [ q8_R4, <monpoly> ] 
  gap> LeadTerm( s2 ); 
  [ q8_R3, <monpoly> ] 
  gap> Print( LeadMonoidPoly( s1 ) );
  2*q8_M2^4 + 3*q8_M1*q8_M3 - 5*q8_M1 
  gap> Print( LeadMonoidPoly( s2 ) ); 
  6*q8_M2^4 + 9*q8_M1*q8_M3 - 15*q8_M1 
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{ZeroModulePoly}}
\logpage{[ 5, 2, 2 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{ZeroModulePoly( Fgens, Fmon )\index{ZeroModulePoly@\texttt{ZeroModulePoly}}
\label{ZeroModulePoly}
}\hfill{\scriptsize (operation)}}\\


 Assuming that \texttt{Fgens} is the free group on the module generators and \texttt{Fmon} is the free group on the monoid generators, then this function returns the
zero module polynomial, which has no terms, and is an element of the module. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> zeromp := ZeroModulePoly( frel, freeq8 );
  <modpoly> 
  gap> Print( zeromp );
  zero modpoly
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{AddTermModulePoly}}
\logpage{[ 5, 2, 3 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{AddTermModulePoly( modpoly, gen, monpoly )\index{AddTermModulePoly@\texttt{AddTermModulePoly}}
\label{AddTermModulePoly}
}\hfill{\scriptsize (operation)}}\\


 This function adds a term \texttt{[gen, monpoly]} to a module polynomial \texttt{modpoly}. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> s3 := AddTermModulePoly( s1, frelgen[3], mp1 );
  <modpoly> 
  gap> Print( s3 );
  q8_Rl*( - 4*q8_M3^3 + q8_M2*q8_M3*q8_Ml - q8_Ml*q8_M2 + 2*q8_M4) 
    + q8_R3*( 2*q8_M2^4 + 3*q8_Ml*q8_M3 - 5*q8_Ml) 
    + q8_R4*(2*q8_M2^4 + 3*q8_Ml*q8_M35*q8_Ml)
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Module Polynomial Operations}}\logpage{[ 5, 3, 0 ]}
{
 \index{=,+,* for module polynomials} Tests for equality and arithmetic operations are performed in the usual way.
Module polynomials may be added or subtracted. A module polynomial can also be
multiplied on the right by a word or by a scalar. The effect of this is to
multiply the monoid polynomial parts of each term by the word or scalar. This
is made clearer in the example. 

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> Print( s1 );
  q8_Rl*( - 4*q8_M3^3 + q8_M2*q8_M3*q8_Ml - q8_Ml*q8_M2 + 2*q8_M4) 
    + q8_R4*( 2*q8_M2^4 + 3*q8_Ml*q8_M3 _ 5*q8_Ml) 
  gap> Print( s2 );
  q8_Rl*(2*q8_M2^4 - 4*q8_M3^3 + q8_M2*q8_M3*q8_Ml + 3*q8_Ml*q8_M3 
      - q8_Ml*q8_M2 + 2*q8_M4 - 5*q8_Ml) 
    + q8_R2*(4*q8_M3^ 3 - q8_M2*q8_M3*q8_Ml + q8_Ml*q8_M2 - 2*q8_M4) 
    + q8_R3*(6*q8_M2^4 + 9*q8_Ml*q8_M3 - 15*q8_Ml) 
  gap> Print( s1+s2 );
  q8_Rl*(2*q8_M2^4 - 8*q8_M3^3 + 2*q8_M2*q8_M3*q8_Ml 
      + 3*q8_Ml*q8_M32*q8_Ml*q8_M2 + 4*q8_M4 - 5*q8_Ml) 
    + q8_R2*(4*q8_M3^ 3 - q8_M2*q8_M3*q8_Ml + q8_Ml*q8_M2 - 2*q8_M4) 
    + q8_R3*(6*q8_M2^4 + 9*q8_Ml*q8_M3 - 15*q8_Ml) 
    + q8_R4*(2*q8_M2^4 + 3*q8_Ml*q8_M3 - 5*q8_Ml) 
  gap> Print( s1 - s2 );
  q8_Rl*( - 2*q8_M2^4 - 3*q8_Ml*q8_M3 + 5*q8_Ml) 
    + q8_R2*( - 4*q8_M3^3 + q8_M2*q8_M3*q8_Ml - q8_Ml*q8_M2 + 2*q8_M4) 
    + q8_R3*( - 6*q8_M2^49*q8_Ml*q8_M3 + 15*q8_Ml) + q8_R4*(2*q8_M2^4 
    + 3*q8_Ml*q8_M3 - 5*q8_Ml) 
  gap> Print( s1*1/2 ); 
  q8_R1*( - 2*q8_M3^3 + 1/2*q8_M2*q8_M3*q8_M1 - 1/2*q8_M1*q8_M2 + q8_M4)
    + q8_R4*( q8_M2^4 + 3/2*q8_M1*q8_M3 - 5/2*q8_M1)
  gap> M[1];
  q8_M1
  gap> Print( s1*M[1] );
  q8_R1*( - 4*q8_M3^3_q8_M1 + q8_M2*q8_M3*q8_M1^2 - q8_M1*q8_M2*q8_M1 
    + 2*q8_M4*q8_M1) + q8_R4*( 2*q8_M2^4*q8_M1 + 3*q8_M1*q8_M3*q8_M1 - 5*q8_M1^2)
  gap> Length( s3 );
  3
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Identities among relators}}\logpage{[ 5, 4, 0 ]}
{
 

\subsection{\textcolor{Chapter }{IdentitiesAmongRelators}}
\logpage{[ 5, 4, 1 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{IdentitiesAmongRelators( grp )\index{IdentitiesAmongRelators@\texttt{IdentitiesAmongRelators}}
\label{IdentitiesAmongRelators}
}\hfill{\scriptsize (attribute)}}\\


 The identities among the relators for a finitely presented group are logged
module polynomials. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> idsq8 := IdentitiesAmongRelators( q8 );
  [ [ ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ),
        ( q8_Y10*( -q8_M1*q8_M4), q8_R2*( q8_M2 - <identity ...>) ),
        ( q8_Y17*( <identity ...>), q8_R1*( -q8_M3 - q8_M2) + q8_R3*( q8_M1^
          2 + q8_M3 + q8_M1 + <identity ...>) ),
        ( q8_Y31*( q8_M1*q8_M4), q8_R3*( q8_M3 - q8_M2) + q8_R4*( q8_M1 - <identity\
   ...>) ), ( q8_Y32*( -q8_M1*q8_M4), q8_R2*( -q8_M1^
          2) + q8_R3*( -q8_M3 - <identity ...>) + q8_R4*( q8_M2 + <identity ...>) )
          ,
        ( q8_Y12*( q8_M1*q8_M4), q8_R1*( -q8_M2) + q8_R3*( q8_M1*q8_M2 + q8_M4) + q\
  8_R4*( q8_M2 - <identity ...>) ),
        ( q8_Y16*( -<identity ...>), q8_R1*( -<identity ...>) + q8_R2*( -q8_M1) + q\
  8_R4*( q8_M3 + q8_M1) ) ],
    [ ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ),
        ( q8_Y10*( -q8_M1*q8_M4), q8_R2*( q8_M2 - <identity ...>) ),
        ( q8_Y3*( -q8_M1*q8_M4*q8_M3) + q8_Y17*( <identity ...>), q8_R1*( -q8_M2 - \
  <identity ...>) + q8_R3*( q8_M1^2 + q8_M3 + q8_M1 + <identity ...>) ),
        ( q8_Y31*( q8_M1*q8_M4), q8_R3*( q8_M3 - q8_M2) + q8_R4*( q8_M1 - <identity\
   ...>) ),
        ( q8_Y10*( -q8_M1*q8_M4*q8_M2 - q8_M1*q8_M4) + q8_Y32*( -q8_M1*q8_M4), q8_R\
  2*( -<identity ...>) + q8_R3*( -q8_M3 - <identity ...>) + q8_R4*( q8_M2 + <identi\
  ty ...>) ),
        ( q8_Y12*( q8_M1*q8_M4), q8_R1*( -q8_M2) + q8_R3*( q8_M1*q8_M2 + q8_M4) + q\
  8_R4*( q8_M2 - <identity ...>) ),
        ( q8_Y16*( -<identity ...>), q8_R1*( -<identity ...>) + q8_R2*( -q8_M1) + q\
  8_R4*( q8_M3 + q8_M1) ) ] ]
  gap> RootIdentities( q8 );
  [ ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ),
    ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ) ]
  
\end{Verbatim}
 

\subsection{\textcolor{Chapter }{RootIdentities}}
\logpage{[ 5, 4, 2 ]}\nobreak
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{RootIdentities( grp )\index{RootIdentities@\texttt{RootIdentities}}
\label{RootIdentities}
}\hfill{\scriptsize (attribute)}}\\


 The \emph{root identities} are identities of the form $r^wr^{-1}$ where $r = w^n$ is a relator and $n>1$. 

 }

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> RootIdentities( q8 );
  [ ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ),
    ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ) ]
  
\end{Verbatim}
 }

 }

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

\bibliographystyle{alpha}
\bibliography{manual}

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


\printindex

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