%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%  loops_manual.tex                                                           %
%                                                                             %
%  Main documentation file for the LOOPS package for GAP.                     %
%                                                                             %
%  by Gabor P. Nagy (University of Szeged, Hungary)                           %
%  and Petr Vojtechovsky (University of Denver, USA )                         %
%                                                                             %
%  Nov 2, 2004                                                                %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\documentclass{report}
\usepackage{amssymb}        % for special mathematical symbols
\usepackage{natbib}         % for references
\usepackage{latexcad}       % for diagrams
\usepackage{color}          % for colors
\usepackage{makeidx}        % for index

% defining colors (not all are used)
\definecolor{Gray}{rgb}{0.3,0.3,0.3}
\definecolor{DarkBlue}{rgb}{0,0,0.4}
\definecolor{DarkGreen}{rgb}{0,0.2,0}
\definecolor{DarkRed}{rgb}{0.2,0,0}
\definecolor{DarkGray}{rgb}{0.2,0.2,0.2}
\definecolor{DarkPurple}{rgb}{0.2,0,0.2}

% example in the manual
\newenvironment{gapex}{\vskip 5mm\color{DarkPurple}\hrule}{\hrule\color{black}\vskip 5mm}

% changing page dimensions
\addtolength{\textwidth}{2cm}\addtolength{\hoffset}{-1cm}
\addtolength{\textheight}{3cm}\addtolength{\voffset}{-15mm}

% (c) words :-)
\def\loops{\texttt{LOOPS}}
\def\gap{\texttt{GAP}}

% shorthands
\def\ldiv{\setminus}
\def\rdiv{/}
\def\lsec#1{\mathcal L(#1)}
\def\rsec#1{\mathcal R(#1)}
\def\lmlt#1{\mathrm{LMlt}(#1)}
\def\rmlt#1{\mathrm{RMlt}(#1)}
\def\mlt#1{\mathrm{Mlt}(#1)}

% displaying LOOPS commands
% r = returns
% c = comment
\def\func#1#2#3#4#5{
    \index{#2}   % NG
    \vskip 2mm
    \noindent$\bullet$\ \ \color{DarkBlue}\texttt{#2}\color{black}\texttt{( #3 )\ \ #1}\\
    \phantom{$\bullet$\ \ }\textit{returns:} #4\\
    \phantom{$\bullet$\ \ }\textit{comment:} #5
    \vskip 2mm
}

\def\rfunc#1#2#3#4{
    \index{#2}   % NG
    \vskip 2mm
    \noindent$\bullet$\ \ \color{DarkBlue}\texttt{#2}\color{black}\texttt{( #3 )\ \ #1}\\
    \phantom{$\bullet$\ \ }\textit{comment:} #4\\
    \vskip 2mm
}

\def\cfunc#1#2#3#4{
    \index{#2}   % NG
    \vskip 2mm
    \noindent$\bullet$\ \ \color{DarkBlue}\texttt{#2}\color{black}\texttt{( #3 )\ \ #1}\\
    \phantom{$\bullet$\ \ }\textit{returns:} #4
    \vskip 2mm
}

\def\rcfunc#1#2#3{
    \index{#2}   % NG
    \vskip 2mm
    \noindent$\bullet$\ \ \color{DarkBlue}\texttt{#2}\color{black}\texttt{( #3 )\ \ #1}
    \vskip 2mm
}

% for indexing purposes
\def\idef#1{\emph{#1}\index{#1}}

\makeindex  % NG

\begin{document}

% our own title page

\thispagestyle{empty}

\begin{center}

\phantom{a}\vskip 3cm

{\Huge \textbf{LOOPS}}

\vskip 5mm

Version 0.998

\vskip 1mm

November 4, 2004

\vskip 1cm

{\Huge \textbf{Package for GAP 4}}

\vskip 4cm

{\Large \emph{G\'abor P.~Nagy}}

\vskip 3mm

Department of Mathematics\\
University of Szeged\\
e-mail:  nagyg@math.u-szeged.hu

\vskip 2cm

{\Large \emph{Petr Vojt\v{e}chovsk\'y}}

\vskip 3mm

Department of Mathematics\\
University of Denver\\
e-mail: petr@math.du.edu
\end{center}

\tableofcontents

% INTRODUCTION

\chapter{Introduction}

\noindent \loops\ is a package for \gap4 whose purpose is to:
\begin{enumerate}
\item[(a)] provide researchers in nonassociative algebra with a powerful
computational tool concerning finite loops and quasigroups,

\item[(b)] extend \gap\ toward the realm of nonassociative structures.
\end{enumerate}

\section{Installation}

\noindent We assume that you have \gap\ v.\ 4.4 or newer installed on your
computer. Download the \loops\ package from the distribution website
\begin{displaymath}
    \texttt{http://www.math.du.edu/loops}
\end{displaymath}
Unpack the downloaded file into the \texttt{pkg} subfolder of your \gap\
folder. After this step, there should be a subfolder \texttt{loops} in your
\texttt{pkg} folder. The package \loops\ can then be loaded to \gap\ anytime
by calling \texttt{LoadPackage("loops")}.

If you wish to load \loops\ automatically while starting \gap, proceed as
follows:
\begin{enumerate}
\item[(i)] open the file \texttt{PackageInfo.g} in the \texttt{loops} folder,

\item[(ii)] edit the value of \texttt{Autoload} from \texttt{Autoload:=false}
to \texttt{Autoload:=true}. (The parameter \texttt{Autoload} is located near
the end of the file \texttt{PackageInfo.g}).
\end{enumerate}

\subsection{Brief description of \loops\ files}

\noindent Table \ref{Tb:Files} summarizes all relevant files forming the
\loops\ package. Some technical files (e.g., pictures used in the
documentation) are not mentioned. You probably don't need any of this
information unless you want to modify \loops.

\begin{table}[ht]\index{list of files}
\caption{Brief description of files forming \loops.}\label{Tb:Files}
\begin{small}
\begin{displaymath}
\begin{array}{lll}
    \textrm{folder}&\textrm{file}&\textrm{description}\\
    \hline
    \texttt{pkg}&\texttt{README.loops}&\textrm{installation and usage instructions}\\
    \texttt{pkg/loops}&\texttt{init.g}&\textrm{declaration of \loops\ methods}\\
    \texttt{}&\texttt{PackageInfo.g}&\textrm{loading info for \gap\ 4.4}\\
    \texttt{}&\texttt{read.g}&\textrm{implementation of \loops\ methods}\\
    \texttt{pkg/loops/data}&\texttt{interesting.tbl}&\textrm{library of interesting loops}\\
    \texttt{}&\texttt{leftbol.tbl}&\textrm{library of left Bol loops}\\
    \texttt{}&\texttt{moufang.tbl}&\textrm{library of Moufang loops}\\
    \texttt{}&\texttt{moufang\_discriminators.tbl}&\textrm{data for isomorphisms of Moufang loops}\\
    \texttt{}&\texttt{paige.tbl}&\textrm{library of Paige loops}\\
    \texttt{}&\texttt{steiner.tbl}&\textrm{library of Steiner loops}\\
    \texttt{pkg/loops/doc}&\texttt{loops\_manual.dvi}&\textrm{dvi version of the documentation}\\
    \texttt{}&\texttt{loops\_manual.html}&\textrm{web version of the documentation}\\
    \texttt{}&\texttt{loops\_manual.pdf}&\textrm{pdf version of the documentation}\\
    \texttt{}&\texttt{loops\_manual.ps}&\textrm{postscript version of the documentation}\\
    \texttt{}&\texttt{loops\_manual.tex}&\textrm{\LaTeX source for the documentation}\\
    \texttt{}&\texttt{manual.six}&\textrm{contextual help for \gap}\\
    \texttt{pkg/loops/etc}&\texttt{}&\textrm{utilities for archive and doc generation}\\
    \texttt{pkg/loops/gap}&\texttt{banner.g}&\textrm{banner of \loops}\\
    \texttt{}&\texttt{examples.gd}&\textrm{methods for loop libraries}\\
    \texttt{}&\texttt{loop\_iso.gd}&\textrm{methods for isomorphisms of loops}\\
    \texttt{}&\texttt{moufang\_modifications.gd}&\textrm{methods for Moufang modifications}\\
    \texttt{}&\texttt{quasigrp.gd}&\textrm{core methods of \loops}\\
    \texttt{}&\texttt{triality.gd}&\textrm{methods for triality of Moufang loops}\\
    \texttt{}&\texttt{examples.gi}&\textrm{methods for loop libraries}\\
    \texttt{}&\texttt{loop\_iso.gi}&\textrm{methods for isomorphisms of loops}\\
    \texttt{}&\texttt{moufang\_modifications.gi}&\textrm{methods for Moufang modifications}\\
    \texttt{}&\texttt{quasigrp.gi}&\textrm{core methods of \loops}\\
    \texttt{}&\texttt{triality.gi}&\textrm{methods for triality of Moufang loops}\\
    \texttt{pkg/loops/tst}&\texttt{auto.tst}&\textrm{test automorphism groups}\\
    \texttt{}&\texttt{lib.tst}&\textrm{test all libraries except Moufang}\\
    \texttt{}&\texttt{mouflib.tst}&\textrm{test library of Moufang loops}\\
    \texttt{}&\texttt{nilpot.tst}&\textrm{test nilpotency}\\
    \texttt{}&\texttt{quasigrp.tst}&\textrm{test core functions}\\
    \texttt{}&\texttt{testall.g}&\textrm{batch file for all tests}
\end{array}
\end{displaymath}
\end{small}
\end{table}

\section{Documentation}

\noindent The documentation is available is several formats: \LaTeX, pdf,
dvi, postscript, html, and as an online help in \gap. All these formats have
been obtained directly from the master \LaTeX\ documentation file.
Consequently, the different formats differ only in their appearance, not in
contents.

The documentation can be found in the \texttt{doc} folder of the \loops\
package and also at the \loops\ distribution website.

The online \gap\ help is available upon installing \loops, and can be
accessed in the usual way, i.e., upon typing \texttt{?command}, \gap\
displays the section of the \loops\ manual containing information about
\texttt{command}.

\section{Test files}

\noindent Test files conforming to the \gap\ standards are provided for \loops.
They can be found in the folder \texttt{loops/tst} and run in the usual way.

The file \texttt{testall.tst} runs all tests for \loops\ with the exception
of the test \texttt{mouflib.tst}. The test \texttt{mouflib.tst} builds all
Moufang loops contained in the libraries of \loops, and runs for about 20
minutes.

\section{Mathematical background}

\noindent We assume that you are familiar with the theory of quasigroups and
loops, for instance with the textbook of Bruck \cite{Br} or Pflugfelder
\cite{Pf}. Nevertheless, we did include definitions and results in this
manual in order to unify the terminology and improve the intelligibility of
the text.

\subsection{Quasigroups and loops}

%%% PV 11/02/04, completely rewritten
\noindent A set with one binary operation (denoted $\cdot$ here) is called
\idef{groupoid} or \idef{magma}, the latter name being used in \gap.
Associative groupoids are known as \emph{semigroups}\index{semigroup}.

An element $1$ of a groupoid $G$ is a \idef{neutral element} or an
\idef{identity element} if $1\cdot x = x\cdot 1 = x$ for every $x$ in $G$.
Semigroup with a neutral element is a \idef{monoid}.

Let $G$ be a groupoid with neutral element $1$. Then an element $y$ is called
a \idef{two-sided inverse} of $x$ in $G$ if $x\cdot y = y\cdot x = 1$. A
monoid in which every element has a two-sided inverse is called a
\idef{group}.

Groups can be reached in another way from groupoids, namely through
quasigroups and loops.

A \idef{quasigroup} $Q$ is a groupoid such that the equation $x\cdot y=z$ has
a unique solution in $Q$ whenever two of the three elements $x$, $y$, $z$ of
$Q$ are specified. Note that multiplication tables of finite quasigroups are
precisely \emph{Latin squares}\index{Latin square}, i.e., a square arrays
with symbols arranged so that each symbol occurs in each row and in each
column exactly once. A \idef{loop} $L$ is a quasigroup with a neutral
element.

Groups are clearly loops, and one can show easily that an associative
quasigroup is a group. Hence the theory of quasigroups and loops is in a
sense complementary to the theory of semigroups and monoids.

\subsection{Translations}

\noindent Given an element $x$ of a quasigroup $Q$ we can associative two
permutations of $Q$ with it: the \idef{left translation} $L_x:Q\to Q$ defined
by $y\mapsto x\cdot y$, and the \idef{right translation} $R_x:Q\to Q$ defined
by $y\mapsto y\cdot x$.

Although it is possible to compose two right (left) translations, the
resulting permutation is not necessarily a right (left) translation. The set
$\mathcal L(Q)=\{L_x;x\in Q\}$ is called the \idef{left section} of $Q$, and,
similarly, $\mathcal R(Q)=\{R_x;x\in Q\}$ is the \idef{right section} of $Q$.

Let $S_Q$ be the symmetric group on $Q$. Then $\mathrm{LMlt}(Q)$, the
subgroup of $S_Q$ generated by $\mathcal L(Q)$, is called the \idef{left
multiplication group} of $Q$. Similarly, $\mathrm{RMlt}(Q)= \langle \mathcal
R(Q)\rangle$ is the \idef{right multiplication group} of $Q$. The smallest
group containing both $\mathrm{LMlt}(Q)$ and $\mathrm{RMlt}(Q)$ is called the
\idef{multiplication group} of $Q$ and is denoted by $\mathrm{Mlt}(Q)$.

\subsection{Homomorphisms and homotopisms}\label{Ss:HH}

\noindent Let $K$, $H$ be two quasigroups. Then a map $f:K\to H$ is a
\idef{homomorphism} if $f(x)\cdot f(y)=f(x\cdot y)$ for every $x$, $y\in K$.
If $f$ is also a bijection, we speak of an \idef{isomorphism}, and the two
quasigroups are called \emph{isomorphic}.

The ordered triple $(\alpha,\beta,\gamma)$ of maps $\alpha$, $\beta$,
$\gamma:K\to H$ is a \idef{homotopism} if $\alpha(x)\cdot\beta(y) =
\gamma(x\cdot y)$ for every $x$, $y\in K$. If the three maps are bijections,
$(\alpha,\beta,\gamma)$ is a \idef{isotopism}, and the two quasigroups are
\emph{isotopic}.

Isotopic groups are necessarily isomorphic, but this is certainly not true
for nonassociative quasigroups or loops. In fact, every quasigroup is
isotopic to a loop, as we shall see.

Let $(K,\cdot)$, $(K,\circ)$ be two quasigroups defined on the same set $K$.
Then an isotopism $(\alpha,\beta,\mathrm{id_K})$ is called a \idef{principal
isotopism}. An important class of principal isotopisms is obtained as
follows:

Let $(K,\cdot)$ be a quasigroup, and let $f$, $g$ be elements of $K$. Define
a new operation $\circ$ on $K$ by
\begin{displaymath}
    x\circ y = R_g^{-1}(x)\cdot L_f^{-1}(y),
\end{displaymath}
where $R_g$, $L_f$ are translations. Then $(K,\circ)$ is a quasigroup
isotopic to $(K,\cdot)$, in fact a loop with neutral element $f\cdot g$. We
call $(K,\circ)$ a \idef{principal loop isotope} of $(K,\cdot)$.

\section{How the package works}

\noindent The package consists of three complementary components: the core
algorithms for quasigroup theoretical notions (see Chapter \ref{Ch:Core}),
some specific algorithms, mostly for Moufang loops (see Chapter
\ref{Ch:Specific}), and the library of small loops (see Chapter
\ref{Ch:Lib}).

Although we do not explain the algorithms in detail here, we describe the
overarching ideas so that the user should be able to anticipate the
capabilities and behavior of the computation.

\subsection{Representing quasigroups in \loops}

\noindent Since the permutation representation in the usual sense is impossible for
nonassociative structures, and since the theory of nonassociative
presentations is not well understood, we had to resort to multiplication
tables to represent quasigroups in \gap. In order to save storage space, we
sometimes use one multiplication table to represent several quasigroups (for
instance when a quasigroup is a subquasigroup of another quasigroup).

Consequently, \emph{the package is intended primarily for quasigroups and
loops of small order} (up to $1000$, say).

\subsection{Calculating with quasigroups in \loops}

\noindent Although the quasigroups are ultimately represented by
multiplication tables, the algorithms are efficient because nearly all
calculations are delegated to groups. The connection between quasigroup and
groups is facilitated via the above-mentioned translations, and we illustrate
it with a few examples:
\begin{enumerate}
\item[1)] This example shows how properties of quasigroups can be translated
into properties of translations in a straightforward way.

Let $Q$ be a quasigroup. We ask if $Q$ is associative. We can either test if
$(xy)z=x(yz)$ for every $x$, $y$, $z\in Q$, or we can ask if $L_{xy}=L_xL_y$
for every $x$, $y\in Q$. Note that since $L_{xy}$, $L_x$, $L_y$ are elements
of a permutation group, we do not have to refer directly to the
multiplication table once the left translations of $Q$ are known.

\item[2)] This example shows how properties of loops can be translated into
properties of translations in a way that requires some theory.

A left Bol loop is a loop satisfying $x(y(xz)) = (x(yx))z$. We claim (without
proof) that a loop $L$ is left Bol if and only if $L_xL_yL_x$ is a left
translation for every $x$, $y\in L$.

\item[3)] This example shows that many properties of loops become purely
group-theoretical once they are expresses in terms of translations.

A loop is simple if it has no nontrivial congruences. Then it is easy to see
that a loop is simple if and only if its multiplication group
$\textrm{Mlt}(L)$ is a primitive permutation group.
\end{enumerate}

\noindent The main idea of the package is therefore: (i) calculate the
translations and the associated permutation groups when they are needed, (ii)
store them as attributes, (iii) use them in algorithms as often as possible.

\subsection{Magmas, quasigroups, loops and groups in \gap}

\noindent Whether an object is considered a quasigroup or a loop is a matter
of declaration in \loops. A declared loop is considered to be a quasigroup,
however, a declared quasigroup is \emph{not} considered to be a loop, even if
it accidentally possesses a neutral element. It is possible to convert a
quasigroup $Q$ (with or without a neutral element) to a loop using

\rcfunc{F}{AsLoop}{Q}

\noindent The category of quasigroups (cf. \texttt{IsQuasigroup}) is declared
in \loops\ so that it is contained in the category of magmas (cf.\
\texttt{IsMagma}). All standard \gap\ command for magmas are therefore
available for quasigroups and loops, too.

Although groups are quasigroups mathematically, they are not treated as
quasigroups in \loops. If you wish to apply methods of \loops\ to groups,
apply one of the conversions

\rcfunc{F}{AsQuasigroup}{G}

\rcfunc{F}{AsLoop}{G}

\noindent to the group $G$. These conversions fail when $G$ is infinite and
will exhaust all available memory when $G$ is huge. For more information on
conversions, see subsection \ref{Ss:Conv}.

\section{Feedback}

\noindent We welcome all comments and suggestions on \loops, especially those
concerning the future development of the package. You can contact us by
e-mail.

\chapter{Core methods}\label{Ch:Core}

\section{Naming, viewing and printing objects in \loops}

\noindent \gap\ displays information about objects in two modes:
\texttt{View} (default, short) and \texttt{Print} (longer). Moreover, when
the name of an object is set, it is always shown, no matter which display
mode is used.

\subsection{Named quasigroups and loops}

\noindent Only loops contained in the libraries of \loops\ are named. For
instance, the loop obtained via \texttt{MoufangLoop( 32, 4 )}---the $4$th
Moufang loop of order $32$---is named \texttt{<Moufang loop 32/4>}.

\subsection{View mode}

\noindent When $Q$ is a quasigroup of order $n$, it is displayed as
\texttt{<quasigroup of order n>} in \loops. Similarly, a loop of order $n$
appears as \texttt{<loop of order n>}.

The displayed information for a loop $L$ is enhanced when it is known that
$L$ has certain additional properties. At this point, we support:
\begin{eqnarray*}
    &&\texttt{<associative loop ...>},\\
    &&\texttt{<extra loop ...>},\\
    &&\texttt{<Moufang loop ...>},\\
    &&\texttt{<C loop ...>},\\
    &&\texttt{<left Bol loop ...>},\\
    &&\texttt{<right Bol loop ...>},\\
    &&\texttt{<LC loop ...>},\\
    &&\texttt{<RC loop ...>},\\
    &&\texttt{<alternative loop ...>},\\
    &&\texttt{<left alternative loop ...>},\\
    &&\texttt{<right alternative loop ...>},\\
    &&\texttt{<flexible loop ...>}.
\end{eqnarray*}
The corresponding mathematical definitions and an example can be found in
subsection \ref{Ss:BM}.

It is possible for a loop to have several of the above properties. In such a
case, we display the first property on the list that is satisfied. For
instance, a left alternative flexible loop will appear as \texttt{<left
alternative loop ...>}.

By default, the $m$th element of a quasigroup appears as \texttt{qm}, the
$m$th element of a loop appears as \texttt{lm}, and the neutral element of a
loop is denoted by \texttt{l1}. However, it is possible to change the names
of elements of a quasigroup $Q$ or loop $L$ to \textit{name}\texttt{m} with

\rcfunc{F}{SetQuasigroupElmName}{Q,\ name}

\rcfunc{F}{SetLoopElmName}{L,\ name}

\noindent Also see the example in Section \ref{Sc:Subquasigroups}.

\subsection{Print mode}

\noindent Elements of quasigroups and loops appear in the same way in both
\texttt{View} and \texttt{Print} modes.

For quasigroups and loops in the \texttt{Print} mode, we display the
multiplication table (if it is known), or we display the elements.
See Section \ref{Sc:BasicAttributes} for another way in which multiplication
tables can be displayed.

In the following example, $L$ is a loop with two elements.

%% PV 1104
\begin{gapex}\begin{verbatim}
gap> L;
<loop of order 2>
gap> Print( L );
<loop with multiplication table
[ [  1,  2 ],
  [  2,  1 ] ]
>
gap> Elements( L );
[ l1, l2 ]
gap> SetLoopElmName( L, "loop_element" );; Elements( L );
[ loop_element1, loop_element2 ]
\end{verbatim}\end{gapex}

\section{Creating quasigroups and loops}

\noindent As mentioned above, quasigroups and loops are represented by
multiplication tables, which we also refer to as \emph{Cayley
tables}\index{Cayley table}. When $Q$ is a quasigroup of order $n$, the
associated Cayley table is an $n\times n$ array with symbols $1$, $\dots$,
$n$ such that $\texttt{qi}\cdot\texttt{qj}= \texttt{qk}$ if and only if the
entry in row $i$ and column $j$ is $k$. Similarly for loops.

The Cayley table can be entered manually, or read off from a file.

\subsection{Testing multiplication tables}

\noindent The following synonymous operations test if a multiplication table
is a multiplication table of a quasigroup, i.e. a Latin squares with symbols
$1$, $\dots$, $n$.

\rcfunc{A}{IsQuasigroupTable}{L}

\rcfunc{A}{IsQuasigroupCayleyTable}{L}

\noindent A Latin square on $1$, $\dots$, $n$ is said to be
\emph{normalized}\index{normalized Latin square} if the first column and the
first row read $1$, $\dots$, $n$. Cayley table of a loop is therefore just
another name for a normalized Latin square. The following operations test if
$L$ is a normalized Latin square:

\rcfunc{A}{IsLoopTable}{L}

\rcfunc{A}{IsLoopCayleyTable}{L}

\noindent A Latin square can be normalized by permuting its columns so that
the first row reads $1$, $\dots$, $n$, and then permuting its rows so that
the first column reads $1$, $\dots$, $n$. Note that it matters whether rows
or columns are permuted first (see subsection \ref{Ss:Conv} for more). This
normalization is achieved in \loops\ with

\rcfunc{F}{NormalizedQuasigroupTable}{L}

\noindent We would like to call the attention to the fact that the package
\texttt{GUAVA} also has some operations dealing with Latin squares (in particular,
the function \texttt{IsLatinSquare} is defined in \texttt{GUAVA}).

\subsection{Creating quasigroups and loops manually}

\noindent When $L$ is a Latin square on $1$, $\dots$, $n$, the corresponding
quasigroup is obtained with

\rcfunc{F}{QuasigroupByCayleyTable}{L}
%%% NG 1102
\rcfunc{F}{QuasigroupByCayleyTable}{L, <name>}

\noindent If \texttt{<name>} is given, then the output of the quasigroup
elements will have the form \texttt{<name>1}, \texttt{<name>2},
... \medskip

\noindent When $L$ is normalized, the corresponding loop is returned by

\rcfunc{F}{LoopByCayleyTable}{L}
%\rcfunc{F}{LoopByCayleyTable}{L, <name>}

\subsection{Creating quasigroups and loops from a file}

\noindent Typing a large multiplication table manually is tedious and
error-prone. We have therefore included a universal algorithm in \loops\ that
reads multiplication tables of quasigroups from a file. Instead of writing a
separate algorithm for each common format, our algorithm relies on the user
to provide a bit of information about the input file. Here is an outline of
the algorithm:

\begin{quote}
\noindent \textbf{Input:} filename F, string D\\
\textbf{Step 1}: Read the entire content of F into a string S.\\
\textbf{Step 2}: Replace all end-of-line characters in S by spaces.\\
\textbf{Step 3}: Replace by spaces all characters of S that appear in D.\\
\textbf{Step 4}: Split S into maximal substrings without spaces, called \emph{chunks.}\\
\textbf{Step 5}: Recognize distinct chunks. Let $n$ be the number of distinct chunks.\\
\textbf{Step 6}: If the number of chunks is not $n^2$, report error.\\
\textbf{Step 7}: Construct the multiplication table by assigning numerical
values $1$, $\dots$, $n$ to chunks, depending on their position among
distinct chunks.
\end{quote}

\noindent The following examples clarify the algorithm and document its
versatility:
\begin{small}
\begin{displaymath}
\begin{array}{c|c|c|l}
    \textrm{input file}&\textrm{string D}&\textrm{resulting mult. table}&\textrm{comments}\\
    \hline
    \begin{array}{l}
        0\ 1\ 2\ 1\\
        2\ 0\ 2\\
        0\ 1
    \end{array}
    &
    \textrm{""}
    &
    \begin{array}{l}
        1\ 2\ 3\\
        2\ 3\ 1\\
        3\ 1\ 2
    \end{array}
    &
    \begin{array}{l}
        \textrm{Data does not have to be}\\
        \textrm{arranged into an array of any kind.}
    \end{array}\\
    \hline
    \begin{array}{l}
        \textrm{red green}\\
        \textrm{green red}
    \end{array}&
    \textrm{""}&
    \begin{array}{l}
        1\ 2\\
        2\ 1
    \end{array}&
    \begin{array}{l}
        \textrm{Chunks can be any strings.}
    \end{array}\\
    \hline
    [\ [0, 1],\ [1, 0]\ ]&
    \textrm{"[,]"}&
    \begin{array}{l}
        1\ 2\\
        2\ 1
    \end{array}&
    \begin{array}{l}
        \textrm{A typical table produced by \gap}\\
        \textrm{is easily parsed by deleting}\\
        \textrm{brackets and commas.}
    \end{array}\\
    \hline
    \begin{array}{l}
        \textrm{x\&y\&z$\backslash$hline}\\
        \textrm{y\&z\&x$\backslash$hline}\\
        \textrm{z\&x\&y}
    \end{array}&
    \textrm{"\&$\backslash\backslash$einlh"}&
    \begin{array}{l}
        1\ 2\ 3\\
        2\ 3\ 1\\
        3\ 1\ 2
    \end{array}&
    \begin{array}{l}
        \textrm{A typical \TeX\ table with rows}\\
        \textrm{separated by lines. We must use}\\
        \textrm{"$\backslash\backslash$" in D because "$\backslash\backslash$" represents}\\
        \textrm{the string "$\backslash$" in \gap.}
    \end{array}\\
    \hline
    \begin{array}{l}
        \textrm{I am as mad as}\\
        \textrm{I say I am}
    \end{array}&
    \textrm{"day"}&
    \begin{array}{l}
        1\ 2\ 3\\
        2\ 3\ 1\\
        3\ 1\ 2
    \end{array}&
    \begin{array}{l}
        \textrm{Just for fun.}
    \end{array}
\end{array}
\end{displaymath}
\end{small}

\noindent And here are the needed \loops\ commands:

\rcfunc{F}{QuasigroupFromFile}{F, D}

\rcfunc{F}{LoopFromFile}{F, D}

\subsection{Conversions}\label{Ss:Conv}

\noindent We provide conversion operations that convert between magmas, quasigroups,
loops and groups, provided such conversions are possible.

If $M$ is a declared magma that happens to be a quasigroup,
the corresponding quasigroup is returned via

\rcfunc{F}{AsQuasigroup}{M}

\noindent If $M$ is a magma that happens to be a quasigroup, the operation

\rcfunc{F}{AsLoop}{M}

\noindent returns a loop $L$ as follows:

If $M$ possesses a neutral element $e$ and $f$ is the first element of $M$,
then $L$ is an isomorphic copy of $M$ via the transposition $(e,f)$.

If $M$ does not posses a neutral element, then $L$ is returned as
\begin{displaymath}
    \texttt{PrincipalLoopIsotope(\ M,\ M.1,\ M.1\ )},
\end{displaymath}
where

\rcfunc{F}{PrincipalLoopIsotope}{Q, f, g}

\noindent is the principal isotope of $Q$ using elements $f$, $g$ of $Q$, as
explained in Subsection \ref{Ss:HH}.

Of course, one can obtain a loop from $M$ in different ways, for instance by
normalizing the Cayley table of $M$. The following example shows that these
three approaches can yield different results in general:

\begin{gapex}\begin{verbatim}
gap> A := [[2,1,5,3,4],[1,2,3,4,5],[5,3,4,1,2],[3,4,2,5,1],[4,5,1,2,3]];;
gap> Q := QuasigroupByCayleyTable( A );;
gap> L := AsLoop( Q );;
gap> C := LoopByCayleyTable( NormalizedQuasigroupTable( CayleyTable(L) ) );;
gap> P := PrincipalLoopIsotope( Q, Elements( Q )[ 2 ], Elements( Q )[ 2 ] );
gap> CayleyTable( L );
[ [ 1, 2, 3, 4, 5 ], [ 2, 1, 5, 3, 4 ], [ 3, 5, 4, 2, 1 ],
  [ 4, 3, 1, 5, 2 ], [ 5, 4, 2, 1, 3 ] ]
gap> CayleyTable( C );
[ [ 1, 2, 3, 4, 5 ], [ 2, 1, 4, 5, 3 ], [ 3, 5, 1, 2, 4 ],
  [ 4, 3, 5, 1, 2 ], [ 5, 4, 2, 3, 1 ] ]
gap> CayleyTable( P );
[ [ 1, 2, 3, 4, 5 ], [ 2, 1, 4, 5, 3 ], [ 3, 4, 5, 2, 1 ],
  [ 4, 5, 1, 3, 2 ], [ 5, 3, 2, 1, 4 ] ]
\end{verbatim}\end{gapex}

\noindent Finally, when $M$ is a declared magma that happens to be a group, then the
corresponding group is returned by

\rcfunc{F}{AsGroup}{M}

\noindent Note that the conversions work in both directions, not just toward
more special structures. Thus, if $G$ is a declared group, then
\texttt{AsLoop( G )} returns the corresponding loop, for instance.

\subsection{Products of loops}

\noindent Let $L1$, $\dots$, $Ln$ be a list consisting of loops and groups,
where $n\ge 1$. Then

\rcfunc{F}{DirectProduct}{L1, ..., Ln}

\noindent returns the direct product of $L1$, $\dots$, $Ln$.

If there are only groups on the list, a group is returned, otherwise a
loop is returned. If $n=1$, $L1$ is returned.

\subsection{Opposite quasigroups and loops}

\noindent When $Q$ is a quasigroup with multiplication $\cdot$, the
\idef{opposite quasigroup} of $Q$ is a quasigroup with the same underlying
set as $Q$ and with multiplication $*$ defined by $x*y=y\cdot x$.

Since the quasigroup-theoretical concepts are often oriented (cf. left Bol
loops versus right Bol loops), it is useful to have access to the opposite
quasigroup of $Q$:

\rcfunc{F}{Opposite}{Q}

\section{GAP categories}

\noindent One can test if an element $x$ belong to a quasigroup or to a loop,
or if a given object $Q$ is a quasigroup or a loop:

\rcfunc{category}{IsQuasigroupElement}{x}

\rcfunc{category}{IsLoopElement}{x}

\rcfunc{category}{IsQuasigroup}{Q}

\rcfunc{category}{IsLoop}{Q}

\section{Basic attributes}\label{Sc:BasicAttributes}

\noindent The list of elements of a quasigroup $Q$ is obtained by the usual
command

\rcfunc{A}{Elements}{Q}

\noindent The Cayley table of a quasigroup $Q$ is returned with

\rcfunc{A}{CayleyTable}{Q}

\noindent One can use \texttt{Display( CayleyTable( Q ) )} for pretty
matrix-style output of small Cayley tables.

The neutral element of a loop $L$ is obtained via

\rcfunc{A}{One}{L}

\noindent If you want to know if a quasigroup $Q$ has a neutral element, you
can find out with the standard function for magmas

\rcfunc{A}{MultiplicativeNeutralElement}{ Q }

\noindent The size of a quasigroup $Q$ is calculated by

\rcfunc{A}{Size}{Q}

 \noindent When $L$ is a power associative loop (i.e., the
orders of elements are well-defined in $L$), the \idef{exponent} of $L$ is
the smallest positive integer divided by orders of all elements of $L$. The
following attribute calculates the exponent without testing for power
associativity:

\rcfunc{A}{Exponent}{L}

\begin{gapex}\begin{verbatim}
gap> Q := QuasigroupByCayleyTable( [ [ 1, 2 ], [ 2, 1 ] ] );
<quasigroup of order 2>
gap> [ IsQuasigroup( Q ); IsLoop( Q ); Size( Q ); Elements( Q ); ]
[ true, false, 2, [ q1, q2 ] ]
gap> IsQuasigroupElement( Elements( Q )[ 2 ] );
true
gap> CayleyTable( Q );
[ [ 1, 2 ], [ 2, 1 ] ]
\end{verbatim}\end{gapex}

\section{Basic arithmetic operations}

\noindent Each quasigroup element in \gap\ knows which quasigroup it
belongs to. It is therefore possible to perform arithmetic operations with
quasigroup elements without referring to the quasigroup. All elements
involved in the calculation must belong to the same quasigroup.

\subsection{Multiplication}

\noindent Two elements $x$, $y$ of the same quasigroup are multiplied by $x*y$ in \gap. Since
multiplication of elements is ambiguous in the nonassociative case, we always multiply
element from left to right (i.e., $x*y*z$ means $(x*y)*z)$). Of course, one can specify
association by parentheses.

\subsection{Division}

\noindent Universal algebraists introduce two additional operations for
quasigroups. Namely the \idef{left division} $x\backslash y$ satisfying
$x\cdot(x\backslash y)=y$, and the \idef{right division} $x/y$ satisfying
$x/y\cdot y=x$. Since the two symbols $/$ and $\backslash$ are already used
for different purposes in \gap, we instead introduce:

\rcfunc{O}{LeftDivision}{x, y}

\rcfunc{O}{RightDivision}{x, y}

\subsection{Powers and inverses}\label{Ss:Invs}

\noindent Powers of elements are not well-defined in quasigroups, since
bracketing can matter even for a single element. We say that the quasigroup
$Q$ is \idef{monoassociative}, if for any $x\in Q$, the submagma generated
by $x$ is associative. Similarly, the loop $L$ is said to be
\idef{power associative}, if for any $x\in L$, the subloop generated by $x$
is associative.

For magmas and positive integer exponents, \gap\ defines the powers in the
following way: $x^1=x$, $x^{2k}=(x^k)\cdot(x^k)$ and
$x^{2k+1}=(x^{2k})\cdot x$ for positive integer $k$. One can easily see
that this returns $x^k$ in $\log_2(k)$ steps. For \loops, we decided to
keep this method, hoping that everybody will use it with care for
quasigroups.

\noindent Let $x$ be an element of a loop $L$ with neutral element $1$. Then the
\idef{left inverse} $x'$ of $x$ is the unique element of $L$ satisfying
$x'x=1$. Similarly, the \idef{right inverse} $x''$ satisfies $xx''=1$. If
$x'=x''$, we call $x^{-1}=x'=x''$ the \idef{inverse} of $x$.

\rcfunc{O}{LeftInverse}{x}

\rcfunc{O}{RightInverse}{x}

\rcfunc{O}{Inverse}{x}

\noindent The following examples illustrates the usage of arithmetic
operations. \texttt{MoufangLoop} will be explained in Chapter \ref{Ch:Lib}.
In this example, \texttt{M.i} coincides with \texttt{Elements( M )[ i ]}.

\begin{gapex}\begin{verbatim}
gap> M := MoufangLoop( 12, 1 );; x := M.2;
l2
gap> [ x * M.3, x^2, x^(-1), Inverse( x ) ];
[ l4, l1, l2, l2 ]
gap> One( M ) = LeftDivision( x, x );
true
\end{verbatim}\end{gapex}

\subsection{Associators and commutators}

\noindent Let $Q$ be a quasigroup and $x$, $y$, $z\in Q$. Then the
\idef{associator} of $x$, $y$, $z$ is the unique element $u$ such that
$(xy)z=(x(yz))u$. The \idef{commutator} of $x$, $y$ is the unique element $v$
such that $xy=(yx)v$.

\rcfunc{O}{Associator}{x, y, z}

\rcfunc{O}{Commutator}{x, y}


\section{Generators}

%%% PV 1102
\noindent The following two attributes are synonyms of
\texttt{GeneratorsOfMagma}.

\rcfunc{A}{GeneratorsOfQuasigroup}{Q}

\rcfunc{A}{GeneratorsOfLoop}{L}

\noindent  As usual in \gap, one can refer to the $i$th
generator of a quasigroup $Q$ by \texttt{Q.i}. Note that it is not necessarily
the case that \texttt{Q.i = Elements( Q )[ i ]}, since the set of generators
can be a proper subset of the elements.

It is easy to prove that a loop of order $n$ can be generated by a subset
containing at most $\log_2{n}$ elements. Such a set is returned via

\rcfunc{A}{SmallGeneratingSet}{L}

\section{Permutations associated with loops}

\subsection{Sections}

\noindent The following two attributes calculate the left and right section of a
quasigroup $Q$:

\rcfunc{A}{LeftSection}{Q}

\rcfunc{A}{RightSection}{Q}

\noindent Given an element $x$ of a quasigroup $Q$, the left and right translations
of $Q$ by $x$ are obtained by

\rcfunc{F}{LeftTranslation}{Q, x}

\rcfunc{F}{RightTranslation}{Q, x}

\subsection{Multiplication groups}

\noindent The left multiplication group, right multiplication group and the multiplication
group of a quasigroup $Q$ is calculated as follows:

\rcfunc{A}{LeftMultiplicationGroup}{Q}

\rcfunc{A}{RightMultiplicationGroup}{Q}

\rcfunc{A}{MultiplicationGroup}{Q}

\noindent The relative versions of multiplication groups are implemented only for loops.
When $S$ is a subloop of a loop $L$, the following functions return the relative
multiplication groups:

\rcfunc{F}{RelativeLeftMultiplicationGroup}{L, S}

\rcfunc{F}{RelativeRightMultiplicationGroup}{L, S}

\rcfunc{F}{RelativeMultiplicationGroup}{L, S}

\subsection{Inner mapping group}

%%% NG1102
\noindent The \idef{inner mapping group} of a loop $L$ is the stabilizer of
the unit element in $\mlt{L}$. The elements of this stabilizer are called
\emph{inner maps} of $L$. The inner mapping group of a loop $L$ is obtained
by:

\rcfunc{A}{InnerMappingGroup}{L}

\begin{gapex}\begin{verbatim}
gap> M := MoufangLoop( 12, 1 );
<Moufang loop 12/1>
gap> LeftSection( M )[ 2 ];
(1,2)(3,4)(5,6)(7,8)(9,12)(10,11)
gap> Mlt := MultiplicationGroup( M ); Inn := InnerMappingGroup( M );
<permutation group of size 2592 with 23 generators>
Group([ (4,6)(7,11), (7,11)(8,10), (2,6,4)(7,9,11), (3,5)(9,11), (8,12,10) ])
gap> Size( Inn );
216
\end{verbatim}\end{gapex}

\section{Subquasigroups and subloops}\label{Sc:Subquasigroups}

\noindent Let $Q$ be a quasigroup and $S$ a subquasigroup of $Q$. Since the multiplication
in $S$ coincides with the multiplication in $Q$, it is reasonable not to store
the multiplication table of $S$. However, the quasigroup $S$ then must know that
it is a subquasigroup of $Q$. In order to facilitate this relationship, we introduce
the attribute

\rcfunc{A}{Parent}{Q}

\noindent for quasigroups. When $Q$ is \emph{not} created as a subquasigroup of
another quasigroup, the attribute \texttt{Parent( Q )} is set to $Q$.
When $Q$ is created as a subquasigroup
of a quasigroup $H$, we set \texttt{Parent( Q ) := Parent( H )}. Thus, in effect,
\texttt{Parent( Q )} is the largest quasigroup from which $Q$ was created.

Given a collection $C$ of elements of a quasigroup $Q$, the function

\rcfunc{F}{PosInParent}{C}

\noindent returns the list of positions of the elements of $C$ among the elements of
\texttt{Parent( Q )}. The multiplication in $Q$ can therefore be easily reconstructed
from \texttt{Parent( Q )} via \texttt{PosInParent}.

When $S$ is a subset of a quasigroup $Q$ (loop $L$), the subquasigroup of $Q$ (subloop
of $L$) is returned via:

\rcfunc{F}{Subquasigroup}{Q, S}

\rcfunc{F}{Subloop}{L, S}

\noindent Finally, the following two functions test if a quasigroup (loop) $S$ is a subquasigroup
(subloop) of a quasigroup $Q$ (loop $L$). Note that the functions return false when
$S$ and $Q$ ($L$) do not have the same parent.

\rcfunc{F}{IsSubquasigroup}{Q, S}

\rcfunc{F}{IsSubloop}{L, S}

\noindent The following example illustrates the main features of the
subquasigroup construction. Note how the Cayley table of the subquasigroup is
created only upon explicit demand. Also note that changing the names of
elements of a suquasigroup (subloop) automatically changes the names of the
elements of the parent subquasigroup (subloop). This is because the elements
are shared.

\begin{gapex}\begin{verbatim}
gap> M := MoufangLoop( 12, 1 );; S := Subloop( M, [ M.5 ] );
<loop of order 3>
gap> [ Parent( S ) = M, Elements( S ), PosInParent( S ) ];
[ true, [ l1, l3, l5], [ 1, 3, 5 ] ]
gap> HasCayleyTable( S );
false
gap> SetLoopElmName( S, "s" );; Elements( S ); Elements( M );
[ s1, s3, s5 ]
[ s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12 ]
gap> CayleyTable( S );
[ [ 1, 2, 3 ], [ 2, 3, 1 ], [ 3, 1, 2 ] ]
gap> [ HasCayleyTable( S ), Parent( S ) = M ];
[ true, true]
gap> L := LoopByCayleyTable( CayleyTable( S ) );
<loop of order 3>
gap> [ Parent( L ) = L, IsSubloop( M, S ), IsSubloop( M, L ) ];
[ true, true, false ]
\end{verbatim}\end{gapex}

\section{Nucleus, commutant, center}

\noindent Let $Q$ be a quasigroup. The \idef{left nucleus} $N_\lambda(Q)$ of $Q$ is
the set $\{x\in Q;\; x(yz)=(xy)z$ for every $y$, $z\in Q\}$. One defines
similarly the \idef{middle nucleus} $N_\mu(Q)$ and the \idef{right nucleus}
$N_\rho(Q)$. Then the \idef{nucleus} $N(Q)$ of $Q$ is equal to
$N_\lambda(Q)\cap N_\mu(Q)\cap N_\rho(Q)$. These nuclei are calculated in
\loops\ as follows:

\rcfunc{A}{LeftNucleus}{Q}

\rcfunc{A}{MiddleNucleus}{Q}

\rcfunc{A}{RightNucleus}{Q}

\rcfunc{A}{Nuc}{Q}

\noindent The word \texttt{Nucleus} is reserved in the core \gap\ system for a
function in two variables, therefore we use the abbreviation \texttt{Nuc},
which is also common in the literature. However, we support these synonyms
of \texttt{Nuc}:

\rcfunc{A}{NucleusOfLoop}{Q}

\rcfunc{A}{NucleusOfQuasigroup}{Q}

\noindent Since all nuclei are subquasigroups of $Q$, they are returned as subquasigroups
(or subloops).

\noindent The \idef{commutant} $C(Q)$ of $Q$ is the set $\{x\in Q;\;xy=yx$
for every $y\in Q\}$. It is also known under the name \idef{Moufang center}.
It is obtained via

\rcfunc{A}{Commutant}{Q}

\noindent The center $Z(Q)$ is defined as $C(Q)\cap N(Q)$, and it is obtained via

\rcfunc{A}{Center}{Q}

\noindent Finally, the \idef{associator subloop} of a loop $L$ is the subloop
of $L$ generated by all associators of $L$. (Note that some authors define the
associator subloop as the smallest normal subloop $A$ of $L$ such that $L/A$
is associative. The two definitions are not equivalent in general.)

\rcfunc{A}{AssociatorSubloop}{L}

\section{Testing properties}

\noindent The reader should be aware that although loops are quasigroups, it
is often the case in the literature that a property named $P$ can differ for
quasigroups and loops; for instance, a Steiner loop is not necessarily a
Steiner quasigroup. To avoid such ambivalences, we often include the noun
\texttt{Loop} or \texttt{Quasigroup} as part of the name of the property;
e.g. \texttt{IsSteinerQuasigroup} versus \texttt{IsSteinerLoop}. On the other
hand, some properties coincide for quasigroups and loops and we therefore do
not include \texttt{Loop}, \texttt{Quasigroup} as part of the name of the
property; e.g. \texttt{IsCommutative}.

\subsection{Associativity, commutativity and generalizations}

\noindent The following properties test if a quasigroup $Q$ is associative
and commutative.

\rcfunc{P}{IsAssociative}{Q}

\rcfunc{P}{IsCommutative}{Q}

\noindent A loop $L$ is said to be \emph{power associative} (resp.\
\emph{diassociative})\index{power associativity}\index{diassoicativy} if
every monogenic subloop of $L$ (resp. every $2$-generated subloop of $L$) is
a group.

\rcfunc{P}{IsPowerAssociative}{L}

\rcfunc{P}{IsDiassociative}{L}

\subsection{Inverse properties}

\noindent A loop $L$ has the \idef{left inverse property} if $x'(xy)=y$ for
every $x$, $y\in L$, where $x'$ is the left inverse of $x$. Dually, $L$ has
the \idef{right inverse property} if $(yx)x''=y$ for every $x$, $y\in L$,
where $x''$ is the right inverse of $x$. If $L$ has both the left and right
inverse property, it has the \idef{inverse property}. We say that $L$ has
\idef{two-sided inverses} if $x'=x''$ for every $x\in L$.

\rcfunc{P}{HasLeftInverseProperty}{L}

\rcfunc{P}{HasRightInverseProperty}{L}

\rcfunc{P}{HasInverseProperty}{L}

\rcfunc{P}{HasTwosidedInverses}{L}

\noindent A loop $L$ with two-sided inverses has the \idef{automorphic
inverse property} if $(xy)^{-1}=x^{-1}y^{-1}$ for every $x$, $y\in L$.
Similarly, it has the \idef{antiautomorphic inverse property} if
$(xy)^{-1}=y^{-1}x^{-1}$.

\rcfunc{P}{HasAutomorphicInverseProperty}{L}

\rcfunc{P}{HasAntiautomorphicInverseProperty}{L}

\noindent There are many additional inverse properties but we decided against
including them at this stage.

\subsection{Properties of quasigroups}

\noindent A quasigroup $Q$ is \emph{semisymmetric}\index{semisymmetric
quasigroup} if $(xy)x=y$ for every $x$, $y\in Q$. Equivalently, $Q$ is
semisymmetric if $x(yx)=y$ for every $x$, $y\in Q$. A semisymmetric
commutative quasigroup is known as \emph{totally symmetric}\index{totally
symmetric quasigroup}. Totally symmetric quasigroups are precisely
quasigroups satisfying $xy=x\ldiv y = x\rdiv y$.

\rcfunc{P}{IsSemisymmetric}{Q}

\rcfunc{P}{IsTotallySymmetric}{Q}

\noindent A quasigroup $Q$ is \idef{idempotent} if $x^2=x$ for every $x\in
Q$. Idempotent totally symmetric quasigroups are known as \emph{Steiner
quasigroups}\index{Steiner quasigroup}. A quasigroup $Q$ is
\emph{unipotent}\index{unipotent quasigroup} if $x^2=y^2$ for every $x$,
$y\in Q$.

\rcfunc{P}{IsIdempotent}{Q}

\rcfunc{P}{IsSteinerQuasigroup}{Q}

\rcfunc{P}{IsUnipotent}{Q}

\noindent A quasigroup is \emph{left distributive}\index{left distributive
quasigroup} if it satisfies $x(yz)=(xy)(xz)$. Similarly, it is \emph{right
distributive}\index{right distributive quasigroup} if it satisfies
$(xy)z=(xz)(yz)$. A \idef{distributive quasigroup} is a quasigroup that is
both left and right distributive. A quasigroup is called
\emph{entropic}\index{entropic quasigroup} or \emph{medial}\index{medial
quasigroup} if it satisfies $(xy)(zw)=(xz)(yw)$.

\rcfunc{P}{IsLeftDistributive}{Q}

\rcfunc{P}{IsRightDistributive}{Q}

\rcfunc{P}{IsDistributive}{Q}

\rcfunc{P}{IsEntropic}{Q}

\rcfunc{P}{IsMedial}{Q}

\noindent TO be compatible with GAP's terminology, we also support the
synonyms

\rcfunc{P}{IsLDistributive}{Q}

\rcfunc{P}{IsRDistributive}{Q}

\noindent for \texttt{IsLeftDistributive} and \texttt{IsRightDistributive},
respectively.

\subsection{Loops of Bol-Moufang type and related properties}\label{Ss:BM}

\noindent Following \cite{Fe} and \cite{PV}, a variety of loops is said to be
of \emph{Bol-Moufang type}\index{loops of Bol-Moufang type} if it is defined
by a single \emph{identity of Bol-Moufang type}, i.e., by an identity that:
(i) contains the same $3$ variables on both sides, (ii) exactly one of the
variables occurs twice on both sides, (iii) the variables occur in the same
order on both sides.

It is proved in \cite{PV} that there are $13$ varieties of nonassociative loops
of Bol-Moufang type, as summarized in Figure \ref{Fg:L}.

%FIGURE
\setlength{\unitlength}{1mm}
\begin{figure}[ht]\begin{center}\input{Ldiag.lp}\end{center}
\caption{Varieties of loops of Bol-Moufang type.}\label{Fg:L}
\end{figure}

Note that although some of the defining identities are not of Bol-Moufang type,
they are equivalent to a Bol-Moufang identity. Moreover, some varieties
in the Figure are defined by several, equivalent identities of Bol-Moufang type.

There are several varieties related to loops of Bol-Moufang type. A loop is
said to be: \emph{alternative}\index{alternative loop} if it is both left and right
alternative; \idef{nuclear square loop} if it is left, middle and right nuclear square.

Here are the corresponding \gap\ commands (argument $L$ indicates that the property
applies only to loops, argument $Q$ indicates that the property applies to
quasigroups):

\rcfunc{P}{IsExtraLoop}{L}

\rcfunc{P}{IsMoufangLoop}{L}

\rcfunc{P}{IsCLoop}{L}

\rcfunc{P}{IsLeftBolLoop}{L}

\rcfunc{P}{IsRightBolLoop}{L}

\rcfunc{P}{IsLCLoop}{L}

\rcfunc{P}{IsRCLoop}{L}

\rcfunc{P}{IsLeftNuclearSquareLoop}{L}

\rcfunc{P}{IsMiddleNuclearSquareLoop}{L}

\rcfunc{P}{IsRightNuclearSquareLoop}{L}

\rcfunc{P}{IsNuclearSquareLoop}{L}

\rcfunc{P}{IsFlexible}{Q}

\rcfunc{P}{IsLeftAlternative}{Q}

\rcfunc{P}{IsRightAlternative}{Q}

\rcfunc{P}{IsAlternative}{Q}

\noindent All inclusions among the varieties of loops of Bol-Moufang type are summarized
in Figure \ref{Fg:L}, and all these inclusions are built into the \loops\ package.
(See Section \ref{Sc:Filters}.)

The following trivial example shows some of the implications and the naming conventions
of \loops\ at work:

\begin{gapex}\begin{verbatim}
gap> L := LoopByCayleyTable( [ [ 1, 2 ], [ 2, 1 ] ] );
<loop of order 2>
gap> IsLeftBolLoop( L );
true
gap> [ HasIsLeftAlternativeLoop( L ), IsLeftAlternativeLoop( L ) ];
[ true, true ]
gap> [ HasIsRightBolLoop( L ), IsRightBolLoop( L ) ];
[ false, true ]
gap> L;
<Moufang loop of order 2>
gap> [ IsAssociative( L ), L ];
[ true, <associative loop of order 2> ]
\end{verbatim}\end{gapex}

\noindent The analogous terminology for quasigroups of Bol-Moufang type is not
standard yet, and hence is not supported in \loops.

\subsection{Conjugacy closed loops}

\noindent A loop is \emph{left} (resp.\ \emph{right}) \emph{conjugacy
closed}\index{left conjugacy closed loop}\index{right conjugacy closed loop}
if its left (resp.\ right) translations are closed under composition. A loop
that is both left and right conjugacy closed is called \emph{conjugacy
closed}\index{conjugacy closed loop}. It is common to refer to these loops
are LCC, RCC, CC-loops, respectively.

\rcfunc{P}{IsLCCLoop}{L}

\rcfunc{P}{IsRCCLoop}{L}

\rcfunc{P}{IsCCLoop}{L}

\noindent The equivalence LCC $+$ RCC $=$ CC is built into the \loops\ package.


\subsection{Additional varieties of loops}

\noindent A left (resp. right) Bol loop with the automorphic inverse property
is known as \emph{left} (resp. \emph{right})
\emph{Bruck loop}\index{left Bruck loop}\index{right Bruck loop}.
Bruck loops are also known as \emph{K-loops}\index{K-loop}.

\rcfunc{P}{IsLeftBruckLoop}{L}

\rcfunc{P}{IsLeftKLoop}{L}

\rcfunc{P}{IsRightBruckLoop}{L}

\rcfunc{P}{IsRightKLoop}{L}

\noindent \idef{Steiner loop} is an inverse property loop of exponent $2$.

\rcfunc{P}{IsSteinerLoop}{L}

\section{Normality}

\noindent A subloop $S$ of a loop $L$ is \emph{normal}\index{normal subloop}
if it is invariant under all inner mappings of $L$. Normality is tested via:

\rcfunc{F}{IsNormal}{L, S}

\noindent When $S$ is a subset of a loop $L$ or a subloop of $L$\, the
\idef{normal closure} of $S$ in $L$ is the smallest normal subloop of $L$
containing $S$. It is obtained by

\rcfunc{F}{NormalClosure}{L, S}

\noindent A loop $L$ is \emph{simple}\index{simple loop} if all normal
subloops of $L$ are trivial. The corresponding test in \loops\ is:

\rcfunc{P}{IsSimple}{L}

\section{Factor loop}

\noindent When $N$ is a normal subloop of a loop $L$, the factor loop $L/N$ can be obtained
directly via the command \texttt{L/N}, or by

\rcfunc{F}{FactorLoop}{L, N}

\noindent The natural projection from $L$ to $L/N$ is returned as follows:

\rcfunc{F}{NaturalHomomorphismByNormalSubloop}{L, N}

\begin{gapex}\begin{verbatim}
gap> M := MoufangLoop( 12, 1 );; S := Subloop( M, [ M.3 ] );
<loop of order 3>
gap> IsNormal( M, S );
true
gap> F := FactorLoop( M, S );
<loop of order 4>
gap> NaturalHomomorphismByNormalSubloop( M, S );
MappingByFunction( <loop of order 12>, <loop of order 4>,
    function( elm ) ... end )
\end{verbatim}\end{gapex}

\section{Nilpotency}

\noindent The definition of nilpotency and nilpotence class is the same as in
group theory. The corresponding commands are:

\rcfunc{A}{NilpotencyClassOfLoop}{L}

\rcfunc{P}{IsNilpotent}{L}

\noindent When $L$ is not nilpotent, \texttt{NilpotencyClassOfLoop( L )}
returns \texttt{fail}.

A loop $L$ is said to be \emph{strongly nilpotent}\index{strongly nilpotent
loop} if its multiplication group is nilpotent. This property is obtained by:

\rcfunc{P}{IsStronglyNilpotent}{L}

\section{Solvability}

\noindent The definition of solvability, derived subloop, derived length,
Frattini subloop and Frattini factor size is the same as for groups. Frattini
subloop is calculated only for strongly nilpotent loops.

\rcfunc{P}{IsSolvable}{L}

\rcfunc{A}{DerivedSubloop}{L}

\rcfunc{A}{DerivedLength}{L}

\rcfunc{A}{FrattiniSubloop}{L}

\rcfunc{A}{FrattinifactorSize}{L}

\section{Filters built into \loops}\label{Sc:Filters}

\noindent Many implications among properties of loops are built directly into
\loops. A sizeable portion of these properties are of trivial character or
are based on definitions (e.g., alternative loops $=$ left alternative loops $+$ right
alternative loops). The remaining implications are theorems.

All filters of \loops\ are summarized below (using the \gap\ convention that
the property on the left is implied by the property (properties) on the right).

\begin{scriptsize}
\begin{verbatim}
( IsExtraLoop,  IsAssociative and IsLoop )
( IsDiassociative, IsAssociative and IsLoop )
( HasInverseProperty, HasRightInverseProperty and IsCommutative )
( HasInverseProperty, HasLeftInverseProperty and IsCommutative )
( IsMoufangLoop, IsRightBolLoop and IsCommutative )
( IsMoufangLoop, IsLeftBolLoop and IsCommutative )
( IsMoufangLoop, IsRightBruckLoop and IsCommutative )
( IsMoufangLoop, IsLeftBruckLoop and IsCommutative )
( IsRightNuclearSquareLoop, IsLeftNuclearSquareLoop and IsCommutative )
( IsLeftNuclearSquareLoop, IsRightNuclearSquareLoop and IsCommutative )
( HasAutomorphicInverseProperty, HasAntiautomorphicInverseProperty and IsCommutative )
( HasAntiautomorphicInverseProperty, HasAutomorphicInverseProperty and IsCommutative )
( IsAlternative, IsLeftAlternative and IsCommutative )
( IsAlternative, IsRightAlternative and IsCommutative )
( HasTwosidedInverses, IsPowerAssociative )
( IsPowerAssociative, IsDiassociative )
( IsAlternative, IsDiassociative )
( IsFlexible, IsDiassociative )
( HasLeftInverseProperty, HasInverseProperty )
( HasRightInverseProperty, HasInverseProperty )
( HasTwosidedInverses, HasInverseProperty )
( HasInverseProperty, HasLeftInverseProperty and HasRightInverseProperty )
( IsMoufangLoop, IsExtraLoop )
( IsNuclearSquareLoop, IsExtraLoop )
( IsCLoop, IsExtraLoop )
( IsExtraLoop, IsMoufangLoop and IsLeftNuclearSquareLoop )
( IsExtraLoop, IsMoufangLoop and IsMiddleNuclearSquareLoop )
( IsExtraLoop, IsMoufangLoop and IsRightNuclearSquareLoop )
( IsLeftBolLoop, IsMoufangLoop )
( IsRightBolLoop, IsMoufangLoop )
( IsFlexible, IsMoufangLoop )
( IsDiassociative, IsMoufangLoop )
( IsMoufangLoop, IsLeftBolLoop and IsRightBolLoop )
( IsLCLoop, IsCLoop )
( IsRCLoop, IsCLoop )
( IsCLoop, IsLCLoop and IsRCLoop )
( IsLeftAlternative, IsLeftBolLoop )
( HasTwosidedInverses, IsLeftBolLoop )
( IsRightAlternative, IsRightBolLoop )
( HasTwosidedInverses, IsRightBolLoop )
( IsLeftAlternative, IsLCLoop )
( IsLeftNuclearSquareLoop, IsLCLoop )
( IsMiddleNuclearSquareLoop, IsLCLoop )
( IsPowerAssociative, IsLCLoop )
( IsRightAlternative, IsRCLoop )
( IsRightNuclearSquareLoop, IsRCLoop )
( IsMiddleNuclearSquareLoop, IsRCLoop )
( IsPowerAssociative, IsRCLoop )
( IsLeftNuclearSquareLoop, IsNuclearSquareLoop )
( IsRightNuclearSquareLoop, IsNuclearSquareLoop )
( IsMiddleNuclearSquareLoop, IsNuclearSquareLoop )
( IsNuclearSquareLoop, IsLeftNuclearSquareLoop and IsRightNuclearSquareLoop and IsMiddleNuclearSquareLoop )
( IsLeftAlternative, IsAlternative )
( IsRightAlternative, IsAlternative )
( IsAlternative, IsLeftAlternative and IsRightAlternative )
( IsLCCLoop, IsCCLoop )
( IsRCCLoop, IsCCLoop )
( IsCCLoop, IsLCCLoop and IsRCCLoop )
( HasAutomorphicInverseProperty, IsLeftBruckLoop )
( IsLeftBolLoop, IsLeftBruckLoop )
( IsLeftBruckLoop, IsLeftBolLoop and HasAutomorphicInverseProperty )
( HasAutomorphicInverseProperty, IsRightBruckLoop )
( IsRightBolLoop, IsRightBruckLoop )
( IsRightBruckLoop, IsRightBolLoop and HasAutomorphicInverseProperty )
( IsCommutative, IsSteinerLoop )
( HasInverseProperty, IsSteinerLoop )
\end{verbatim}
\end{scriptsize}

\chapter{Specific methods}\label{Ch:Specific}

\section{Isomorphisms and automorphisms}

\noindent All isomorphisms between two loops can be found with \loops. The function

\rcfunc{F}{IsomorphismLoops}{L, M}

\noindent returns a single isomorphism between loops $L$, $M$, if the loops are isomorphic, and
it fails otherwise. If an isomorphism exists it is returned as a permutation $\pi\in S_{|L|}$,
where $\pi(i)=j$ means that the $i$th element of $L$ is mapped onto the $j$th element of $M$.

The function

\rcfunc{F}{AutomorphismGroup}{L}

\noindent returns the automorphism group of the loop $L$. Since two
isomorphisms differ by an automorphism, all isomorphisms can be obtained by
the above two functions.

\subsection{Discriminator}

\noindent In order to speed up the search for isomorphisms and automorphisms,
we first calculate some loop invariants preserved under isomorphisms, and use these invariants
to partition the loop into blocks of elements preserved under isomorphism.
These invariants for a loop $L$ can be obtained via

\rcfunc{F}{Discriminator}{L}

\noindent Since the details are technical, we will not present them here. See
\cite{VoEJC} for more.

If two loops have different discriminators, they are not isomorphic. If they
have identical discriminator, they may or may not be isomorphic. The function

\rcfunc{F}{AreEqualDiscriminators}{D1, D2}

\noindent returns true if the discriminators $D1$, $D2$ are equal.

Given a loop $L$ and its discriminator $D$, the function

\rcfunc{F}{EfficientGenerators}{L, D}

\noindent returns a generating set of $L$ that is optimized with respect to
the discriminator $D$. Once again, the details are too technical to be
presented here. The returned set of generators is usually very small. Also
see \texttt{SmallGeneratingSet}.

\section{Moufang modifications}

\noindent Ale\v{s} Dr\'apal discovered two prominent families of extensions
of Moufang loops. These extensions can be used to obtain many, perhaps all,
nonassociative Moufang loops of order at most $64$. We call these two
constructions \idef{Moufang modifications}. The library of Moufang loops
included with \loops\ is based on Moufang modifications. We describe the two
modifications briefly here. See \cite{DV} for details.

\subsection{Cyclic modification}

\noindent Assume that $L$ is a Moufang loop with normal subloop $S$ such that
$L/S$ is a cyclic group of order $2m$. Let $h\in S\cap Z(L)$.
Let $\alpha$ be a generator of $L/S$ and write
$L = \bigcup_{i\in M} \alpha^i$, where $M=\{-m+1$, $\dots$, $m\}$. Let $\sigma:\mathbb Z\to M$
be defined by
\begin{displaymath}
    \sigma(i) = \left\{\begin{array}{ll}
        0,&i\in M,\\
        1,&i>m,\\
        -1,&i<-m+1.
    \end{array}\right.
\end{displaymath}
Introduce a new multiplication $*$ on $L$ defined by
\begin{displaymath}
    x*y = xyh^{\sigma(i+j)},
\end{displaymath}
where $x\in \alpha^i$, $y\in\alpha^j$, $i\in M$, $j\in M$. Then $(L,*)$ is a
Moufang loop, a \idef{cyclic modification} of $L$.

When $L$, $S$, $\alpha$, $h$ are as above and when $a$ is any element of $\alpha$, the
corresponding cyclic modification is obtained via

\rcfunc{F}{LoopByCyclicModification}{L, S, a, h}

\subsection{Dihedral modification}

\noindent Assume that $L$ is a Moufang loop with normal subloop $S$ such that
$L/S$ is a dihedral group of order $4m$, with $m\ge 1$. Let $M$ and $\sigma$ be defined
as in the cyclic case. Let $\beta$, $\gamma\in L/S$ be two involutions of $L/S$ such
that $\alpha=\beta\gamma$ generates a cyclic subgroup of $L/S$ of order $2m$.
Let $e\in\beta$ and $f\in\gamma$ be arbitrary. Then $L$ can be written as a disjoint
union $L=\bigcup_{i\in M}(\alpha^i\cup e\alpha^i)$, and also
$L=\bigcup_{i\in M}(\alpha^i\cup \alpha^if$. Let $G_0=\bigcup_{i\in M}\alpha^i$, and
$G_1=L\setminus G_0$. Let $h\in S\cap N(L)\cap Z(G_0)$.
Introduce a new multiplication $*$ n $L$ defined by
\begin{displaymath}
    x*y = xyh^{(-1)^r\sigma(i+j)},
\end{displaymath}
where $x\in\alpha^i\cup e\alpha^i$, $y\in\alpha^j\cup \alpha^jf$, $i\in M$,
$j\in M$, $y\in G_r$, $r\in\{0,1\}$. Then $(L,*)$ is a Moufang loop, a
\idef{dihedral modification} of $L$.

When $L$, $S$, $e$, $f$ and $h$ are as above, the corresponding dihedral
modification is obtained via

\rcfunc{F}{LoopByDihedralModification}{L, S, e, f, h}

\subsection{Loops $M(G,2)$}

\noindent In order to apply the cyclic and dihedral modification, it is beneficial
to have access to a class of nonassociative Moufang loops. The following construction
is due to Chein:

Let $G$ be a group. Let $\overline{G}=\{\overline{g};\;g\in G\}$ be a set of new elements.
Define multiplication $*$ on $L=G\cup \overline{G}$ by
\begin{displaymath}
    g*h = gh,\ g*\overline{h}=\overline{hg},\
    \overline{g}*h = \overline{gh^{-1}},\
    \overline{g}*\overline{h}=h^{-1}g,
\end{displaymath}
where $g$, $h\in G$. Then $L=M(G,2)$ is a Moufang loop that is nonassociative
if and only if $G$ is nonabelian.

The loop $M(G,2)$ can be obtained from a finite group $G$ with

\rcfunc{F}{LoopMG2}{G}

\noindent in \loops.

\section{Triality for Moufang loops}

\noindent Let $G$ be a group and $\sigma$, $\rho$ be automorphisms of $G$,
satisfying $\sigma^2 = \rho^3 = (\sigma \rho)^2 = 1$. We write the
automorphisms of a group as exponents and $[g,\sigma]$ for
$g^{-1}g^\sigma$. We say that the triple $(G,\rho,\sigma)$ is a \idef{group
with triality} if $[g, \sigma] [g,\sigma]^\rho [g,\sigma]^{\rho^2} =1$
holds for all $g \in G$. It is known that one can associate a group with
triality $(G,\rho,\sigma)$ in a canonical way with a Moufang loop $L$. See
\cite{NV} for more details.

For any Moufang loop $L$, we can calculate the triality
group as a permutation group acting on $3|L|$
points. If the multiplication group of $L$ is
polycyclic, then we can also represent the triality group
as a pc group. In both cases, the automorphisms
$\sigma$ and $\rho$ are in the same family as the
elements of $G$.

Given a Moufang loop $L$, the function

\rcfunc{F}{TrialityPermGroup}{L}

\noindent returns a record [$G$, $\rho$, $\sigma$], where $G$ is the group
with triality associated with $L$, and $\rho$, $\sigma$ are the corresponding
triality automorphisms.

The function

\rcfunc{F}{TrialityPcGroup}{L}

\noindent differs from \texttt{TrialityPermGroup} only in that $G$ is
returned as a pc group.

\chapter{Libraries of small loops}\label{Ch:Lib}

\noindent Libraries of small loops are an integral part of \loops.

\section{A typical library}

\noindent A library named ``my Library'' is stored in file
\texttt{data/mylibrary.tbl}, and the corresponding data structure is named
\texttt{my\_library\_data}.

The array \texttt{my\_library\_data} consists of three lists:
\texttt{my\_library\_data[ 1 ]} is a list of orders for which there is at
least one loop in the library, \texttt{my\_library\_data[ 2 ][ k ]} is the
number of loops of order \texttt{my\_library\_data[ 1 ][ k ]} in the library,
and \texttt{my\_library\_data[ 3 ][ s ]} contains data necessary to produce
the $s$th loop in the library. The format of \texttt{my\_library\_data[ 3 ]}
depends on the particular library and is not standardized in any way.

The user can retrieve the $m$th loop of order $n$ from
library named ``my Library'' according to the template

\rcfunc{global function template}{MyLibraryLoop}{n, m}

\noindent It is also possible to obtain the same loop with

\rcfunc{F}{LibraryLoop}{name, n, m}

\noindent where \texttt{name} is the name of the library.

For example, when the library is called ``left Bol'', the corresponding data
file is called \texttt{data/leftbol.tbl}, the corresponding data structure is
named \texttt{left\_bol\_data}, and the $m$th left Bol loop of order $n$ is
obtained via

\rcfunc{F}{LeftBolLoop}{n, m}

\noindent or via

\rcfunc{F}{LibraryLoop}{"left Bol", n, m}

\noindent We are now going to describe the individual libraries in detail. A
brief information about the library named \texttt{name} can also be obtained
in \loops\ with

\rcfunc{F}{DisplayLibraryInfo}{name}

\section{Left Bol loops}

\noindent The library named ``left Bol'' contains all $6$ nonassociative left
Bol loops of order $8$. Following the general pattern, the $m$th
nonassociative left Bol loop of order $n$ is obtained by

\rcfunc{F}{LeftBolLoop}{n, m}

We intend to enlarge this library significantly in future versions of \loops,
when the classification of small Bol loops is completed.


\section{Small Moufang loops}

\noindent The library named ``Moufang'' contains all nonassociative Moufang loops of order less than $64$,
and additional $4262$ nonassociative Moufang loops of order $64$. It is possible that there
are no other nonassociative Moufang loops of order $64$ than those contained in the library.

The $m$th nonassociative Moufang loop of order $n$ is obtained by

\rcfunc{F}{MoufangLoop}{n, m}

\noindent For $n\le 63$, our catalog numbers coincide with those of
Goodaire et al. \cite{Goodaire}.

The extent of the library is summarized below:

\begin{small}
\begin{displaymath}
    \begin{array}{r|rrrrrrrrrrrrrrrr}
        \textrm{order}                &12&16&20&24&28&32&36&40&42&44&48&52&54&56&60&64\\
        \textrm{loops in the libary}  &1 &5 &1 &5 &1 &71&4 &5 &1 &1 &51&1 &2 &4 &5 &4262
    \end{array}
\end{displaymath}
\end{small}

\noindent The \emph{octonion loop}\index{octonions} of order $16$ (i.e., the
multiplication loop of the $\pm$ basis elements in the $8$-dimensional
standard real octonion algebra) is \texttt{MoufangLoop( 16, 3 )}.

\subsection{Search for additional Moufang loops}

\noindent Since we would like to know if there are additional nonassociative Moufang
loops of order $64$, we have implemented the function

\rcfunc{F}{IsomorphismTypeOfMoufangLoop}{L}

\noindent If $L$ is a Moufang loop cataloged in \loops\ as the $m$th Moufang
loop of order $n$, the function returns $\texttt{[[n,m],p]}$, where $p$ is a
permutation of \texttt{[1..n]} that is an isomorphism from $L$ to the
cataloged copy of $L$. If $n=64$ and $L$ is Moufang loop not cataloged in
\loops, the user is prompted to contact the authors of \loops.

In order to speed up the function \texttt{IsomorphismTypeOfMoufangLoop}, we
have precalculated and stored in the data file \texttt{data\slash
moufang\_discriminators.tbl} the discriminators of all Moufang loops in the
library. The file is rather large (850 KB) and took about 20 minutes to
precalculate. You can delete the file if you won't use
\texttt{IsomorphismTypeOfMoufangLoop}.

\begin{gapex}\begin{verbatim}
gap> D := DirectProduct( MoufangLoop( 16, 2 ), CyclicGroup( 2 ) );
<loop of order 32>
gap> IsomorphismTypeOfMoufangLoop( D );
[ [ 32, 2 ], (2,3,12,20,11,29,23,13,30,31,28,27,22,15,32,18,10,19,16,24,14,
25,21,8,7,6,9,17,5) ]
gap> A := AutomorphismGroup( D ); Size( A );
<permutation group with 34 generators>
3072
\end{verbatim}\end{gapex}

\section{Steiner loops}

\noindent Here is how the libary ``Steiner'' is described within \loops:

\begin{gapex}\begin{verbatim}
gap> DisplayLibraryInfo( "Steiner" );
The library contains all nonassociative Steiner loops of order less or equal
to 16. It also contains the associative Steiner loops of order 4 and 8.
------
Extent of the library:
   1 loop of order 4
   1 loop of order 8
   1 loop of order 10
   2 loops of order 14
   80 loops of order 16
true
\end{verbatim}\end{gapex}

\noindent The $m$th Steiner loop of order $n$ is obtained by

\rcfunc{F}{SteinerLoop}{n, m}

\noindent

\noindent Our catalog numbers coincide with those of Colbourn and Rosa \cite{CR}.

\section{Paige loops}

\noindent \emph{Paige loops}\index{Paige loop} are nonassociative finite
simple Moufang loops. By \cite{Li}, there is precisely one Paige loop for
every finite field $GF(q)$.

The library named ``Paige'' contains the smallest nonassociative simple
Moufang loop

\rcfunc{F}{PaigeLoop}{2}

\section{Interesting loops}

\noindent The library named "interesting" contains some loops that are
illustrative for the theory of loops. At this point, the library contains a
nonassociative loop of order $5$, a nonassociative nilpotent loop of order
$6$, a nonMoufang left Bol loop of order $16$, and the loop of
sedenions\index{sedenions} of order $32$ (sedenions generalize octonions).

The loops are obtained with

\rcfunc{F}{InterestingLoop}{n, m}

\chapter{Plans for future versions}

\noindent We hope that the \loops\ package will become a standard
computational tool in quasigroup theory and loop theory, and we therefore
anticipate some interest among researchers in expanding the package. In this
chapter, we present several possible directions in which this future
expansion could lead. Since we will base our decision on your feedback,
please let us know what you would like to see implemented in \loops.

\section{Alternative representations of quasigroups and loops in \gap}

\noindent (The word "representation" does not have the usual mathematical
meaning in this section.) Direct products, semidirect products and many other
constructions of loops can be represented in a more space-efficient way than
by Cayley tables. Large Paige loops, generalizations of octonions and other
loops can be represented nicely. None of these representations is currently
implemented in \loops.

Presentations of some loops within their varieties are known and perhaps
should be found in \loops.

\section{Better support for quasigroups}

\noindent This package is concerned primarily with loops. Although some
functions are kept on a level general enough for quasigroups, many are not.
Only a few quasigroup-theoretical properties are testable in \loops\ at this
point. The operations \texttt{LeftDivision} and \texttt{RightDivision} are
awkward to work with.

\section{More homomorphisms and homotopisms}

The general concept of homomorphisms of quasigroup is obvious. Beside
\begin{displaymath}
\texttt{NaturalHomomorphismByNormalSubloop},\ \texttt{PrincipalLoopIsotope},
\end{displaymath}
other homomorphisms and homotopisms should be defined for loops and
quasigroups.

\section{Expanded libraries}

\noindent More Bol loops should be cataloged. Interesting loops should be
gathered in a more systematic way. Loops could be cataloged not only up to
isomorphism but also up to isotopism. We know how to create the library of
all conjugacy closed loops of order $p^2$. Any interest?

\section{Bits and pieces}

We would like to see the following features in a future version of \loops:
$M_k$ laws, cross inverse property (CIP), weak inverse property (WIP),
homotopisms.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% BIBLIOGRAPHY                                                                %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newpage                                                % PV
\addcontentsline{toc}{chapter}{Bibliography}            % PV

\bibliographystyle{plain}
\begin{thebibliography}{9}

\bibitem[Bruck(1971)]{Br} R.~Hubert~Bruck, A Survey of Binary Systems, third
printing, corrected, \emph{Ergebnisse der Mathematik und ihrer Grenzgebiete},
\emph{Neue Folge} \textbf{20}, Springer-Verlag, 1971.

\bibitem[Chein(1990)]{Ch} O.~Chein, H.~O.~Pflugfelder, J.~D.~H.~Smith (editors),
Quasigroups and Loops: Theory and Applications, \emph{Sigma Series in Pure
Mathematics} \textbf{8}, Heldermann Verlag Berlin, 1990.

\bibitem[Colbourn and Rosa (1999)]{CR} Charles J.~Colbourn and Alexander Rosa, Triple systems,
\emph{Oxford Mathematical Monographs}, The Clarendon Press, Oxford University
Press, New York, 1999.

\bibitem[Dr\'apal and Vojt\v{e}chovsk\'y(2004)]{DV} Ale\v{s} Dr\'apal and Petr
Vojt\v{e}chovsk\'y, \emph{Moufang loops that share associator and three
quarters of their multiplication tables}, to appear in Rocky Mountain Journal
of Mathematics.

\bibitem[Fenyves(1969)]{Fe} Ferenc Fenyves, \emph{Extra loops II, On loops with
identities of Bol-Moufang type}, Publ. Math. Debrecen \textbf{16}(1969),
187--192.

\bibitem[Goodaire, May and Raman(1999)]{Goodaire} Edgar G. Goodaire, Sean
May and Maitreyi Raman, {The Moufang loops of order less than $64$},
Commack, NY: Nova Science Publishers, 1999.

\bibitem[Liebeck(1987)]{Li} M.~Liebeck, \emph{The classification of finite
simple Moufang loops}, Math. Proc. Cambridge Philos. Soc. \textbf{102}
(1987), 33--47.

\bibitem[Nagy and Vojt\v{e}chovsk\'y(2003)]{NV} G\'abor~P.~Nagy and Petr
Vojt\v{e}chovsk\'y, \emph{Octonions, simple Moufang loops and triality},
Quasigroups and Related Systems \textbf{10} (2003), 65--94.

\bibitem[Pflugfelder(1990)]{Pf} Hala~O.~Pflugfelder, Quasigroups and Loops:
Introduction, \emph{Sigma Series in Pure Mathematics} \textbf{7}, Heldermann
Verlag Berlin, 1990.

\bibitem[Phillips and Vojt\v{e}chovsk\'y(2004)]{PV} J.~D.~Phillips and Petr
Vojt\v{e}chovsk\'y, \emph{Varieties of loops of Bol-Moufang type},
submitted.

\bibitem[Vojt\v{e}chovsk\'y(2004)]{VoEJC} Petr Vojt\v{e}chovsk\'y,
\emph{Toward the classification of Moufang loops of order $64$}, submitted.

\end{thebibliography}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% INDEX                                                                       %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newpage                                        % NG
\addcontentsline{toc}{chapter}{Index}           % NG
\printindex                                     % PV


\end{document}
