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 Testing properties of quasigroups and loops.
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
Parent(
Q ) A
for a quasigroup Q.
When Q is not created as a subquasigroup of another quasigroup, the
attribute Parent(
Q )
is set to Q. When Q is created as a subquasigroup
of a quasigroup H, we let Parent(
Q ) := Parent(
H )
. Thus, in effect,
Parent(
Q )
is the largest quasigroup from which Q has been created.
Let Q be a quasigroup with parent P, where P is some n-element
quasigroup. Let x be an element of Q. Then x![1]
is the position of x
among the elements of P, i.e., x![1] = Position( Elements( P ), x )
. The
position of x among the elements of Q is obtained via
Position(
Q, x ) O
While referring to elements of Q by their positions, we therefore must decide
if the positions are meant among the elements of Q, or among the elements of
P. Since it requires no calculation to obtain x![1]
, we always use the
position of an element in its parent quasigroup. In this way, many attributes
of a quasigroup, including its Cayley table, are permanently tied to its
parent. It is now clear why we have not insisted that Cayley tables of
quasigroups must have entries covering the entire interval 1, ..., m,
for some m.
When S is a list of quasigroup elements, not necessarily from the same quasigroup, the operation
PosInParent(
S )
returns the list of positions of elements of S in the corresponding parent,
i.e., PosInParent(
S )[ i ] = S[ i ]![ 1 ] = Position( Parent( S[ i ] ), S[
i ] )
.
noindentAssume that A, B are two quasigroups with common parent Q. Let
GA, GB be the canonical generating sets of A and B, respectively,
obtained by the method GeneratorsSmallest
, described above. Then we
define A < B if and only if GA < GB lexicographically.
Note that if A is a subquasigroup of B, we get A < B, but not necessarily vice versa.
When S is a subset of a quasigroup Q (loop L), the smallest subquasigroup of Q (subloop of L) generated by S is returned via:
Subquasigroup(
Q,
S ) O
Subloop(
L,
S ) O
In fact, we allow S to be a list of integers, too, representing the positions of the respective elements in the parent quasigroup (loop).
The following two operations test if a quasigroup (loop) S is a subquasigroup
(subloop) of a quasigroup Q. They return true
if and only if Q and S
have the same parent, and if S is a subset of Q.
IsSubquasigroup(
Q,
S ) O
IsSubloop(
Q,
S ) O
The operation
AllSubloops(
L ) O
returns a list of all subloops of the loop L.
Let S be a subloop of L. The list of all right cosetsindexcoset of S in L is obtained via
RightCosets(
L,
S ) F
The coset S is listed first, and the elements of each coset are ordered in the same way as elements of S, i.e., if S = [s1,...,sm] then Sx=[s1x, ..., smx].
When S is a subloop of L, the right transversalindextransversal of S with respect to L is a subset of L containing one element from each right coset of S in L. It is obtained by
RightTransversal(
L,
S ) O
and it returns the first element from each right coset obtained by
RightCosets(
L,
S )
.
When x is an element of a quasigroup Q, the left translation Lx is a
permutation of Q. In LOOPS, all permutations associated with quasigroups
and their elements are permutations in the sense of GAP, i.e., bijections of
some interval 1, ..., n. Moreover, following our convention, the
numerical entries of the permutation point to the positions among elements of
Parent(
Q )
, not Q.
The left and right translations by x in Q are obtained by
LeftTranslation(
Q,
x ) O
RightTranslation(
Q,
x ) O
The following two attributes calculate the left and right section of a quasigroup Q:
LeftSection(
Q ) A
RightSection(
Q ) A
Here is an example illustrating the main features of the subquasigroup construction and the relationship between a quasigroup and its parent.
Note how the Cayley table of the 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.
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) ]
The left multiplication group, right multiplication group and the multiplication group of a quasigroup Q are calculated as follows:
LeftMultiplicationGroup(
Q ) A
RightMultiplicationGroup(
Q ) A
MultiplicationGroup(
Q ) A
Let S be a subloop of a loop L. Then the relative left multiplication groupindexrelative left multiplication group of L with respect to S is the group áL(x)|x Î Sñ, where L(x) is the left translation by x in Q restricted to S. The relative right multiplication groupindexrelative right multiplication group and relative multiplication group indexrelative multiplication group are defined analogously.
RelativeLeftMultiplicationGroup(
L,
S ) O
RelativeRightMultiplicationGroup(
L,
S ) O
RelativeMultiplicationGroup(
L,
S ) O
The inner mapping groupindexinner mapping group of a loop L is the stabilizer of the unit element in Mlt(L). The elements of this stabilizer are called inner maps of L.
The left inner mapping groupindexleft inner mapping group of a loop L is the stabilizer of the unit element in LMlt(L). The right inner mapping groupindexright inner mapping group is defined dually.
Equivalently, the left inner mapping group is generated by all left inner mappingsindexleft inner mapping L(x,y) = Lyx-1LyLx, and the right inner mapping group is generated by all right inner mappingsindexright inner mapping R(x,y) = Rxy-1RyRx.
In analogy with group theory, we define the conjugationindexconjugation, or the middle inner mappingindexmiddle inner mapping by x as T(x) = Lx-1Rx. The middle inner mappingindexmiddle inner mapping is then the subgroup of Mlt(L) generated by all conjugations.
The corresponding commands in LOOPS are
LeftInnerMapping(
L,
x,
y ) O
MiddleInnerMapping(
L,
x ) O
RightInnerMapping(
L,
x,
y ) O
LeftInnerMappingGroup(
L ) A
MiddleInnerMappingGroup(
L ) A
RightInnerMappingGroup(
L ) A
InnerMappingGroup(
L ) A
Here is an example for multiplication groups and inner mapping groups:
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
Let Q be a quasigroup. The left nucleusindexleft nucleus Nl(Q) of Q is the set {x Î Q| x(yz)=(xy)z for every y, z Î Q}. One defines similarly the middle nucleusindexmiddle nucleus Nm(Q) and the right nucleusindexright nucleus Nr(Q). Then the nucleusindexnucleus N(Q) of Q is the intersection of the three nuclei.
The nuclei are calculated in LOOPS as follows:
LeftNucleus(
Q ) A
MiddleNucleus(
Q ) A
RightNucleus(
Q ) A
Nuc(
Q ) A
Unfortunately, the word Nucleus
is reserved in the core of GAP for a
global function with two variables. That is the reason why we have used the
abbreviation Nuc
, which is also common in the literature. However, we support
these synonyms of Nuc
:
NucleusOfLoop(
Q ) A
NucleusOfQuasigroup(
Q ) A
Since all nuclei are subquasigroups of Q, they are returned as subquasigroups (resp. subloops). When Q is a loop then all nuclei are in fact groups, and they are returned as associative loops.
The commutantindexcommutant C(Q) of Q is the set {x Î Q | xy=yx for every y Î Q}. It is also known under the name Moufang centerindexMoufang center and centrumindexcentrum. It is obtained via
Commutant(
Q ) A
The center Z(Q) is defined as the intersection of C(Q) and N(Q), and it is obtained via
Center(
Q ) A
It is a subgroup of Q and is therefore returned as an associative loop.
Finally, the associator subloopindexassociator subloop of a loop L is the smallest normal subloop A(L) of L containing all associators of L. Equivalently, A(L) is the smallest normal subloop K such that L/K is associative. We use another equivalent reformulation for the purposes of computation: A(L) is the smallest normal subloop of L containing {x\a(x) | x Î L, a is a left inner mapping}.
AssociatorSubloop(
L ) A
A subloop S of a loop L is normalindexnormal subloop if it is invariant under all inner mappings of L. Normality is tested via:
IsNormal(
L,
S ) O
When S is a subset of a loop L or a subloop of L, the normal closureindexnormal closure of S in L is the smallest normal subloop of L containing S. It is obtained by
NormalClosure(
L,
S ) O
A loop L is simpleindexsimple loop if all normal subloops of L are trivial. The corresponding test in LOOPS is:
IsSimple(
L ) O
When N is a normal subloop of a loop L, the factor loop L/N can be
obtained directly via the command L/N
, or by
FactorLoop(
L,
N ) O
The natural projection from L to L/N is returned by
NaturalHomomorphismByNormalSubloop(
L,
N ) O
Here is an illustrating example:
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( x ) ... end )
The definition of nilpotency and nilpotence class is the same as in group theory. The corresponding commands are:
NilpotencyClassOfLoop(
L ) A
IsNilpotent(
L ) P
When L is not nilpotent, NilpotencyClassOfLoop(
L )
returns fail
.
A loop L is said to be strongly nilpotentindexstrongly nilpotent loop if its multiplication group is nilpotent. This property is obtained by
IsStronglyNilpotent(
L ) P
Let L be a loop. Define iterated centersindexiterated centers Zi(L) as follows: Z0(L)=Z(L), Zi+1(L) = pi-1( Zi(L) ), where pi is the canonical projection L® L/Zi(L). The longest series Zi(L), Zi-1(L), ..., Z0(L) with Zi(L) > Zi-1(L) > ¼ > Z0(L) is called the upper central seriesindexupper central series of L, and is returned via
UpperCentralSeries(
L ) A
The lower central seriesindexlower central series, defined in the usual way, is obtained by
LowerCentralSeries(
L ) A
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.
IsSolvable(
L ) P
DerivedSubloop(
L ) A
DerivedLength(
L ) A
FrattiniSubloop(
L ) A
FrattinifactorSize(
L ) A
All isomorphisms between two loops can be found with LOOPS. The operation
IsomorphismLoops(
L,
M ) O
returns a single isomorphism between loops L, M if the loops are
isomorphic, and fail
otherwise.
If an isomorphism exists, it is returned as a permutation p of 1, ..., |L|, where ip=j means that the ith element of L is mapped onto the jth element of M. This is true even if L or M are not their own parents.
Since one frequently needs to filter a list of loops up to isomorphism, we support
LoopsUpToIsomorphism(
ls ) O
Given a list ls of loops, the operation returns a sublist of ls containing one loop from each isomorphism class of loops present in ls.
The attribute
AutomorphismGroup(
L ) A
returns the automorphism group of the loop L, with the same convention on
permutations as in the case of IsomorphismLoops
.
Since two isomorphisms "differ" by an automorphism, all isomorphisms can be obtained by the above two functions.
While dealing with Cayley tables, it is often useful to rename or reorder the elements without changing the isomorphism type. When Q is a quasigroup of size n and p is a permutation of {1,...,n},
IsomorphicCopyByPerm( Q, p )
returns quasigroup (Q,°) such that p(xy) = p(x)°p(y), i.e., x°y = p( p-1(x)p-1(y)). When Q is a declared loop, a loop is returned. Consequently, when Q is a declared loop and p(1) = k ¹ 1, then p is first replaced by p°(1,k), to make sure that the Cayley table is normalized.
When S is a normal subloop of L,
IsomorphicCopyByNormalSubloop( L, S )
returns an isomorphic copy of L in which the elements are ordered according to the right cosets of S. In particular, the Cayley table of S will appear in the top left corner of the Cayley table of the resulting loop.
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 isomorphisms. These invariants for a loop L can be obtained via
Discriminator(
L ) O
Since the details are technical, we will not present them here. See Vo
or the file iso.gi
for more.
If two loops have different discriminators, they are not isomorphic. If they have identical discriminators, they may or may not be isomorphic. The operation
AreEqualDiscriminators(
D1,
D2 ) O
returns true
if the discriminators D1, D2 are equal.
The package contains a slow method for testing if two loops are isotopic:
IsotopismLoops(
K,
L ) O
It returns fail
if K, L are not isotopic, else it returns an isotopism as
a triple of bijections on {1,...,|K|}.
The method works as follows: It is well known that if a loop K is isotopic to a loop L then there exist a principal loop isotope P of K such that P is isomorphic to L. The algorithm first finds all principal isotopes of K, then filters them up to isomorphism, and then checks if any of them is isomorphic to L. This is rather slow already for small orders, say 30.
The function
LoopsUpToIsotopism(
ls ) O
filters the list ls in a way similar to LoopsUpToIsomorphism
, but using
isotopism as the underlying equivalence relation.
[Up] [Previous] [Next] [Index]
loops manual