From 42a5e826d9ba62fc4d4fec2ec3778df354743557 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Sun, 22 Oct 2017 18:23:45 +0200 Subject: [PATCH] general opposite construction --- gap/byconj.gd | 7 +- gap/byconj.gi | 27 ++++---- gap/structure.gd | 13 ++++ gap/structure.gi | 165 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+), 17 deletions(-) diff --git a/gap/byconj.gd b/gap/byconj.gd index 06e62d5..7cb81f6 100644 --- a/gap/byconj.gd +++ b/gap/byconj.gd @@ -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); diff --git a/gap/byconj.gi b/gap/byconj.gi index 0d75813..c75bdef 100644 --- a/gap/byconj.gi +++ b/gap/byconj.gi @@ -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 diff --git a/gap/structure.gd b/gap/structure.gd index 6d7d865..e205e4a 100644 --- a/gap/structure.gd +++ b/gap/structure.gd @@ -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 diff --git a/gap/structure.gi b/gap/structure.gi index 399467a..3029424 100644 --- a/gap/structure.gi +++ b/gap/structure.gi @@ -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);