\Chapter{How the package works}

The package consists of three complementary components:
\beginlist%unordered
\item{$\circ$} the core algorithms for quasigroup theoretical notions
    (see Chapters "Basic methods and attributes",
    "Some methods based on permutation groups" and
    "Testing properties of quasigroups and loops"),
\item{$\circ$} some specific algorithms, mostly for Moufang loops
    (see Chapter "Specific methods"),
\item{$\circ$} the library of small loops (see Chapter
    "Libraries of small loops").
\endlist
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 {\LOOPS} during computation.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Representing quasigroups}

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, <the package is intended primarily for quasigroups and loops of
small order>, say up to $1000$.

The categories `IsQuasigroupElement', `IsLoopElement', `IsQuasigroup', and
`IsLoop' are declared in {\LOOPS} as follows:

\begintt
DeclareCategory( "IsQuasigroupElement", IsMultiplicativeElement );
DeclareRepresentation( "IsQuasigroupElmRep",
    IsPositionalObjectRep and IsMultiplicativeElement, [1] );
DeclareCategory( "IsLoopElement",
    IsQuasigroupElement and IsMultiplicativeElementWithInverse );
DeclareRepresentation( "IsLoopElmRep",
    IsPositionalObjectRep and IsMultiplicativeElementWithInverse, [1] );
## latin (auxiliary category for GAP to tell apart IsMagma and IsQuasigroup)
DeclareCategory( "IsLatin", IsObject );
DeclareCategory( "IsQuasigroup", IsMagma and IsLatin );
DeclareCategory( "IsLoop", IsQuasigroup and
    IsMultiplicativeElementWithInverseCollection);
\endtt

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Conversions between magmas, quasigroups, loops and groups}

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 <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

\>AsLoop( <Q> ) O

As we have seen above, the category `IsQuasigroup' is declared in {\LOOPS} so
that it is contained in the category `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

\>AsQuasigroup( <G> ) O
\>AsLoop( <G> ) O

to the group $G$. These conversions fail when $G$ is infinite and will exhaust
all available memory when $G$ is huge.

For much more information on conversions, see Section "Conversions".


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Calculating with quasigroups}

Although the quasigroups are ultimately represented by multiplication tables,
the algorithms are efficient because nearly all calculations are delegated to
groups. The connection between quasigroups and groups is facilitated via the
above-mentioned translations, and we illustrate it with a few examples:

\medskip

*Example 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.

*Example 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$.

*Example 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 is a primitive
permutation group.

\medskip

The main idea of the package is therefore to:
\beginlist%unordered
\item{$\circ$} calculate the translations and the associated permutation
    groups when they are needed,
\item{$\circ$} store them as attributes,
\item{$\circ$} use them in algorithms as often as possible.
\endlist

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Naming, viewing and printing quasigroups and their elements}

{\GAP} displays information about objects in two modes:
\beginlist%unordered
\item{$\circ$}
    `View' (default, short),
\item{$\circ$}
    `Print' (longer).
\endlist
Moreover, when the name of an object is set, it is always shown, no matter
which display mode is used.

Only loops contained in the libraries of {\LOOPS} are named. For instance, the
loop obtained via `MoufangLoop( 32, 4 )', the $4$th Moufang loop of order $32$,
is named `Moufang loop 32/4'.

When $Q$ is a quasigroup of order $n$, it is displayed as `\<quasigroup of
order n>'. Similarly, a loop of order $n$ appears as `\<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:
\begintt
    <associative loop ...>
    <extra loop ...>
    <Moufang loop ...>
    <C loop ...>
    <left Bol loop ...>
    <right Bol loop ...>
    <LC loop ...>
    <RC loop ...>
    <alternative loop ...>
    <left alternative loop ...>
    <right alternative loop ...>
    <flexible loop ...>
\endtt
The corresponding mathematical definitions and an example can be found in
Section "Loops of Bol-Moufang type and related properties".

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.

By default, elements of a quasigroup appear as `q<n>' and elements of a loop
appear as `l<n>' in both display modes. The neutral element of a loop is always
denoted by `l1'. However, one can change the names of elements of a quasigroup
$Q$ or loop $L$ to <name> with

\>SetQuasigroupElmName( <Q>, <name> ) O
\>SetLoopElmName( <L>, <name> ) O

For quasigroups and loops in the `Print' mode, we display the multiplication
table (if it is known), or we display the elements.

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

\beginexample
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 ]
\endexample
