general opposite construction
This commit is contained in:
parent
ccf0e6f8e3
commit
42a5e826d9
|
@ -2,12 +2,13 @@
|
||||||
|
|
||||||
# The following outline of defining c
|
# The following outline of defining c
|
||||||
|
|
||||||
DeclareCategory( "IsConjugatorObject",
|
DeclareCategory("IsConjugatorObject",
|
||||||
IsMultiplicativeElement and IsLeftQuotientElement and
|
IsMultiplicativeElement and IsLeftQuotientElement and
|
||||||
IsLSelfDistElement and IsIdempotent);
|
IsLSelfDistElement and IsIdempotent);
|
||||||
DeclareCategoryCollections("IsConjugatorObject");
|
DeclareCategoryCollections("IsConjugatorObject");
|
||||||
|
|
||||||
DeclareAttribute("ConjugatorFamily", IsFamily);
|
DeclareAttribute("ConjugatorFamily", IsFamily);
|
||||||
|
DeclareAttribure("ConjugatorType", IsFamily);
|
||||||
|
|
||||||
DeclareSynonym("IsDefaultConjugatorObject",
|
DeclareSynonym("IsDefaultConjugatorObject",
|
||||||
IsConjugatorObject and IsPositionalObjectOneSlotRep);
|
IsConjugatorObject and IsPositionalObjectOneSlotRep);
|
||||||
|
|
|
@ -2,22 +2,21 @@
|
||||||
|
|
||||||
InstallMethod(ConjugatorFamily, "for a family",
|
InstallMethod(ConjugatorFamily, "for a family",
|
||||||
[IsFamily],
|
[IsFamily],
|
||||||
function(fam)
|
# Does GAP provide any way to get at the name of a family other than
|
||||||
local F;
|
# fam!.NAME ?
|
||||||
# Does GAP provide any way to get at the name of a family other than
|
fam -> NewFamily(Concatenation("ConjugatorFamily(", fam!.NAME, ")"),
|
||||||
# fam!.NAME ?
|
IsConjugatorObject)
|
||||||
F := NewFamily(Concatenation("ConjugatorFamily(", fam!.NAME, ")"),
|
);
|
||||||
IsConjugatorObject);
|
|
||||||
F!.ConjType := NewType(F, IsDefaultConjugatorObject);
|
|
||||||
return F;
|
|
||||||
end);
|
|
||||||
|
|
||||||
ConjugatorType@ := obj -> ConjugatorFamily(FamilyObj(obj))!.ConjType;
|
InstallMethod(ConjugatorType, "for a family",
|
||||||
|
[IsFamily],
|
||||||
|
fam -> NewType(ConjugatorFamily(fam), IsDefaultConjugatorObject)
|
||||||
|
);
|
||||||
|
|
||||||
InstallMethod(ConjugatorObj,
|
InstallMethod(ConjugatorObj,
|
||||||
"for a mult element that allows quotients (and should be assoc)",
|
"for a mult element that allows quotients (and should be assoc)",
|
||||||
[IsMultiplicativeElementWithInverse],
|
[IsMultiplicativeElementWithInverse],
|
||||||
obj -> Objectify(ConjugatorType@(obj), [Immutable(obj)])
|
obj -> Objectify(ConjugatorType(FamilyObj(obj)), [Immutable(obj)])
|
||||||
);
|
);
|
||||||
|
|
||||||
## Printing and viewing
|
## Printing and viewing
|
||||||
|
@ -36,19 +35,19 @@ InstallMethod(UnderlyingMultiplicativeElement, "for a conjugator object",
|
||||||
obj -> obj![1]
|
obj -> obj![1]
|
||||||
);
|
);
|
||||||
|
|
||||||
InstallMethod( \=, "for two conjugator objects",
|
InstallMethod(\=, "for two conjugator objects",
|
||||||
IsIdenticalObj,
|
IsIdenticalObj,
|
||||||
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
|
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
|
||||||
function(l,r) return l![1] = r![1]; end
|
function(l,r) return l![1] = r![1]; end
|
||||||
);
|
);
|
||||||
|
|
||||||
InstallMethod( \<, "for two conjugator objects",
|
InstallMethod(\<, "for two conjugator objects",
|
||||||
IsIdenticalObj,
|
IsIdenticalObj,
|
||||||
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
|
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
|
||||||
function(l,r) return l![1] < r![1]; end
|
function(l,r) return l![1] < r![1]; end
|
||||||
);
|
);
|
||||||
|
|
||||||
InstallMethod( \*, "for two conjugator objects",
|
InstallMethod(\*, "for two conjugator objects",
|
||||||
IsIdenticalObj,
|
IsIdenticalObj,
|
||||||
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
|
[IsDefaultConjugatorObject, IsDefaultConjugatorObject],
|
||||||
function(l,r) return ConjugatorObj(LeftQuotient(l![1],r![1])*l![1]); end
|
function(l,r) return ConjugatorObj(LeftQuotient(l![1],r![1])*l![1]); end
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
## GAP Categories and representations
|
## GAP Categories and representations
|
||||||
|
|
||||||
|
## Info class for RAQ
|
||||||
|
DeclareInfoClass("InfoRAQ");
|
||||||
|
|
||||||
## Self-distributivity
|
## Self-distributivity
|
||||||
# Note these are properties that can and therefore should be defined just at
|
# Note these are properties that can and therefore should be defined just at
|
||||||
# the level of MultiplicativeElements and Magmas, hence although the LOOPS
|
# the level of MultiplicativeElements and Magmas, hence although the LOOPS
|
||||||
|
@ -67,6 +70,16 @@ DeclareGlobalFunction("RightQuandleNC");
|
||||||
# Underlying operation
|
# Underlying operation
|
||||||
DeclareGlobalFunction("CloneOfTypeByGenerators");
|
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
|
# Attributes for the generators
|
||||||
|
|
||||||
# Generates the structure by \* and LeftQuotient. Note that for finite
|
# Generates the structure by \* and LeftQuotient. Note that for finite
|
||||||
|
|
165
gap/structure.gi
165
gap/structure.gi
|
@ -303,3 +303,168 @@ InstallMethod(ViewString, "for a right quasigroup with generators",
|
||||||
String(Size(GeneratorsOfRightQuasigroup(Q))),
|
String(Size(GeneratorsOfRightQuasigroup(Q))),
|
||||||
" generators>"));
|
" 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);
|
||||||
|
|
Loading…
Reference in New Issue