loops/gap/quasigroups.gd

174 lines
7.9 KiB
GDScript3

#############################################################################
##
#W quasigroups.gd Representing, creating and displaying quasigroups [loops]
##
#H @(#)$Id: quasigroups.gd, v 3.4.0 2017/10/17 gap Exp $
##
#Y Copyright (C) 2004, G. P. Nagy (University of Szeged, Hungary),
#Y P. Vojtechovsky (University of Denver, USA)
##
#############################################################################
## GAP CATEGORIES AND REPRESENTATIONS
## -------------------------------------------------------------------------
## Categories convenient for defining quasigroups
## element which is an admissible argument for the right argument of /
DeclareCategory( "IsRightQuotientElement", IsExtLElement);
DeclareCategoryCollections("IsRightQuotientElement");
DeclareCategoryCollections("IsRightQuotientElementCollection");
## Every associative element with an inverse can form right quotients
## (in fact, in some sense it might be enough to have just a left inverse,
## but there doesn't seem to be any benefit to delving to that level of
## detail at this point.)
## By noting this property, we can create a RightQuasigroup from, e.g., group
## elements
InstallTrueMethod(IsRightQuotientElement,
IsMultiplicativeElementWithInverse and IsAssociativeElement);
## Now what we would like to do is re-declare
## DeclareOperation( "/", [IsExtRElement, IsRightQuotientElement] );
## but we can't since "/" is in the kernel, so we will have to content
## ourselves with InstallOtherMethod() calls on /. (I am not actually sure what
## the practical upshot of that is, i.e. if it has any shortcomings as compared
## to if we could declare "/" more generally.)
## Element which is admissible for the left argument of LeftQuotient()
DeclareCategory( "IsLeftQuotientElement", IsExtRElement);
DeclareCategoryCollections("IsLeftQuotientElement");
DeclareCategoryCollections("IsLeftQuotientElementCollection");
## Every associative element with an inverse can form left quotients
InstallTrueMethod(IsLeftQuotientElement,
IsMultiplicativeElementWithInverse and IsAssociativeElement);
## Again, ideally (in some sense) we'd like to redeclare
## DeclareOperation("LeftQuotient", [IsLeftQuotientElement,IsExtLElement]);
## element of a quasigroup
DeclareSynonym( "IsQuasigroupElement",
IsMultiplicativeElement and
IsLeftQuotientElement and IsRightQuotientElement );
DeclareRepresentation( "IsQuasigroupElmRep",
IsPositionalObjectRep and IsQuasigroupElement, [1] );
## element of a loop
DeclareSynonym( "IsLoopElement",
IsQuasigroupElement and IsMultiplicativeElementWithInverse );
DeclareRepresentation( "IsLoopElmRep",
IsQuasigroupElmRep and IsMultiplicativeElementWithInverse, [1] );
## Right quasigroup
DeclareCategory("IsRightQuasigroup",
IsMagma and IsRightQuotientElementCollection);
## Although the following assertion is mathematically correct, unfortunately
## it interferes with method selection for standard group operations
## in GAP. As an example, if it is uncommented, it will no longer be possible
## to construct a CyclicGroup; trying to do so eventually dies in
## GeneratorsOfRightQuasigroup. Those errors could conceivably be corrected by
## delving further into GAP's method selection mechanism and adjusting the
## declarations of various quasigroup operations, but it doesn't seem worth
## the effort as there is unlikely to be much call to consider a group as a
## quasigroup. If it is desirable to do so in a particular case, it should be
## possible to use the elements of the group to form a quasigroup, since they
## will all satisfy IsRightQuotientElement by a TrueMethod installed above.
## InstallTrueMethod(IsRightQuasigroup, IsGroup);
## Left quasigroup
DeclareCategory("IsLeftQuasigroup",
IsMagma and IsLeftQuotientElementCollection);
## We forego the following for the reasons outlined above for right quasigroups.
## InstallTrueMethod(IsLeftQuasigroup, IsGroup);
## quasigroup
DeclareSynonym( "IsQuasigroup", IsRightQuasigroup and IsLeftQuasigroup );
## loop
DeclareSynonym( "IsLoop", IsQuasigroup and IsMagmaWithOne and
IsMultiplicativeElementWithInverseCollection);
#############################################################################
## TESTING MULTIPLICATION TABLES
## -------------------------------------------------------------------------
DeclareProperty( "IsLeftQuasigroupTable", IsMatrix );
DeclareProperty( "IsRightQuasigroupTable", IsMatrix );
DeclareSynonym( "IsQuasigroupTable",
IsLeftQuasigroupTable and IsRightQuasigroupTable );
DeclareSynonym( "IsQuasigroupCayleyTable", IsQuasigroupTable );
DeclareProperty( "IsLoopTable", IsMatrix );
DeclareSynonym( "IsLoopCayleyTable", IsLoopTable );
DeclareGlobalFunction("CanonicalCayleyTableOfLeftQuasigroupTable");
DeclareOperation( "CanonicalCayleyTable", [ IsMatrix ] );
DeclareOperation( "NormalizedQuasigroupTable", [ IsMatrix ] );
#############################################################################
## CREATING QUASIGROUPS AND LOOPS MANUALLY
## -------------------------------------------------------------------------
DeclareAttribute( "CayleyTable", IsMagma );
DeclareOperation( "QuasigroupByCayleyTable", [ IsMatrix ] );
DeclareOperation( "LoopByCayleyTable", [ IsMatrix ] );
DeclareOperation( "SpecifyElmNamePrefix", [ IsCollection, IsString ] );
DeclareSynonym( "SetQuasigroupElmName", SpecifyElmNamePrefix );
DeclareSynonym( "SetLoopElmName", SpecifyElmNamePrefix );
DeclareOperation( "BindElmNames", [ IsMagma ] );
DeclareAttribute( "ConstructorFromTable", IsMagma );
DeclareOperation( "CanonicalCopy", [ IsMagma ] );
#############################################################################
## CREATING QUASIGROUPS AND LOOPS FROM A FILE
## -------------------------------------------------------------------------
DeclareOperation( "QuasigroupFromFile", [ IsString, IsString ] );
DeclareOperation( "LoopFromFile", [ IsString, IsString ] );
#############################################################################
## CREATING QUASIGROUPS AND LOOPS BY SECTIONS
## -------------------------------------------------------------------------
DeclareGlobalFunction("CayleyTableByPerms");
DeclareOperation( "QuasigroupByLeftSection", [ IsPermCollection ] );
DeclareOperation( "LoopByLeftSection", [ IsPermCollection ] );
DeclareOperation( "QuasigroupByRightSection", [ IsPermCollection ] );
DeclareOperation( "LoopByRightSection", [ IsPermCollection ] );
DeclareOperation( "QuasigroupByRightFolder", [ IsGroup, IsGroup, IsMultiplicativeElementCollection ] );
DeclareOperation( "LoopByRightFolder", [ IsGroup, IsGroup, IsMultiplicativeElementCollection ] );
#############################################################################
## CONVERSIONS
## -------------------------------------------------------------------------
DeclareOperation( "IntoQuasigroup", [ IsMagma ] );
DeclareOperation( "PrincipalLoopIsotope",
[ IsQuasigroup, IsQuasigroupElement, IsQuasigroupElement ] );
DeclareOperation( "IntoLoop", [ IsMagma ] );
DeclareOperation( "IntoGroup", [ IsMagma ] );
#############################################################################
## PRODUCTS OF QUASIGROUPS AND LOOPS
## --------------------------------------------------------------------------
DeclareGlobalFunction("ProductTableOfCanonicalCayleyTables");
#DirectProduct already declared for groups.
#############################################################################
## OPPOSITE QUASIGROUPS AND LOOPS
## --------------------------------------------------------------------------
DeclareGlobalFunction( "OppositeQuasigroup");
DeclareGlobalFunction( "OppositeLoop");
DeclareAttribute( "Opposite", IsMagma );
#############################################################################
## AUXILIARY
## --------------------------------------------------------------------------
DeclareGlobalFunction( "LOOPS_ReadCayleyTableFromFile" );
DeclareGlobalFunction( "LOOPS_CayleyTableByRightFolder" );