Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/loops/doc/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 29.7.2024 mit Größe 142 kB image not shown  

 loops.xml   Interaktion und
PortierbarkeitXML

 
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE Book SYSTEM "gapdoc.dtd"
[<!ENTITY LOOPS "LOOPS">] >

<Book Name="Loops">

<!-- Typesetting rules for this document that produce acceptable outcome in
both html and pdf:

* Use <Br/><P/> at the beginning of paragraphs that are supposed to have an empty line just before them for greater emphasis, eg., before Remark, Example, and to break up the text. (This has no effect on html.)

* Inside <ManSection>, list all <Func .../> etc at the beginning, followed by optional <Returns></Returns>, and only then add remarks and other explanatory text within <Description>.

* If there is additional text after ManSection, insert <Br/> at the end of the last tag of the <ManSection>, e.g., <Br/></Description></ManSection>. (This has no effect in html.)

-->


<#Include SYSTEM "title.xml">

<TableOfContents/>

<Body>

<!-- CHAPTER Introduction -->

<Chapter Label="Chap:Introduction"> <Heading>Introduction</Heading>

&LOOPS; is a package for <Package>GAP4</Package> whose purpose is to:
        <List>
                <Item>provide researchers in nonassociative algebra with a powerful computational tool concerning finite loops and quasigroups,</Item>
                <Item>extend &GAP; toward the realm of nonassociative structures.</Item>
        </List>
&LOOPS; has been accepted as an official package of &GAP; in May 2015.

<!-- Section: Installation -->

<Section Label="Sec:Installation"> <Heading>Installation</Heading>

Have <Package>GAP 4.8</Package> or newer installed on your computer.

<P/>If you do not see the subfolder <File>pkg/loops</File> in the main directory of &GAP; then download the &LOOPS; package from the distribution website <URL>https://gap-packages.github.io/loops/</URL> and unpack the downloaded file into the <File>pkg</File> subfolder.

<P/>The package &LOOPS; can then be loaded to &GAP; anytime by calling <Code>LoadPackage("loops");</Code>.

<P/>If you wish to load &LOOPS; automatically while starting &GAP;, start &GAP;, execute the following commands,
<Verb>
gap> pref := UserPreference( "PackagesToLoad " );;
gap> Add( pref, "loops" );;
gap> SetUserPreference( "PackagesToLoad", pref );;
gap> WriteGapIniFile();;
</Verb>
quit &GAP; and restart it.

</Section>

<!-- Section: Documentation -->

<Section Label="Sec:Documentation"> <Heading>Documentation</Heading>

The documentation has been prepared with the &GAPDoc; package and is therefore available in several formats: &LaTeX;, pdf, ps, html, and as an inline help in &GAP;. All these formats have been obtained directly from the master XML documentation file. Consequently, the different formats of the documentation differ only in their appearance, not in content.

<P/>The preferred format of the documentation is html with MathJax turned on.

<P/>All formats of the documentation can be found in the <File>doc</File> folder of &LOOPS;. You can also download the documentation from the &LOOPS; distribution website.

<P/>The inline &GAP; help is available upon installing &LOOPS; and can be accessed in the usual way, i.e., upon typing <Code>?command</Code>, &GAP; displays the section of the &LOOPS; manual containing information about <Code>command</Code>.

</Section>

<!-- Section: Test Files -->

<Section Label="Sec:TestFiles"> <Heading>Test Files</Heading>

Test files conforming to &GAP; standards are provided for &LOOPS; and can be found in the folder <File>tst</File>. The command <Code>ReadPackage("loops","tst/testall.g")</Code> runs all tests for &LOOPS;.

</Section>

<!-- Section: Memory Management -->

<Section Label="Sec:MemoryManagement"> <Heading>Memory Management</Heading>

Some libraries of loops are loaded only upon explicit demand and can occupy a lot of memory. For instance, the library or RCC loops occupies close to 100 MB of memory when fully loaded. The command <Code>LOOPS_FreeMemory();</Code> will attempt to free memory by unbinding on-demand library data loaded by &LOOPS;.

</Section>

<!-- Section: Feedback -->

<Section Label="Sec:Feedback"> <Heading>Feedback</Heading>

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

</Section>

</Chapter>

<!-- CHAPTER Mathematical Background -->

<Chapter Label="Chap:MathematicalBackground"> <Heading>Mathematical Background</Heading>

We assume that you are familiar with the theory of quasigroups and loops, for instance with the textbook of Bruck <Cite Key="Br"/> or Pflugfelder <Cite Key="Pf"/>. Nevertheless, we did include definitions and results in this manual in order to unify terminology and improve legibility of the text. Some general concepts of quasigroups and loops can be found in this chapter. More special concepts are defined throughout the text as needed.

<!-- Section: Quasigroups and loops -->

<Section Label="Sec:QuasigroupsAndLoops"> <Heading>Quasigroups and Loops</Heading>

A set with one binary operation (denoted <M>\cdot</M> here) is called <Index>groupoid</Index><Emph>groupoid</Emph> or <Index>magma</Index><Emph>magma</Emph>, the latter name being used in &GAP;.

<P/>An element <M>1</M> of a groupoid <M>G</M> is a <Index>neutral element</Index><Emph>neutral element</Emph> or an <Index Subkey="element">identity</Index><Emph>identity element</Emph> if <M>1\cdot x = x\cdot 1 = x</M> for every <M>x</M> in <M>G</M>.

<P/>Let <M>G</M> be a groupoid with neutral element <M>1</M>. Then an element <M>x^{-1}</M> is called a <Index Subkey="two-sided">inverse</Index><Emph>two-sided inverse</Emph> of <M>x</M> in <M>G</M> if <M> x\cdot x^{-1} = x^{-1}\cdot x = 1</M>.

<P/>Recall that <Index>group</Index>groups are associative groupoids with an identity element and two-sided inverses.  Groups can be reached in another way from groupoids, namely via quasigroups and loops.

<P/>A <Index>quasigroup</Index><Emph>quasigroup</Emph> <M>Q</M> is a groupoid such that the equation <M>x\cdot y=z</M> has a unique solution in <M>Q</M> whenever two of the three elements <M>x</M>, <M>y</M>, <M>z</M> of <M>Q</M> are specified. Note that multiplication tables of finite quasigroups are precisely <Index>latin square</Index><Emph>latin squares</Emph>, i.e., square arrays with symbols arranged so that each symbol occurs in each row and in each column exactly once. A <Index>loop</Index><Emph>loop</Emph> <M>L</M> is a quasigroup with a neutral element.

<P/>Groups are clearly loops. Conversely, it is not hard to show that associative quasigroups are groups.

</Section>

<!-- Section: Translations -->

<Section Label="Sec:Translations"> <Heading>Translations</Heading>

Given an element <M>x</M> of a quasigroup <M>Q</M>, we can associative two permutations of <M>Q</M> with it: the <Index Subkey="left">translation</Index><Emph>left translation</Emph> <M>L_x:Q\to Q</M> defined by <M>y\mapsto x\cdot y</M>, and the <Index Subkey="right">translation</Index><Emph>right translation</Emph> <M>R_x:Q\to Q</M> defined by <M>y\mapsto y\cdot x</M>.

<P/>The binary operation <M>x\backslash y = L_x^{-1}(y)</M> is called the <Index Subkey="left">division</Index><Emph>left division</Emph>, and <M>x/y = R_y^{-1}(x)</M> is called the <Index  Subkey="right">division</Index><Emph>right division</Emph>.

<P/>Although it is possible to compose two left (right) translations of a quasigroup, the resulting permutation is not necessarily a left (right) translation. The set <M>\{L_x|x\in Q\}</M> is called the <Index Subkey="left">section</Index><Emph>left section</Emph> of <M>Q</M>, and <M>\{R_x|x\in Q\}</M> is the <Index Subkey="right">section</Index><Emph>right section</Emph> of <M>Q</M>.

<P/>Let <M>S_Q</M> be the symmetric group on <M>Q</M>. Then the subgroup <M>{\rm Mlt}_{\lambda}(Q)=\langle L_x|x\in Q\rangle</M> of <M>S_Q</M> generated by all left translations is the <Index Subkey="left">multiplication group</Index><Emph>left multiplication group</Emph> of <M>Q</M>. Similarly, <M>{\rm Mlt}_{\rho}(Q)= \langle R_x|x\in Q\rangle</M> is the <Index Subkey="right">multiplication group</Index><Emph>right multiplication group</Emph> of <M>Q</M>. The smallest group containing both <M>{\rm Mlt}_{\lambda}(Q)</M> and <M>{\rm Mlt}_{\rho}(Q)</M> is called the <Index>multiplication group</Index><Emph>multiplication group</Emph> of <M>Q</M> and is denoted by <M>{\rm Mlt}(Q)</M>.

<P/>For a loop <M>Q</M>, the <Index Subkey="left">inner mapping group</Index><Emph>left inner mapping group</Emph> <M>{\rm Inn}_{\lambda}(Q)</M> is the stabilizer of <M>1</M> in <M>{\rm Mlt}_{\lambda}(Q)</M>. The <Index Subkey="right">inner mapping group</Index><Emph>right inner mapping group</Emph> <M>{\rm Inn}_{\rho}(Q)</M> is defined dually. The <Index>inner mapping group</Index><Emph>inner mapping group</Emph> <M>{\rm Inn}(Q)</M> is the stabilizer of <M>1</M> in <M>Q</M>.

</Section>

<!-- Section:  Subquasigroups and subloops -->

<Section Label="Sec:SubquasigroupsAndSubloops"> <Heading>Subquasigroups and Subloops</Heading>

A nonempty subset <M>S</M> of a quasigroup <M>Q</M> is a <Index>subquasigroup</Index><Emph>subquasigroup</Emph> if it is closed under multiplication and the left and right divisions. In the finite case, it suffices for <M>S</M> to be closed under multiplication. <Index>subloop</Index><Emph>Subloops</Emph> are defined analogously when <M>Q</M> is a loop.

<P/>The <Index Subkey="left">nucleus</Index><Emph>left nucleus</Emph> <M>{\rm Nuc}_{\lambda}(Q)</M> of <M>Q</M> consists of all elements <M>x</M> of <M>Q</M> such that <M>x(yz) = (xy)z</M> for every <M>y</M>, <M>z</M> in <M>Q</M>. The <Index Subkey="middle">nucleus</Index><Emph>middle nucleus</Emph> <M>{\rm Nuc}_{\mu}(Q)</M> and the <Index Subkey="right">nucleus</Index><Emph>right nucleus</Emph> <M>{\rm Nuc}_{\rho}(Q)</M> are defined analogously. The <Index>nucleus</Index><Emph>nucleus</Emph> <M>{\rm Nuc}(Q)</M> is the intersection of the left, middle and right nuclei.

<P/>The <Index>commutant</Index><Emph>commutant</Emph> <M>C(Q)</M> of <M>Q</M> consists of all elements <M>x</M> of <M>Q</M> that commute with all elements of <M>Q</M>. The    <Index>center</Index><Emph>center</Emph> <M>Z(Q)</M> of <M>Q</M> is the intersection of <M>{\rm Nuc}(Q)</M> with <M>C(Q)</M>.

<P/>A subloop <M>S</M> of <M>Q</M> is <Index Subkey="normal">subloop</Index><Emph>normal</Emph> in <M>Q</M> if <M>f(S)=S</M> for every inner mapping <M>f</M> of <M>Q</M>.

</Section>

<!-- Section:  Nilpotence and solvability -->

<Section Label="Sec:NilpotenceAndSolvability"> <Heading>Nilpotence and Solvability</Heading>

For a loop <M>Q</M> define <M>Z_0(Q) = 1</M> and let <M>Z_{i+1}(Q)</M> be the preimage of the center of <M>Q/Z_i(Q)</M> in <M>Q</M>. A loop <M>Q</M> is <Index>nilpotence class</Index><Index>nilpotent loop</Index><Index Subkey="nilpotent">loop</Index><Emph>nilpotent of class</Emph> <M>n</M> if <M>n</M> is the least nonnegative integer such that <M>Z_n(Q)=Q</M>. In such case <M>Z_0(Q)\le Z_1(Q)\le \dots \le Z_n(Q)</M> is the <Emph>upper central series</Emph><Index Subkey="upper">central series</Index>.

<P/>The <Index>derived subloop</Index><Emph>derived subloop</Emph> <M>Q' of Q is the least normal subloop of Q such that Q/Q'</M> is a commutative group. Define <M>Q^{(0)}=Q</M> and let <M>Q^{(i+1)}</M> be the derived subloop of <M>Q^{(i)}</M>. Then <M>Q</M> is <Index>solvability class</Index><Index>solvable loop</Index><Index Subkey="solvable">loop</Index><Emph>solvable of class</Emph> <M>n</M> if <M>n</M> is the least nonnegative integer such that <M>Q^{(n)} = 1</M>. In such a case <M>Q^{(0)}\ge Q^{(1)}\ge \cdots \ge Q^{(n)}</M> is the <Emph>derived series</Emph><Index>derived series</Index> of <M>Q</M>.

</Section>

<!-- Section:  Commutators and Associators -->

<Section Label="Sec:AssociatorsAndCommutators"> <Heading>Associators and Commutators</Heading>

Let <M>Q</M> be a quasigroup and let <M>x</M>, <M>y</M>, <M>z</M> be elements of <M>Q</M>. Then the <Index>commutator</Index><Emph>commutator</Emph> of <M>x</M>, <M>y</M> is the unique element <M>[x,y]</M> of <M>Q</M> such that <M>xy = [x,y](yx)</M>, and the <Index>associator</Index><Emph>associator</Emph> of <M>x</M>, <M>y</M>, <M>z</M> is the unique element <M>[x,y,z]</M> of <M>Q</M> such that <M>(xy)z = [x,y,z](x(yz))</M>.

<P/>The <Index>associator subloop</Index><Emph>associator subloop</Emph> <M>A(Q)</M> of <M>Q</M> is the least normal subloop of <M>Q</M> such that <M>Q/A(Q)</M> is a group.

<P/>It is not hard to see that <M>A(Q)</M> is the least normal subloop of <M>Q</M> containing all commutators, and <M>Q' is the least normal subloop of Q containing all commutators and associators.

</Section>

<!-- Section:  Homomorphisms and Homotopisms -->

<Section Label="Sec:HomomorphismsAndHomotopisms"> <Heading>Homomorphism and Homotopisms</Heading>

Let <M>K</M>, <M>H</M> be two quasigroups. Then a map <M>f:K\to H</M> is a <Index>homomorphism</Index><Emph>homomorphism</Emph> if <M>f(x)\cdot f(y)=f(x\cdot y)</M> for every <M>x</M>, <M>y\in K</M>. If <M>f</M> is also a bijection, we speak of an <Index>isomorphism</Index><Emph>isomorphism</Emph>, and the two quasigroups are called isomorphic.

<P/>An ordered triple <M>(\alpha,\beta,\gamma)</M> of maps <M>\alpha</M>, <M>\beta</M>,
<M>\gamma:K\to H</M> is a <Index>homotopism</Index><Emph>homotopism</Emph> if <M>\alpha(x)\cdot\beta(y) = \gamma(x\cdot y)</M> for every <M>x</M>, <M>y</M> in <M>K</M>. If the three maps are bijections, then <M>(\alpha,\beta,\gamma)</M> is an <Index>isotopism</Index><Emph>isotopism</Emph>, and the two quasigroups are isotopic.

<P/>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.

<P/>Let <M>(K,\cdot)</M>, <M>(K,\circ)</M> be two quasigroups defined on the same set <M>K</M>. Then an isotopism <M>(\alpha,\beta,{\rm id}_K)</M> is called a <Index Subkey="principal">isotopism</Index><Emph>principal isotopism</Emph>. An important class of principal isotopisms is obtained as follows:

Let <M>(K,\cdot)</M> be a quasigroup, and let <M>f</M>, <M>g</M> be elements of <M>K</M>. Define a new operation <M>\circ</M> on <M>K</M> by <M>x\circ y = R_g^{-1}(x)\cdot L_f^{-1}(y)</M>, where <M>R_g</M>, <M>L_f</M> are translations. Then <M>(K,\circ)</M> is a quasigroup isotopic to <M>(K,\cdot)</M>, in fact a loop with neutraelement <M>f\cdot g</M>. We call <M>(K,\circ)</M> a <Index Subkey="principal">loop isotope</Index><Emph>principal loop isotope</Emph> of <M>(K,\cdot)</M>.

</Section>

</Chapter>

<!-- CHAPTER: How the Package Works -->

<Chapter Label="Chap:HowThePackageWorks"> <Heading>How the Package Works</Heading>

The package consists of three complementary components:
<List>
        <Item>the core algorithms for quasigroup theoretical notions  (see Chapters <Ref Chap="Chap:CreatingQuasigroupsAndLoops"/>, <Ref Chap="Chap:BasicMethodsAndAttributes"/>, <Ref Chap="Chap:MethodsBasedOnPermutationGroups"/> and <Ref Chap="Chap:TestingPropertiesOfQuasigroupsAndLoops"/>),</Item>
        <Item>algorithms for specific varieties of loops, mostly for Moufang loops (see Chapter <Ref Chap="Chap:SpecificMethods"/>),</Item>
        <Item>the library of small loops (see Chapter <Ref Chap="Chap:LibrariesOfLoops"/>).</Item>
</List>
Although we do not explain the algorithms in detail here, we describe the general philosophy so that users can anticipate the capabilities and behavior of &LOOPS;.

<!-- Section:  Representing quasigroups -->

<Section Label="Sec:RepresentingQuasigroups"> <Heading>Representing Quasigroups</Heading>

Since permutation representation in the usual sense is impossible for nonassociative structures, and since the theory of nonassociative presentations is not well understood, we resorted 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. See Section <Ref Sect="Sec:AboutCayleyTables"/> for more details.)

<P/>Consequently, the package is intended primarily for quasigroups and loops of small order, say up to 1000.

<P/>The &GAP; categories <Index>IsQuasigroupElement</Index><Code>IsQuasigroupElement</Code>, <Index>IsLoopElement</Index><Code>IsLoopElement</Code>, <Index>IsQuasigroup</Index><Code>IsQuasigroup</Code> and <Index>IsLoop</Index><Code>IsLoop</Code> are declared in &LOOPS; as follows:

<Verb>
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( "IsLatinMagma", IsObject );
DeclareCategory( "IsQuasigroup", IsMagma and IsLatinMagma );
DeclareCategory( "IsLoop", IsQuasigroup and
    IsMultiplicativeElementWithInverseCollection);
</Verb>

</Section>

<!-- Section:  Conversions between magmas, quasigroups, loops and groups -->

<Section Label="Sec:ConversionsEtc"> <Heading>Conversions between magmas, quasigroups, loops and groups</Heading>

Whether an object is considered a magma, quasigroup, loop or group is a matter of declaration in &LOOPS;. Loops are automatically quasigroups, and both groups and quasigroups are automatically magmas. All standard &GAP; commands for magmas are therefore available for quasigroups and loops.

<P/>In &GAP;, functions of the type <Code>AsSomething(<Arg>X</Arg>)</Code> convert the domain <Arg>X</Arg> into <Code>Something</Code>, if possible, without changing the underlying domain <Arg>X</Arg>. For example, if <Arg>X</Arg> is declared as magma but is associative and has neutral element and inverses, <Code>AsGroup(<Arg>X</Arg>)</Code> returns the corresponding group with the underlying domain <Arg>X</Arg>.

<P/>We have opted for a more general kind of conversions in &LOOPS; (starting with version 2.1.0), using functions of the type <Code>IntoSomething(<Arg>X</Arg>)</Code>. The two main features that distinguish <Code>IntoSomething</Code> from <Code>AsSomething</Code> are:
<List>
        <Item>The function <Code>IntoSomething(<Arg>X</Arg>)</Code> does not necessarily return the same    domain as <Arg>X</Arg>. The reason is that <Arg>X</Arg> can be a group, for instance, defined on one of many possible domains, while <Code>IntoLoop(<Arg>X</Arg>)</Code> must result in a loop, and hence be defined on a subset of some interval <M>1</M>, <M>\dots</M>, <M>n</M> (see Section <Ref Sect="Sec:ParentOfAQuasigroup"/>).</Item>
        <Item>In some special situations, the function <Code>IntoSomething(<Arg>X</Arg>)</Code> allows to    convert <Arg>X</Arg> into <Code>Something</Code> even though <Arg>X</Arg> does not have all the properties  of <Code>Something</Code>. For instance, every quasigroup is isotopic to a loop, so it makes sense to allow the conversion <Code>IntoLoop(<Arg>Q</Arg>)</Code> even if the quasigroup <Arg>Q</Arg> does not posses a neutral element.</Item>
</List>
Details of all conversions in &LOOPS; can be found in Section <Ref Sect="Sec:Conversions"/>.

</Section>

<!-- Section:  Calculating with Quasigroups -->

<Section Label="Sec:CalculationWithQuasigroups"> <Heading>Calculating with Quasigroups</Heading>

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 translations (see Section <Ref Sect="Sec:Translations"/>), and we illustrate it with a few examples:

<Br/><P/><B>Example:</B> This example shows how properties of quasigroups can be translated into properties of translations in a straightforward way. Let <M>Q</M> be a quasigroup. We ask if <M>Q</M> is associative. We can either test if <M>(xy)z=x(yz)</M> for every <M>x</M>, <M>y</M>, <M>z</M> in <M>Q</M>, or we can ask if <M>L_{xy}=L_xL_y</M> for every <M>x</M>, <M>y</M> in <M>Q</M>. Note that since <M>L_{xy}</M>, <M>L_x</M> and <M>L_y</M> are elements of a permutation group, we do not have to refer directly to the multiplication table once the left translations of <M>Q</M> are known.

<Br/><P/><B>Example:</B> This example shows how properties of loops can be translated into
properties of translations in a way that requires some theory. A <Index Subkey="left">Bol loop</Index><Index Subkey="left Bol">loop</Index><Emph>left Bol loop</Emph> is a loop satisfying <M>x(y(xz)) = (x(yx))z</M>. We claim (without proof) that a loop <M>Q</M> is left Bol if and only if <M>L_xL_yL_x</M> is a left translation for every <M>x</M>, <M>y</M> in <M>Q</M>.

<Br/><P/><B>Example:</B> This example shows that many properties of loops become purely
group-theoretical once they are expressed in terms of translations. A loop is <Index>simple loop</Index><Index Subkey="simple">loop</Index><Emph>simple</Emph> if it has no nontrivial congruences. It is possible to show that a loop is simple if and only if its multiplication group is a primitive permutation group.

<Br/><P/>The main idea of the package is therefore to:
<List>
        <Item>calculate the translations and the associated permutation groups when they are needed,</Item>
        <Item>store them as attributes,</Item>
        <Item>use them in algorithms as often as possible.</Item>
</List>

</Section>

<!-- Section:  Naming, Viewing and Printing Quasigroups and their Elements -->

<Section Label="Sec:NamingEtc"> <Heading>Naming, Viewing and Printing Quasigroups and their Elements</Heading>

&GAP; displays information about objects in two modes: the <Code>View</Code> mode (default, short), and the <Code>Print</Code> mode (longer). Moreover, when the name of an object is set, the name is always shown, no matter which display mode is used.

<P/>Only loops contained in the libraries of &LOOPS; are named. For instance, the loop obtained via <Code>MoufangLoop(32,4)</Code>, the 4th Moufang loop of order 32, is named "Moufang loop 32/4'' and is shown as <Moufang loop 32/4>.

<P/>A generic quasigroup of order <M>n</M> is displayed as <Code><quasigroup of order n></Code>. Similarly, a loop of order <M>n</M> appears as <Code><loop of order n></Code>.

<P/>The displayed information of a generic loop is enhanced if more information about the loop becomes available. For instance, when it is established that a loop of order 12 has the left alternative property, the loop will be shown as <Code><left alternative loop of order 12></Code> until a stronger property is obtained. Which property is displayed is governed by the filters built into &LOOPS; (see Appendix <Ref Appendix="Apx:Filters"/>).

<ManSection><Heading>SetQuasigroupElmName and SetLoopElmName</Heading>

<Func Name="SetQuasigroupElmName" Arg="Q, name"/>
<Func Name="SetLoopElmName" Arg="Q, name"/>

<Description>The above functions change the names of elements of a quasigroup (resp. loop) <Arg>Q</Arg> to <Arg>name</Arg>.</Description>

<Description>By default, elements of a quasigroup appear as <Code>qi</Code> and elements of a loop appear as <Code>li</Code> in both display modes, where <Code>i</Code> is a positive integer. The neutral element of a loop is always indexed by 1.<Br/></Description>

</ManSection>

<P/>For quasigroups and loops in the <Code>Print</Code> mode, we display the multiplication table (if it is known), otherwise we display the elements.

<Br/><P/>In the following example, <Code>L</Code> is a loop with two elements.

<Example><![CDATA[
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 ]
]]></Example>

</Section>

</Chapter>

<!-- CHAPTER: Creating Quasigroups and Loops -->

<Chapter Label="Chap:CreatingQuasigroupsAndLoops"> <Heading>Creating Quasigroups and Loops</Heading>

In this chapter we describe several ways in which quasigroups and loops can be created in &LOOPS;.

<!-- Section:  About Cayley Tables -->

<Section Label="Sec:AboutCayleyTables"> <Heading>About Cayley Tables</Heading>

Let <M>X=\{x_1,\dots,x_n\}</M> be a set and <M>\cdot</M> a binary operation on <M>X</M>. Then an <M>n</M> by <M>n</M> array with rows and columns bordered by <M>x_1</M>, <M>\dots</M>, <M>x_n</M>, in this order, is a <Index>Cayley table</Index><Emph>Cayley table</Emph>, or a <Index>multiplication table</Index><Emph>multiplication table</Emph> of <M>\cdot</M>, if the entry in the row <M>x_i</M> and column <M>x_j</M> is <M>x_i\cdot x_j</M>.

<P/>A Cayley table is a <Index>quasigroup table</Index><Emph>quasigroup table</Emph> if it is a <Index>latin square</Index>latin square, i.e., if every entry <M>x_i</M> appears in every column and every row exactly once.

<P/>An unfortunate feature of multiplication tables in practice is that they are often not bordered, that is, it is up to the reader to figure out what is meant. Throughout this manual and in &LOOPS;, we therefore make the following assumption: <Emph>All distinct entries in a quasigroup table must be positive integers, say <M>x_1 < x_2 < \cdots < x_n</M>, and if no border is specified, we assume that the table is bordered by <M>x_1</M>, <M>\dots</M>, <M>x_n</M>, in this order.</Emph> Note that we do not assume that the distinct entries <M>x_1</M>, <M>\dots</M>, <M>x_n</M> form the interval <M>1</M>, <M>\dots</M>, <M>n</M>. The significance of this observation will become clear in Chapter <Ref Chap="Chap:MethodsBasedOnPermutationGroups"/>.

<P/>Finally, we say that a quasigroup table is a <Index>loop table</Index><Emph>loop table</Emph> if the first row and the first column are the same, and if the entries in the first row are ordered in an ascending fashion.

</Section>

<!-- Section:  Testing Cayley Tables -->

<Section Label="Sec:TestingCayleyTables"> <Heading>Testing Cayley Tables</Heading>

<ManSection>
<Heading>IsQuasigroupTable and IsQuasigroupCayleyTable</Heading>
<Oper Name="IsQuasigroupTable" Arg="T"/>
<Oper Name="IsQuasigroupCayleyTable" Arg="T"/>
<Returns><Code>true</Code> if <Arg>T</Arg> is a quasigroup table as defined above, else <Code>false</Code>.</Returns>
</ManSection>

<ManSection>
<Heading>IsLoopTable and IsLoopCayleyTable</Heading>
<Oper Name="IsLoopTable" Arg="T"/>
<Oper Name="IsLoopCayleyTable" Arg="T"/>
<Returns><Code>true</Code> if <Arg>T</Arg> is a loop table as defined above, else <Code>false</Code>.<Br/></Returns>
</ManSection>

<P/><B>Remark:</B>The package <Package>GUAVA</Package> also contains operations dealing with latin squares. In particular, <Code>IsLatinSquare</Code> is declared in <Package>GUAVA</Package>.

</Section>

<!-- Section:  Canonical and Normalized Cayley Tables -->

<Section Label="Sec:CanonicalAndNormalizedCayleyTables"> <Heading>Canonical and Normalized Cayley Tables</Heading>

<ManSection>
<Oper Name="CanonicalCayleyTable" Arg="T"/>
<Returns>Canonical Cayley table constructed from Cayley table <Arg>T</Arg> by replacing entries <M>x_i</M> with <M>i</M>.</Returns>
<Description>A Cayley table is said to be <Index Subkey="canonical">Cayley table</Index><Emph>canonical</Emph> if it is based on elements <M>1</M>, <M>\dots</M>, <M>n</M>. Although we do not assume that every quasigroup table is canonical, it is often desirable to present quasigroup tables in canonical way.</Description>
</ManSection>

<ManSection>
<Oper Name="CanonicalCopy" Arg="Q"/>
<Returns>A canonical copy of the quasigroup or loop <Arg>Q</Arg>.</Returns>
<Description>This is a shorthand for <Code>QuasigroupByCayleyTable(CanonicalCayleyTable(<Arg>Q</Arg>)</Code> when <Arg>Q</Arg> is a declared quasigroup, and <Code>LoopByCayleyTable(CanonicalCayleyTable(<Arg>Q</Arg>)</Code> when <Arg>Q</Arg> is a loop.</Description>
</ManSection>

<ManSection>
<Oper Name="NormalizedQuasigroupTable" Arg="T"/>
<Returns>A normalized version of the Cayley table <Arg>T</Arg>.</Returns>
<Description>A given Cayley table <Arg>T</Arg> is normalized in three steps as follows: first, <Code>CanonicalCayleyTable</Code> is called to rename entries to <M>1</M>, <M>\dots</M>, <M>n</M>, then the columns of <Arg>T</Arg> are permuted so that the first row reads <M>1</M>, <M>\dots</M>, <M>n</M>, and finally the rows of <Arg>T</Arg> are permuted so that the first column reads <M>1</M>, <M>\dots</M>, <M>n</M>.</Description>
</ManSection>

</Section>

<!-- Section:  Creating Quasigroups and Loops From Cayley Tables -->

<Section Label="Sec:CreatingQuasigroupsAndLoopsFromCayleyTables"> <Heading>Creating Quasigroups and Loops From Cayley Tables</Heading>

<ManSection>
<Heading>QuasigroupByCayleyTable and LoopByCayleyTable</Heading>
<Oper Name="QuasigroupByCayleyTable" Arg="T"/>
<Oper Name="LoopByCayleyTable" Arg="T"/>
<Returns>The quasigroup (resp. loop) with quasigroup table (resp. loop table) <Arg>T</Arg>.</Returns>
<Description>Since <Code>CanonicalCayleyTable</Code> is called within the above operation, the resulting quasigroup will have Cayley table with distinct entries <M>1</M>, <M>\dots</M>, <M>n</M>.
</Description>
</ManSection>

<Example><![CDATA[
gap> ct := CanonicalCayleyTable( [[5,3],[3,5]] );
[ [ 2, 1 ], [ 1, 2 ] ]
gap> NormalizedQuasigroupTable( ct );
[ [ 1, 2 ], [ 2, 1 ] ]
gap> LoopByCayleyTable( last );
<loop of order 2>
gap> [ IsQuasigroupTable( ct ), IsLoopTable( ct ) ];
[ true, false ]
]]></Example>

</Section>

<!-- Section:  Creating Quasigroups and Loops from a File -->

<Section Label="Sec:CreatingQuasigroupsAndLoopsFromAFile"> <Heading>Creating Quasigroups and Loops from a File</Heading>

Typing a large multiplication table manually is tedious and error-prone. We have therefore included a general method in &LOOPS; that reads multiplication tables of quasigroups from a file.

<P/>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, with file named <Arg>filename</Arg> and a string <Arg>del</Arg> as input (in essence, the characters of <Arg>del</Arg> will be ignored while reading the file):
<List>
        <Item>read the entire content of <Arg>filename</Arg> into a string <Arg>s</Arg>,</Item>
        <Item>replace all end-of-line characters in <Arg>s</Arg> by spaces,</Item>
        <Item>replace by spaces all characters of <Arg>s</Arg> that appear in <Arg>del</Arg>,</Item>
        <Item>split <Arg>s</Arg> into maximal substrings without spaces, called <Emph>chunks</Emph> here,</Item>
        <Item>let <M>n</M> be the number of distinct chunks,</Item>
        <Item>if the number of chunks is not <M>n^2</M>, report error,</Item>
        <Item>construct the multiplication table by assigning numerical values <M>1</M>, <M>\dots</M>, <M>n</M> to chunks, depending on their position among distinct chunks.</Item>
</List>

<P/>The following examples clarify the algorithm and document its versatility. All examples are of the form <M>F+D\Longrightarrow T</M>, meaning that an input file containing <M>F</M> together with the deletion string <M>D</M> produce multiplication table <M>T</M>.

<Br/><P/><B>Example:</B> Data does not have to be arranged into an array of any kind.
<Display>
        \begin{array}{cccc}
                0&1&2&1\\
                2&0&2& \\
                0&1& &
        \end{array}\quad + \quad "" \quad \Longrightarrow\quad
        \begin{array}{ccc}
                1&2&3\\
                2&3&1\\
                3&1&2
        \end{array}
</Display>

<P/><B>Example:</B> Chunks can be any strings.
<Display>
        \begin{array}{cc}
                {\rm red}&{\rm green}\\
                {\rm green}&{\rm red}\\
        \end{array}\quad + \quad ""  \quad \Longrightarrow\quad
        \begin{array}{cc}
                1& 2\\
                2& 1
        \end{array}
</Display>

<P/><B>Example:</B> A typical table produced by &GAP; is easily parsed by deleting brackets and commas.
<Display>
        [ [0, 1], [1, 0] ] \quad + \quad "[,]"  \quad \Longrightarrow\quad
        \begin{array}{cc}
                1& 2\\
                2& 1
        \end{array}
</Display>

<P/><B>Example:</B> A typical &TeX; table with rows separated by lines is also easily converted. Note that we have to use <M>\backslash\backslash</M> to ensure that every occurrence of <M>\backslash</M> is deleted, since <M>\backslash\backslash</M> represents the character <M>\backslash</M> in &GAP;
<Display>
        \begin{array}{lll}
                x\&& y\&&\ z\backslash\backslash\cr
                y\&& z\&&\ x\backslash\backslash\cr
                z\&& x\&&\ y
        \end{array}
         \quad + \quad "\backslash\backslash\&" \quad \Longrightarrow\quad
        \begin{array}{ccc}
                1&2&3\cr
                2&3&1\cr
                3&1&2
        \end{array}
</Display>

<ManSection>
<Heading>QuasigroupFromFile and LoopFromFile</Heading>
<Oper Name="QuasigroupFromFile" Arg="filename, del"/>
<Oper Name="LoopFromFile" Arg="filename, del"/>
<Returns>The quasigroup (resp. loop) whose multiplication table data is in file <Arg>filename</Arg>, ignoring the characters contained in the string <Arg>del</Arg>.</Returns>
</ManSection>

</Section>

<!-- Section:  Creating Quasigroups and Loops From Sections -->

<Section Label="Sec:CreatingQuasigroupsAndLoopsFromSections"> <Heading>Creating Quasigroups and Loops From Sections</Heading>

<ManSection>
<Oper Name="CayleyTableByPerms" Arg="P"/>
<Returns>If <Arg>P</Arg> is a set of <M>n</M> permutations of an <M>n</M>-element set <M>X</M>, returns Cayley table <M>C</M> such that <M>C[i][j] = X[j]^{P[i]}</M>.</Returns>

<Description><P/>The cardinality of the underlying set is determined by the moved points of the first permutation in <Arg>P</Arg>, unless the first permutation is the identity permutation, in which case the second permutation is used.

<P/>In particular, if <Arg>P</Arg> is the left section of a quasigroup <Arg>Q</Arg>, <Code>CayleyTableByPerms(<Arg>Q</Arg>)</Code> returns the multiplication table of <Arg>Q</Arg>.
</Description>

</ManSection>

<ManSection>
<Heading>QuasigroupByLeftSection and LoopByLeftSection</Heading>
<Oper Name="QuasigroupByLeftSection" Arg="P"/>
<Oper Name="LoopByLeftSection" Arg="P"/>
<Returns>If <Arg>P</Arg> is a set of permutations corresponding to the left translations of a quasigroup (resp. loop), returns the corresponding quasigroup (resp. loop).</Returns>

<Description>The order of permutations in <Arg>P</Arg> is important in the quasigroup case, but it is disregarded in the loop case, since then the order of rows in the corresponding multiplication table is determined by the presence of the neutral element.</Description>
</ManSection>

<ManSection>
<Heading>QuasigroupByRightSection and LoopByRightSection</Heading>

<Oper Name="QuasigroupByRightSection" Arg="P"/>
<Oper Name="LoopByRightSection" Arg="P"/>
<Description>
These are the dual operations to <Code>QuasigroupByLeftSection</Code> and <Code>LoopByLeftSection</Code>.</Description>
</ManSection>

<Example><![CDATA[
gap> S := Subloop( MoufangLoop( 12, 1 ), [ 3 ] );;
gap> ls := LeftSection( S );
[ (), (1,3,5), (1,5,3) ]
gap> CayleyTableByPerms( ls );
[ [ 1, 3, 5 ], [ 3, 5, 1 ], [ 5, 1, 3 ] ]
gap> CayleyTable( LoopByLeftSection( ls ) );
[ [ 1, 2, 3 ], [ 2, 3, 1 ], [ 3, 1, 2 ] ]
]]></Example>

</Section>

<!-- Section:  Creating Quasigroups and Loops from Folders -->

<Section Label="Sec:CreatingQuasigroupsAndLoopsFromFolders"> <Heading>Creating Quasigroups and Loops From Folders</Heading>

Let <M>G</M> be a group, <M>H</M> a subgroup of <M>G</M>, and <M>T</M> a right transversal to <M>H</M> in <M>G</M>. Let <M>\tau:G\to T</M> be defined by <M>x\in H\tau(x)</M>. Then the operation <M>\circ</M> defined on the right cosets <M>Q = \{Ht|t\in T\}</M> by <M>Hs\circ Ht = H\tau(st)</M> turns <M>Q</M> into a quasigroup if and only if <M>T</M> is a right transversal to all conjugates <M>g^{-1}Hg</M> of <M>H</M> in <M>G</M>. (In fact, every quasigroup <M>Q</M> can be obtained in this way  by letting <M>G={\rm Mlt}_\rho(Q)</M>, <M>H={\rm Inn}_\rho(Q)</M> and <M>T=\{R_x|x\in Q\}</M>.)

<P/>We call the triple <M>(G,H,T)</M> a <Index Subkey ="quasigroup">folder</Index><Emph>right quasigroup (or loop) folder</Emph>.

<ManSection>
<Heading>QuasigroupByRightFolder and LoopByRightFolder</Heading>

<Oper Name="QuasigroupByRightFolder" Arg="G, H, T"/>
<Oper Name="LoopByRightFolder" Arg="G, H, T"/>
<Returns>The quasigroup (resp. loop) from the right folder (<Arg>G</Arg>, <Arg>H</Arg>, <Arg>T</Arg>).</Returns>

</ManSection>

<P/><B>Remark:</B> We do not support the dual operations for left sections since, by default, actions in &GAP; act on the right.

<Br/><P/>Here is a simple example in which <M>T</M> is actually the right section of the resulting loop.

<Example><![CDATA[
gap> T := [ (), (1,2)(3,4,5), (1,3,5)(2,4), (1,4,3)(2,5), (1,5,4)(2,3) ];;
gap> G := Group( T );; H := Stabilizer( G, 1 );;
gap> LoopByRightFolder( G, H, T );
<loop of order 5>
]]></Example>

</Section>

<!-- Section:  Creating Quasigroups and Loops by Nuclear Extensions  -->

<Section Label="Sec:CreatingQuasigroupsAndLoopsByNuclearExtensions"> <Heading>Creating Quasigroups and Loops By Nuclear Extensions</Heading>

Let <M>K</M>, <M>F</M> be loops. Then a loop <M>Q</M> is an <Index>extension</Index><Emph>extension</Emph> of <M>K</M> by <M>F</M> if <M>K</M> is a normal subloop of <M>Q</M> such that <M>Q/K</M> is isomorphic to <M>F</M>. An extension <M>Q</M> of <M>K</M> by <M>F</M> is <Index Subkey="nuclear">extension</Index><Emph>nuclear</Emph> if <M>K</M> is an abelian group and <M>K\le N(Q)</M>.

<P/>A map <M>\theta:F\times F\to K</M> is a <Index>cocycle</Index><Emph>cocycle</Emph> if <M>\theta(1,x) = \theta(x,1) = 1</M> for every <M>x\in F</M>.

<P/>The following theorem holds for loops <M>Q</M>, <M>F</M> and an abelian group <M>K</M>: <M>Q</M> is
a nuclear extension of <M>K</M> by <M>F</M> if and only if there is a cocycle <M>\theta:F\times F\to K</M> and a homomorphism <M>\varphi:F\to{\rm Aut}(Q)</M> such that <M>K\times F</M> with multiplication <M>(a,x)(b,y) = (a\varphi_x(b)\theta(x,y),xy)</M> is isomorphic to <M>Q</M>.

<ManSection>

<Oper Name="NuclearExtension" Arg="Q, K"/>

<Returns> The data necessary to construct <Arg>Q</Arg> as a nuclear extension of the subloop <Arg>K</Arg> by <Arg>Q</Arg><M>/</M><Arg>K</Arg>, namely <M>[K, F, \varphi, \theta]</M> as above. Note that <Arg>K</Arg> must be a commutative subloop of the nucleus of <Arg>Q</Arg>.</Returns>

<Description>If <M>n=|F|</M> and <M>m=|</M><Arg>K</Arg><M>|</M>, the cocycle <M>\theta</M> is returned as an <M>n\times n</M> array with entries in <M>\{1,\dots,m\}</M>, and the homomorphism <M>\varphi</M> is returned as a list of length <M>n</M> of permutations of <M>\{1,\dots,m\}</M>.</Description>

</ManSection>

<ManSection>

<Oper Name="LoopByExtension" Arg="K, F, f, t"/>
<Returns>The extension of an abelian group <Arg>K</Arg> by a loop <Arg>F</Arg>, using action <Arg>f</Arg> and cocycle <Arg>t</Arg>. The arguments must be formatted as the output of <Code>NuclearExtension</Code>.</Returns>

</ManSection>

<Example><![CDATA[
gap> F := IntoLoop( Group( (1,2) ) );
<loop of order 2>
gap> K := DirectProduct( F, F );;
gap> phi := [ (), (2,3) ];;
gap> theta := [ [ 1, 1 ], [ 1, 3 ] ];;
gap> LoopByExtension( K, F, phi, theta );
<loop of order 8>
gap> IsAssociative( last );
false
]]></Example>

</Section>

<!-- Section:  Random Quasigroups and Loops -->

<Section Label="Sec:RandomQuasigroupsAndLoops"> <Heading>Random Quasigroups and Loops</Heading>

An algorithm is said to select a latin square of order <M>n</M> <Emph>at random</Emph><Index Subkey="random">latin square</Index> if every latin square of order <M>n</M> is returned by the algorithm with the same probability. Selecting a latin square at random is a nontrivial problem.

<P/>In <Cite Key="JaMa"/>, Jacobson and Matthews defined a random walk on the space of latin squares and so-called improper latin squares that visits every latin square with the same probability. The diameter of the space is no more than <M>4(n-1)^3</M> in the sense that no more than <M>4(n-1)^3</M> properly chosen steps are needed to travel from one latin square of order <M>n</M> to another.

<P/>The Jacobson-Matthews algorithm can be used to generate random quasigroups as follows: (i) select any latin square of order <M>n</M>, for instance the canonical multiplication table of the cyclic group of order <M>n</M>, (ii) perform sufficiently many steps of the random walk, stopping at a proper or improper latin square, (iii) if necessary, perform a few more steps to end up with a proper latin square. Upon normalizing the resulting latin square, we obtain a random loop of order <M>n</M>.

<P/>By the above result, it suffices to use about <M>n^3</M> steps to arrive at any latin square of order <M>n</M> from the initial latin square. In fact, a smaller number of steps is probably sufficient.

<ManSection>

<Heading>RandomQuasigroup and RandomLoop</Heading>

<Oper Name="RandomQuasigroup" Arg="n[, iter]"/>
<Oper Name="RandomLoop" Arg="n[, iter]"/>

<Returns>A random quasigroup (resp. loop) of order <Arg>n</Arg> using the Jacobson-Matthews algorithm. If the optional argument <Arg>iter</Arg> is omitted, <Arg>n</Arg><M>{}^3</M> steps are used. Otherwise <Arg>iter</Arg> steps are used.</Returns>

<Description>If <Arg>iter</Arg> is small, the Cayley table of the returned quasigroup (resp. loop) will be close to the canonical Cayley table of the cyclic group of order <Arg>n</Arg>.</Description>

</ManSection>

<ManSection>

<Oper Name="RandomNilpotentLoop" Arg="lst"/>

<Returns>A random nilpotent loop<Index Subkey="nilpotent">loop</Index> as follows (see Section <Ref Sect="Sec:NilpotencyAndCentralSeries"/> for more information on nilpotency): <Arg>lst</Arg> must be a list of positive integers and/or finite abelian groups. If <Code><Arg>lst</Arg>=[a1]</Code> and <Code>a1</Code> is an integer, a random abelian group of order <Code>a1</Code> is returned, else <Code>a1</Code> is an abelian group and <Code>AsLoop(a1)</Code> is returned. If <Code><Arg>lst</Arg>= [a1,...,am]</Code>, a random central extension of <Code>RandomNilpotentLoop([a1])</Code> by <Code>RandomNilpotentLoop([a2,...,am])</Code> is returned.</Returns>

<Description>To determine the nilpotency class <M>c</M> of the resulting loop, assume that <Arg>lst</Arg> has length at least 2, contains only integers bigger than 1, and let <M>m</M> be the last entry of <Arg>lst</Arg>. If <M>m>2</M> then <M>c</M> is equal to <Code>Length(<Arg>lst</Arg>)</Code>, else <M>c</M> is equal to <Code>Length(<Arg>lst</Arg>)-1</Code>.</Description>

</ManSection>

</Section>

<!-- Section:  Conversions -->

<Section Label="Sec:Conversions"> <Heading>Conversions</Heading>

&LOOPS; contains methods that convert between magmas, quasigroups, loops and groups, provided such conversions are possible. Each of the conversion methods <Code>IntoQuasigroup</Code>, <Code>IntoLoop</Code> and <Code>IntoGroup</Code> returns <Code>fail</Code> if the requested conversion is not possible.

<Br/><P/><B>Remark:</B> Up to version 2.0.0 of &LOOPS;, we supported <Code>AsQuasigroup</Code>, <Code>AsLoop</Code> and <Code>AsGroup</Code> in place of <Code>IntoQuasigroup</Code>, <Code>IntoLoop</Code> and <Code>IntoGroup</Code>, respectively. We have changed the terminology starting with version 2.1.0 in order to comply with &GAP; naming rules for <Code>AsSomething</Code>, as explained in Chapter <Ref Chap="Chap:HowThePackageWorks"/>. Finally, the method <Code>AsGroup</Code> is a core method of &GAP; that returns an fp group if its argument is an associative loop.

<ManSection>

<Oper Name="IntoQuasigroup" Arg="M"/>
<Returns>If <Arg>M</Arg> is a declared magma that happens to be a quasigroup, the corresponding quasigroup is returned. If <Arg>M</Arg> is already declared as a quasigroup, <Arg>M</Arg> is returned.</Returns>

</ManSection>

<ManSection>
<Oper Name="PrincipalLoopIsotope" Arg="M, f, g"/>

<Returns>An isomorphic copy of the principal isotope <M>(</M><Arg>M</Arg>,<M>\circ)</M> via the transposition <M>(1</M>,<Arg>f</Arg><M>\cdot</M><Arg>g</Arg><M>)</M>. An isomorphic copy is returned rather than <M>(</M><Arg>M</Arg>,<M>\circ)</M> because in &LOOPS; all loops have to have neutral element labeled as <M>1</M>.</Returns>

<Description>Given a quasigroup <M>M</M> and two of its elements <M>f</M>, <M>g</M>, the principal loop isotope <M>x\circ y = R_g^{-1}(x)\cdot L_f^{-1}(y)</M> turns <M>(M,\circ)</M> into a loop with neutral element <M>f\cdot g</M> (see Section <Ref Sect="Sec:HomomorphismsAndHomotopisms"/>).</Description>
</ManSection>

<ManSection>

<Oper Name="IntoLoop" Arg="M"/>
<Returns>If <Arg>M</Arg> is a declared magma that happens to be a quasigroup (but not necessarily a loop!), a loop is returned as follows: If <Arg>M</Arg> is already declared as a loop, <Arg>M</Arg> is returned. Else, if <Arg>M</Arg> possesses a neutral element <M>e</M> and if <M>f</M> is the first element of <Arg>M</Arg>, then an isomorphic copy of <Arg>M</Arg> via the transposition <M>(e,f)</M> is returned. If <Arg>M</Arg> does not posses a neutral element, <Code>PrincipalLoopIsotope(<Arg>M</Arg>, <Arg>M.1</Arg>, <Arg>M.1</Arg>)</Code> is returned.<Br/></Returns>
</ManSection>

<P/><B>Remark:</B> One could obtain a loop from a declared magma <Arg>M</Arg> in yet another way, by normalizing the Cayley table of <Arg>M</Arg>. The three approaches can result in nonisomorphic loops in general.

<ManSection>

<Oper Name="IntoGroup" Arg="M"/>
<Returns>If <Arg>M</Arg> is a declared magma that happens to be a group, the corresponding group is returned as follows: If <Arg>M</Arg> is already declared as a group, <Arg>M</Arg> is returned, else <Code>RightMultiplicationGroup(IntoLoop(<Arg>M</Arg>))</Code> is returned, which is a permutation group isomorphic to <Arg>M</Arg>.</Returns>

</ManSection>

</Section>

<!-- Section:  Products of Loops -->

<Section Label="Sec:ProductsOfLoops"> <Heading>Products of Quasigroups and Loops</Heading>

<ManSection>

<Oper Name="DirectProduct" Arg="Q1, ..., Qn"/>
<Returns>If each <Arg>Qi</Arg> is either a declared quasigroup, declared loop or a declared group, the direct product of <Arg>Q1</Arg>, <M>\dots</M>, <Arg>Qn</Arg> is returned. If every <Arg>Qi</Arg> is a declared group, a group is returned; if every <Arg>Qi</Arg> is a declared loop, a loop is returned; otherwise a quasigroup is returned.</Returns>

</ManSection>

</Section>

<!-- Section:  Opposite Quasigroups and Loops -->

<Section Label="Sec:OppositeQuasigroupsAndLoops"> <Heading>Opposite Quasigroups and Loops</Heading>

When <M>Q</M> is a quasigroup with multiplication <M>\cdot</M>, the <Index>opposite quasigroup</Index><Index Subkey="opposite">quasigroup</Index><Emph>opposite quasigroup</Emph> of <M>Q</M> is a quasigroup with the same underlying set as <M>Q</M> and with multiplication <M>*</M> defined by <M>x*y=y\cdot x</M>.

<ManSection>
<Heading>Opposite, OppositeQuasigroup and OppositeLoop</Heading>

<Attr Name="Opposite" Arg="Q"/>
<Oper Name="OppositeQuasigroup" Arg="Q"/>
<Oper Name="OppositeLoop" Arg="Q"/>
<Returns> The opposite of the quasigroup (resp. loop) <Arg>Q</Arg>. Note that if <Code>OppositeQuasigroup(<Arg>Q</Arg>)</Code> or <Code>OppositeLoop(<Arg>Q</Arg>)</Code> are called, then the returned quasigroup or loop is not stored as an attribute of <Arg>Q</Arg>.</Returns>

</ManSection>

</Section>

</Chapter>

<!-- CHAPTER: Basic Methods and Attributes -->

<Chapter Label="Chap:BasicMethodsAndAttributes"> <Heading>Basic Methods And Attributes</Heading>

In this chapter we describe the basic core methods and attributes of the &LOOPS; package.

<!-- Section:  Basic Attributes -->

<Section Label="Sec:BasicAttributes"> <Heading>Basic Attributes</Heading>

We associate many attributes with quasigroups in order to speed up computation. This section lists some basic attributes of quasigroups and loops.

<ManSection>
<Attr Name="Elements" Arg="Q"/>
<Returns>The list of elements of a quasigroup <Arg>Q</Arg>.</Returns>
<Description>See Section <Ref Sect="Sec:NamingEtc"/> for more information about element labels.</Description>
</ManSection>

<ManSection>
<Attr Name="CayleyTable" Arg="Q"/>
<Returns>The Cayley table of a quasigroup <Arg>Q</Arg>.</Returns>
<Description>See Section <Ref Sect="Sec:AboutCayleyTables"/> for more information about quasigroup Cayley tables.</Description>
</ManSection>

<ManSection>
<Attr Name="One" Arg="Q"/>
<Returns>The identity element of a loop <Arg>Q</Arg>.</Returns>
</ManSection>

<P/><B>Remark:</B>If you want to know if a quasigroup <Arg>Q</Arg> has a neutral element, you can find out
with the standard function for magmas <Code>MultiplicativeNeutralElement(<Arg>Q</Arg>)</Code>.

<ManSection>
<Attr Name="Size" Arg="Q"/>
<Returns>The size of a quasigroup <Arg>Q</Arg>.</Returns>
</ManSection>

<ManSection>
<Attr Name="Exponent" Arg="Q"/>
<Returns>The exponent of a power associative loop <Arg>Q</Arg>. (The method does not test if <Arg>Q</Arg> is power associative.)</Returns>
<Description>When <Arg>Q</Arg> is a <Emph>power associative loop</Emph><Index Subkey="power associative">loop</Index><Index>power associative loop</Index>, that is, the powers of elements are well-defined in <Arg>Q</Arg>, then the <Emph>exponent</Emph><Index>exponent</Index> of <Arg>Q</Arg> is the smallest positive integer divisible by the orders of all elements of <Arg>Q</Arg>. </Description>
</ManSection>

</Section>

<!-- Section:  Basic Arithmetic Operations -->

<Section Label="Sec:BasicArithemticOperations"> <Heading>Basic Arithmetic Operations</Heading>

Each quasigroup element in &GAP; knows to which quasigroup it belongs. 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.

<P/>Two elements <M>x</M>, <M>y</M> of the same quasigroup are multiplied by <M>x*y</M> in &GAP;. Since multiplication of at least three elements is ambiguous in the nonassociative case, we parenthesize elements by default from left to right, i.e., <M>x*y*z</M> means <M>((x*y)*z)</M>. Of course, one can specify the order of multiplications by providing parentheses.

<ManSection>
<Heading>LeftDivision and RightDivision</Heading>

<Oper Name="LeftDivision" Arg="x, y"/>
<Oper Name="RightDivision" Arg="x, y"/>
<Returns>The left division <Arg>x</Arg><M>\backslash</M><Arg>y</Arg> (resp. the right division <Arg>x</Arg><M>/</M><Arg>y</Arg>) of two elements <Arg>x</Arg>, <Arg>y</Arg> of the same quasigroup.<Br/></Returns>

<Oper Name="LeftDivision" Arg="S, x"/>
<Oper Name="LeftDivision" Arg="x, S"/>
<Oper Name="RightDivision" Arg="S, x"/>
<Oper Name="RightDivision" Arg="x, S"/>
<Returns>The list of elements obtained by performing the specified arithmetical operation elementwise using a list <Arg>S</Arg> of elements and an element <Arg>x</Arg>.<Br/></Returns>

</ManSection>

<P/><B>Remark:</B> We support <M>/</M> in place of <Code>RightDivision</Code>. But we do not support <M>\backslash</M> in place of <Code>LeftDivision</Code>.

<ManSection>
<Heading>LeftDivisionCayleyTable and RightDivisionCayleyTable</Heading>
<Oper Name="LeftDivisionCayleyTable" Arg="Q"/>
<Oper Name="RightDivisionCayleyTable" Arg="Q"/>
<Returns>The Cayley table of the respective arithmetic operation of a quasigroup <Arg>Q</Arg>.</Returns>
</ManSection>

</Section>

<!-- Section:  Powers and Inverses -->

<Section Label="Sec:PowersAndInverses"> <Heading>Powers and Inverses</Heading>

Powers of elements are generally not well-defined in quasigroups. For magmas and a positive integral exponent, &GAP; calculates powers in the following way: <M>x^1=x</M>, <M>x^{2k}=(x^k)\cdot(x^k)</M> and <M>x^{2k+1}=(x^{2k})\cdot x</M>. One can easily see that this returns <M>x^k</M> in about <M>\log_2(k)</M> steps. For &LOOPS;, we have decided to keep this method, but the user should be aware that the method is sound only in power associative quasigroups.

<P/>Let <M>x</M> be an element of a loop <M>Q</M> with neutral element <M>1</M>. Then the <Emph>left inverse</Emph><Index Subkey="left">inverse</Index> <M>x^\lambda</M> of <M>x</M> is the unique element of <M>Q</M> satisfying <M>x^\lambda x=1</M>. Similarly, the <Emph>right inverse</Emph><Index Subkey="right">inverse</Index> <M>x^\rho</M> satisfies <M>xx^\rho=1</M>. If <M>x^\lambda=x^\rho</M>, we call <M>x^{-1}=x^\lambda=x^\rho</M> the <Emph>inverse</Emph><Index>inverse</Index> of <M>x</M>.

<ManSection>
<Heading>LeftInverse, RightInverse and Inverse</Heading>

<Oper Name="LeftInverse" Arg="x"/>
<Oper Name="RightInverse" Arg="x"/>
<Oper Name="Inverse" Arg="x"/>
<Returns>The left inverse, right inverse and inverse, respectively, of the quasigroup element <Arg>x</Arg>.</Returns>
</ManSection>

<Example><![CDATA[
gap> CayleyTable( Q );
[ [ 1, 2, 3, 4, 5 ],
  [ 2, 1, 4, 5, 3 ],
  [ 3, 4, 5, 1, 2 ],
  [ 4, 5, 2, 3, 1 ],
  [ 5, 3, 1, 2, 4 ] ]
gap> elms := Elements( Q );
gap> [ l1, l2, l3, l4, l5 ];
gap> [ LeftInverse( elms[3] ), RightInverse( elms[3] ), Inverse( elms[3] ) ];
[ l5, l4, fail ]
]]></Example>

</Section>

<!-- Section:  Associators and Commutators -->

<Section Label="Sec:AssociatorsAndCommutators2"> <Heading>Associators and Commutators</Heading>

See Section <Ref Sect="Sec:AssociatorsAndCommutators"/> for definitions of associators and commutators.

<ManSection>
<Oper Name="Associator" Arg="x, y, z"/>
<Returns>The associator of the elements <Arg>x</Arg>, <Arg>y</Arg>, <Arg>z</Arg> of the same quasigroup.</Returns>
</ManSection>

<ManSection>
<Oper Name="Commutator" Arg="x, y"/>
<Returns>The commutator of the elements <Arg>x</Arg>, <Arg>y</Arg> of the same quasigroup.</Returns>
</ManSection>

</Section>

<!-- Section:  Generators -->

<Section Label="Sec:Generators"> <Heading>Generators</Heading>

<ManSection>
<Heading>GeneratorsOfQuasigroup and GeneratorsOfLoop</Heading>
<Attr Name="GeneratorsOfQuasigroup" Arg="Q"/>
<Attr Name="GeneratorsOfLoop" Arg="Q"/>
<Returns>A set of generators of a quasigroup (resp. loop) <Arg>Q</Arg>. (Both methods are synonyms of <Code>GeneratorsOfMagma</Code>.)</Returns>
</ManSection>

<P/>As usual in &GAP;, one can refer to the <Code>i</Code>th generator of a quasigroup <Code>Q</Code> by <Code>Q.i</Code>. Note that while it is often the case that <Code> Q.i = Elements(Q)[i]</Code>, it is not necessarily so.

<ManSection>
<Attr Name="GeneratorsSmallest" Arg="Q"/>
<Returns>A generating set <M>\{q_0</M>, <M>\dots</M>, <M>q_m\}</M> of <Arg>Q</Arg> such that
<M>Q_0=\emptyset</M>, <M>Q_m=</M><Arg>Q</Arg>, <M>Q_i=\langle q_1</M>, <M>\dots</M>, <M>q_i \rangle</M>, and <M>q_{i+1}</M> is the least element of <Arg>Q</Arg><M>\setminus Q_i</M>.</Returns>
</ManSection>

<ManSection>
<Attr Name="SmallGeneratingSet" Arg="Q"/>
<Returns>A small generating set <M>\{q_0</M>, <M>\dots</M>, <M>q_m\}</M> of <Arg>Q</Arg> obtained as follows: <M>q_0</M> is the least element for which <M>\langle q_0\rangle</M> is largest possible, <M>q_1</M>$ is the least element for which <M>\langle q_0,q_1</M> is largest possible, and so on.</Returns>
</ManSection>

</Section>

</Chapter>

<!-- CHAPTER: Methods Based on Permutation Groups -->

<Chapter Label="Chap:MethodsBasedOnPermutationGroups"> <Heading>Methods Based on Permutation Groups</Heading>

Most calculations in the &LOOPS; package are delegated to groups, taking advantage of the various permutations and permutation groups associated with quasigroups. This chapter explains in detail how the permutations associated with a quasigroup are calculated, and it also describes some of the core methods of &LOOPS; based on permutations. Additional core methods can be found in Chapter <Ref Chap="Chap:TestingPropertiesOfQuasigroupsAndLoops"/>.

<!-- Section:  Parent of a Quasigroup -->

<Section Label="Sec:ParentOfAQuasigroup"> <Heading>Parent of a Quasigroup</Heading>

Let <M>Q</M> be a quasigroup and <M>S</M> a subquasigroup of <M>Q</M>. Since the multiplication in <M>S</M> coincides with the multiplication in <M>Q</M>, it is reasonable not to store the multiplication table of <M>S</M>. However, the quasigroup <M>S</M> then must know that it is a subquasigroup of <M>Q</M>.

<ManSection>
<Attr Name="Parent" Arg="Q"/>
<Returns>The parent quasigroup of the quasigroup <Arg>Q</Arg>.</Returns>

<Description>When <Arg>Q</Arg> is not created as a subquasigroup of another quasigroup, the attribute <Code>Parent(<Arg>Q</Arg>)</Code> is set to <Arg>Q</Arg>. When <Arg>Q</Arg> is created as a subquasigroup of a quasigroup <Arg>H</Arg>, we set <Code>Parent(<Arg>Q</Arg>)</Code> equal to <Code>Parent(<Arg>H</Arg>)</Code>. Thus, in effect, <Code>Parent(<Arg>Q</Arg>)</Code> is the largest quasigroup from which <Arg>Q</Arg> has been created.</Description>

</ManSection>

<ManSection>
<Oper Name="Position" Arg="Q, x"/>
<Returns>The position of <Arg>x</Arg> among the elements of <Arg>Q</Arg>.<Br/></Returns>
</ManSection>

<P/>Let <Arg>Q</Arg> be a quasigroup with parent <Arg>P</Arg>, where <Arg>P</Arg> is some <M>n</M>-element quasigroup. Let <Arg>x</Arg> be an element of <Arg>Q</Arg>. Then <Code><Arg>x</Arg>![1]</Code> is the position of <Arg>x</Arg> among the elements of <Arg>P</Arg>, i.e., <Code><Arg>x</Arg>![1] = Position(Elements(<Arg>P</Arg>),<Arg>x</Arg>)</Code>.

<P/>While referring to elements of <Arg>Q</Arg> by their positions, the user should understand whether the positions are meant among the elements of <Arg>Q</Arg>, or among the elements of the parent <Arg>P</Arg> of <Arg>Q</Arg>. Since it requires no calculation to obtain <Code><Arg>x</Arg>![1]</Code>, we always use the position of an element in its parent quasigroup in &LOOPS;. In this way, many attributes of a quasigroup, including its Cayley table, are permanently tied to its parent.

<P/>It is now clear why we have not insisted that Cayley tables of quasigroups must have entries covering the entire interval <M>1</M>, <M>\dots</M>, <M>n</M> for some <M>n</M>.

<ManSection>

<Oper Name="PosInParent" Arg="S"/>
<Returns>When <Arg>S</Arg> is a list of quasigroup elements (not necessarily from the same quasigroup), returns the corresponding list of positions of elements of <Arg>S</Arg> in the corresponding parent, i.e., <Code>PosInParent(<Arg>S</Arg>)[i] = <Arg>S</Arg>[i]![1] = Position(Parent(<Arg>S</Arg>[i]),<Arg>S</Arg>[i])</Code>.<Br/></Returns>

</ManSection>

<P/>Quasigroups with the same parent can be compared as follows. Assume that <M>A</M>, <M>B</M> are two quasigroups with common parent <M>Q</M>. Let <M>G_A</M>, <M>G_B</M> be the canonical generating sets of <M>A</M> and <M>B</M>, respectively, obtained by the method <Code>GeneratorsSmallest</Code> (see Section <Ref Sect="Sec:Generators"/>). Then we define <M>A<B</M> if and only if <M>G_A<G_B</M> lexicographically.

</Section>

<!-- Section:  Subquasigroups and Subloops -->

<Section Label="Sec:SubquasigroupsAndSubloops2"> <Heading>Subquasigroups and Subloops</Heading>

<ManSection>
<Oper Name="Subquasigroup" Arg="Q, S"/>
<Returns>When <Arg>S</Arg> is a subset of elements or indices of a quasigroup (resp. loop) <Arg>Q</Arg>, returns the smallest subquasigroup (resp. subloop) of <Arg>Q</Arg> containing <Arg>S</Arg>.</Returns>

<Description>We allow <Arg>S</Arg> to be a list of elements of <Arg>Q</Arg>, or a list of integers representing the positions of the respective elements in the parent quasigroup (resp. loop) of <Arg>Q</Arg>.

<P/>If <Arg>S</Arg> is empty, <Code>Subquasigroup(<Arg>Q</Arg>,<Arg>S</Arg>)</Code> returns the empty set if <Arg>Q</Arg> is a quasigroup, and it returns the one-element subloop of <Arg>Q</Arg> if <Arg>Q</Arg> is a loop.

<P/><B>Remark:</B> The empty set is sometimes considered to be a subquasigroup of <Arg>Q</Arg> (although not in &LOOPS;). The above convention is useful for handling certain situations, for instance when the user calls <Code>Center(<Arg>Q</Arg>)</Code> for a quasigroup <Arg>Q</Arg> with empty center.</Description>
</ManSection>

<ManSection>
<Oper Name="Subloop" Arg="Q, S"/>
<Description>This is an analog of <Code>Subquasigroup(<Arg>Q</Arg>,<Arg>S</Arg>)</Code> that can be used only when <Arg>Q</Arg> is a loop. Since there is no difference in the outcome while calling <Code>Subquasigroup(<Arg>Q</Arg>,<Arg>S</Arg>)</Code> or <Code>Subloop(<Arg>Q</Arg>,<Arg>S</Arg>)</Code> when <Arg>Q</Arg> is a loop, it is safe to always call <Code>Subquasigroup(<Arg>Q</Arg>,<Arg>S</Arg>)</Code>, whether <Arg>Q</Arg> is a loop or not.
</Description>
</ManSection>

<ManSection>
<Heading>IsSubquasigroup and IsSubloop</Heading>
<Oper Name="IsSubquasigroup" Arg="Q, S"/>
<Oper Name="IsSubloop" Arg="Q, S"/>

<Returns><Code>true</Code> if <Arg>S</Arg> is a subquasigroup (resp. subloop) of a quasigroup (resp. loop) <Arg>Q</Arg>, <Code>false</Code> otherwise. In other words, returns <Code>true</Code> if <Arg>S</Arg> and <Arg>Q</Arg> are quasigroups (resp. loops) with the same parent and <Arg>S</Arg> is a subset of <Arg>Q</Arg>.</Returns>
</ManSection>

<ManSection>
<Oper Name="AllSubquasigroups" Arg="Q"/>
<Returns>A list of all subquasigroups of a loop <Arg>Q</Arg>.</Returns>
</ManSection>

<ManSection>
<Oper Name="AllSubloops" Arg="Q"/>
<Returns>A list of all subloops of a loop <Arg>Q</Arg>.</Returns>
</ManSection>

<ManSection>

<Func Name="RightCosets" Arg="Q, S"/>
<Returns>If <Arg>S</Arg> is a subloop of <Arg>Q</Arg>, returns a list of all right cosets<Index>coset</Index> of <Arg>S</Arg> in <Arg>Q</Arg>.</Returns>

<Description>The coset <Arg>S</Arg> is listed first, and the elements of each coset are ordered in the same way as the elements of <Arg>S</Arg>, i.e., if <Arg>S</Arg><M> = [s_1,\dots,s_m]</M>, then <Arg>S</Arg><M>x=[s_1x,\dots,s_mx]</M>.</Description>

</ManSection>

<ManSection>
<Oper Name="RightTransversal" Arg="Q, S"/>
<Returns>A right transversal of a subloop <Arg>S</Arg> in a loop <Arg>Q</Arg>. The transversal consists of the list of first elements from the right cosets obtained by <Code>RightCosets(<Arg>Q</Arg>,<Arg>S</Arg>)</Code>.</Returns>
<Description>When <Arg>S</Arg> is a subloop of <Arg>Q</Arg>, the right transversal<Index>transversal</Index> of <Arg>S</Arg> with respect to <Arg>Q</Arg> is a subset of <Arg>Q</Arg> containing one element from each right coset of <Arg>S</Arg> in <Arg>Q</Arg>.</Description>
</ManSection>

</Section>

<!-- Section:  Translations and Sections -->

<Section Label="Sec:TranslationsAndSections"> <Heading>Translations and Sections</Heading>

When <M>x</M> is an element of a quasigroup <M>Q</M>, the left translation <M>L_x</M> is a permutation of <M>Q</M>. In &LOOPS;, all permutations associated with quasigroups and their elements are permutations in the sense of &GAP;, i.e., they are bijections of some interval <M>1</M>, <M>\dots</M>, <M>n</M>. Moreover, following our convention, the numerical entries of the permutations point to the positions among elements of the parent of <M>Q</M>, not among elements of <M>Q</M>.

<ManSection>
<Heading>LeftTranslation and RightTranslation</Heading>
<Oper Name="LeftTranslation" Arg="Q, x"/>
<Oper Name="RightTranslation" Arg="Q, x"/>
<Returns>If <Arg>x</Arg> is an element of a quasigroup <Arg>Q</Arg>, returns the left translation (resp. right translation) by <Arg>x</Arg> in <Arg>Q</Arg>.</Returns>
</ManSection>

<ManSection>
<Heading>LeftSection and RightSection</Heading>
<Oper Name="LeftSection" Arg="Q"/>
<Oper Name="RightSection" Arg="Q"/>
<Returns>The left section (resp. right section) of a quasigroup <Arg>Q</Arg>.<Br/></Returns>
</ManSection>

<P/>Here is an example illustrating the main features of the subquasigroup construction and the relationship between a quasigroup and its parent.

<P/>Note how the Cayley table of a subquasigroup is created only upon explicit demand. Also note that changing the names of elements of a subquasigroup (subloop) automatically changes the names of the elements of the parent subquasigroup (subloop). This is because the elements are shared.

<Example><![CDATA[
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, 3, 5 ], [ 3, 5, 1 ], [ 5, 1, 3 ] ]
gap> LeftSection( S );
[ (), (1,3,5), (1,5,3) ]
gap> [ HasCayleyTable( S ), Parent( S ) = M ];
[ true, true ]
gap> L := LoopByCayleyTable( CayleyTable( S ) );; Elements( L );
[ l1, l2, l3 ]
gap> [ Parent( L ) = L, IsSubloop( M, S ), IsSubloop( M, L ) ];
[ true, true, false ]
gap> LeftSection( L );
[ (), (1,2,3), (1,3,2) ]
]]></Example>

</Section>

<!-- Section:  Multiplication Groups -->

<Section Label="Sec:MultiplicationGroups"> <Heading>Multiplication Groups</Heading>

<ManSection>
<Heading>LeftMultiplicationGroup, RightMultiplicationGroup and MultiplicationGroup</Heading>
--> --------------------

--> maximum size reached

--> --------------------

98%


¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.46Angebot  Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.