general opposite construction

This commit is contained in:
Glen Whitney 2017-10-22 18:23:45 +02:00
parent ccf0e6f8e3
commit 42a5e826d9
4 changed files with 195 additions and 17 deletions

View File

@ -2,12 +2,13 @@
# The following outline of defining c
DeclareCategory( "IsConjugatorObject",
IsMultiplicativeElement and IsLeftQuotientElement and
IsLSelfDistElement and IsIdempotent);
DeclareCategory("IsConjugatorObject",
IsMultiplicativeElement and IsLeftQuotientElement and
IsLSelfDistElement and IsIdempotent);
DeclareCategoryCollections("IsConjugatorObject");
DeclareAttribute("ConjugatorFamily", IsFamily);
DeclareAttribure("ConjugatorType", IsFamily);
DeclareSynonym("IsDefaultConjugatorObject",
IsConjugatorObject and IsPositionalObjectOneSlotRep);

View File

@ -2,22 +2,21 @@
InstallMethod(ConjugatorFamily, "for a family",
[IsFamily],
function(fam)
local F;
# Does GAP provide any way to get at the name of a family other than
# fam!.NAME ?
F := NewFamily(Concatenation("ConjugatorFamily(", fam!.NAME, ")"),
IsConjugatorObject);
F!.ConjType := NewType(F, IsDefaultConjugatorObject);
return F;
end);
# Does GAP provide any way to get at the name of a family other than
# fam!.NAME ?
fam -> NewFamily(Concatenation("ConjugatorFamily(", fam!.NAME, ")"),
IsConjugatorObject)
);
ConjugatorType@ := obj -> ConjugatorFamily(FamilyObj(obj))!.ConjType;
InstallMethod(ConjugatorType, "for a family",
[IsFamily],
fam -> NewType(ConjugatorFamily(fam), IsDefaultConjugatorObject)
);
InstallMethod(ConjugatorObj,
"for a mult element that allows quotients (and should be assoc)",
[IsMultiplicativeElementWithInverse],
obj -> Objectify(ConjugatorType@(obj), [Immutable(obj)])
obj -> Objectify(ConjugatorType(FamilyObj(obj)), [Immutable(obj)])
);
## Printing and viewing
@ -36,19 +35,19 @@ InstallMethod(UnderlyingMultiplicativeElement, "for a conjugator object",
obj -> obj![1]
);
InstallMethod( \=, "for two conjugator objects",
InstallMethod(\=, "for two conjugator objects",
IsIdenticalObj,
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
function(l,r) return l![1] = r![1]; end
);
InstallMethod( \<, "for two conjugator objects",
InstallMethod(\<, "for two conjugator objects",
IsIdenticalObj,
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
function(l,r) return l![1] < r![1]; end
);
InstallMethod( \*, "for two conjugator objects",
InstallMethod(\*, "for two conjugator objects",
IsIdenticalObj,
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
function(l,r) return ConjugatorObj(LeftQuotient(l![1],r![1])*l![1]); end

View File

@ -2,6 +2,9 @@
## GAP Categories and representations
## Info class for RAQ
DeclareInfoClass("InfoRAQ");
## Self-distributivity
# Note these are properties that can and therefore should be defined just at
# the level of MultiplicativeElements and Magmas, hence although the LOOPS
@ -67,6 +70,16 @@ DeclareGlobalFunction("RightQuandleNC");
# Underlying operation
DeclareGlobalFunction("CloneOfTypeByGenerators");
## Opposite structures
DeclareCategory("IsOppositeObject", IsMultiplicativeElement);
DeclareCategoryCollections("IsOppositeObject");
DeclareAttribute("OppositeFamily", IsFamily);
DeclareAttribute("OppositeType", IsFamily);
DeclareSynonym("IsDefaultOppositeObject",
IsOppositeObject and IsPositionalObjectOneSlotRep);
DeclareAttribute("OppositeObj", IsMultiplicativeElement);
DeclareAttribute("UnderlyingMultiplicativeElement", IsOppositeObject);
# Attributes for the generators
# Generates the structure by \* and LeftQuotient. Note that for finite

View File

@ -303,3 +303,168 @@ InstallMethod(ViewString, "for a right quasigroup with generators",
String(Size(GeneratorsOfRightQuasigroup(Q))),
" generators>"));
## Opposite structures
OFDir@ := NewDictionary("strings", true);
# What property does the Opposite family have for each property of the
# underlying elements? (or fail if there is no implied property)
AddDictionary(OFDir@, "CanEasilyCompareElements", CanEasilyCompareElements);
AddDictionary(OFDir@, "CanEasilySortElements", CanEasilySortElements);
AddDictionary(OFDir@, "IsAdditiveElement", fail);
AddDictionary(OFDir@, "IsAdditivelyCommutativeElement", fail);
AddDictionary(OFDir@, "IsAssociativeElement", IsAssociativeElement);
AddDictionary(OFDir@, "IsCommutativeElement", IsCommutativeElement);
AddDictionary(OFDir@, "IsCyc", fail);
AddDictionary(OFDir@, "IsCyclotomic", fail);
AddDictionary(OFDir@, "IsExtAElement", fail);
AddDictionary(OFDir@, "IsExtLElement", IsExtRElement);
AddDictionary(OFDir@, "IsExtRElement", IsExtLElement);
AddDictionary(OFDir@, "IsInt", fail);
AddDictionary(OFDir@, "IsLeftQuotientElement", IsRightQuotientElement);
AddDictionary(OFDir@, "IsLSelfDistElement", IsRSelfDistElement);
AddDictionary(OFDir@, "IsMultiplicativeElement", fail);
AddDictionary(OFDir@, "IsMultiplicativeElementWithInverse",
IsMultiplicativeElementWithInverse);
AddDictionary(OFDir@, "IsMultiplicativeElementWithOne",
IsMultiplicativeElementWithOne);
AddDictionary(OFDir@, "IsNearAdditiveElement", fail);
AddDictionary(OFDir@, "IsNearAdditiveElementWithInverse", fail);
AddDictionary(OFDir@, "IsNearAdditiveElementWithZero", fail);
AddDictionary(OFDir@, "IsPosRat", fail);
AddDictionary(OFDir@, "IsRat", fail);
AddDictionary(OFDir@, "IsRightQuotientElement", IsLeftQuotientElement);
AddDictionary(OFDir@, "IsRSelfDistElement", IsLSelfDistElement);
AddDictionary(OFDir@, "IsZDFRE", fail);
InstallMethod(OppositeFamily, "for a family",
[IsFamily],
function(fam)
local F, elt, elt_props, opp_props, prop, filt, opp_filt;
elt := Representative(fam);
elt_props := CategoriesOfObject(elt);
Append(elt_props(KnownTruePropertiesOfObject(elt)));
opp_props := [];
for prop in elt_props do
if KnowsDictionary(OFDir@, prop) then
filt := LookupDictionary(OFDir@, prop);
if filt <> fail then Add(opp_props, filt); fi;
else
Info(InfoRAQ, 0,
"Note: RAQ unfamiliar with element property ", prop,
", ignoring.");
fi;
od;
opp_filt := IsMultiplicativeElement;
for filt in opp_props do opp_filt := opp_filt and filt; od;
return NewFamily(Concatenation("OppositeFamily(", fam!.NAME, ")"),
IsOppositeObject, opp_filt);
end);
InstallMethod(OppositeType, "for a family",
[IsFamily],
fam -> NewType(OppositeFamily(fam), IsDefaultOppositeObject)
);
InstallMethod(OppositeObj, "for a multiplicative element",
[IsMultiplicativeElement],
function (obj)
local fam;
fam := FamilyObj(obj);
SetRepresentative(fam, obj);
return Objectify(OppositeType(fam), [Immutable(obj)]);
end);
InstallMethod(OppositeObj, "for a commutative element",
[IsMultiplicativeElement and IsCommutativeElement],
IdFunc
);
InstallMethod(UnderlyingMultiplicativeElement, "for a default opposite obj",
[IsDefaultOppositeObject],
obj -> obj![1]
);
## Printing and viewing opposite objects
InstallMethod(String, "for opposite objects",
[IsDefaultOppositeObject],
obj -> Concatenation("OppositeObj( ", String(obj![1]), " )")
);
InstallMethod(ViewString, "for opposite objects",
[IsDefaultOppositeObject],
obj -> Concatenation("o", ViewString(obj![1]))
);
InstallMethod(\=, "for two opposite objects",
IsIdenticalObj,
[IsDefaultOppositeObject, IsDefaultOppositeObject],
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
function(l,r) return l![1] = r![1]; end
);
InstallMethod(\<, "for two opposite objects",
IsIdenticalObj,
[IsDefaultOppositeObject, IsDefaultOppositeObject],
function(l,r) return l![1] < r![1]; end
);
InstallMethod(\*, "for two opposite objects",
IsIdenticalObj,
[IsDefaultOppositeObject, IsDefaultOppositeObject],
function(l,r) return OppositeObj(r![1]*l![1]); end
);
InstallMethod(LeftQuotient, "for two opposite objects",
IsIdenticalObj,
[IsDefaultOppositeObject and IsLeftQuotientElement, IsDefaultOppositeObject],
function(l,r) return OppositeObj(r![1]/l![1]); end
);
InstallMethod(\/, "for two opposite objects",
IsIdenticalObj,
[IsDefaultOppositeObject, IsDefaultOppositeObject and IsRightQuotientElement],
function(l,r) return OppositeObj(LeftQuotient(r![1], l![1])); end
);
InstallMethod(OneOp, "for an opposite object",
[IsDefaultOppositeObject and IsMultiplicativeElementWithOne],
ob -> OppositeObj(One(ob![1]))
);
InstallMethod(InverseOp, "for an opposite object",
[IsDefaultOppositeObject and IsMultiplicativeElementWithInverse],
ob -> OppositeObj(Inverse(ob![1]))
);
# Now the many Opposite implementations. How can we cut this down?
InstallMethod(Opposite, "for a commutative magma",
[IsMagma and IsCommutative],
IdFunc
);
InstallMethod(Opposite, "for a finitely generated magma",
[IsMagma and HasGeneratorsOfMagma],
function(M)
local fam, elts;
fam := CollectionsFamily(OppositeFamily(ElementsFamily(FamilyObj(M))));
elts := List(GeneratorsOfMagma(M), m -> OppositeObj(m));
return Magma(fam, elts);
end);
InstallMethod(Opposite, "for a finitely generated magma with one",
[IsMagmaWithOne and HasGeneratorsOfMagmaWithOne],
function(M)
local fam, elts;
fam := CollectionsFamily(OppositeFamily(ElementsFamily(FamilyObj(M))));
elts := List(GeneratorsOfMagmaWithOne(M), m -> OppositeObj(m));
return MagmaWithOne(fam, elts);
end);
InstallMethod(Opposite, "for a finitely generated magma with inverse",
[IsMagmaWithInverse and HasGeneratorsOfMagmaWithInverse],
function(M)
local fam, elts;
fam := CollectionsFamily(OppositeFamily(ElementsFamily(FamilyObj(M))));
elts := List(GeneratorsOfMagmaWithInverse(M), m -> OppositeObj(m));
return MagmaWithInverse(fam, elts);
end);