# byconj.gi RAQ Implementation of quandles by conjugation 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); ConjugatorType@ := obj -> ConjugatorFamily(FamilyObj(obj))!.ConjType; InstallMethod(ConjugatorObj, "for a mult element that allows quotients (and should be assoc)", [IsMultiplicativeElement and IsLeftQuotientElement and IsRightQuotientElement], obj -> Objectify(ConjugatorType@(obj), Immutable(obj)) ); # Even though IsMultiplicativeElementWithInverse implies both # IsLeftQuotientElement and IsRightQuotientElement, GAP doesn't seem to # calculate these implications on built-in elements. So we need to repeat the # method for IsMultiplicativeElementWithInverse, which is true of built-ins, # particularly permutations, which serve as a common representation of group # elements. InstallMethod(ConjugatorObj, "for a mult element with inverse (and should be assoc)", [IsMultiplicativeElementWithInverse], obj -> Objectify(ConjugatorType@(obj), [Immutable(obj)]) ); ## Printing and viewing InstallMethod(String, "for conjugator objects", [IsDefaultConjugatorObject], obj -> Concatenation("ConjugatorObj( ", String(obj![1]), " )") ); InstallMethod(ViewString, "for conjugator objects", [IsDefaultConjugatorObject], obj -> Concatenation("^", ViewString(obj![1]), ":") ); InstallMethod(UnderlyingMultiplicativeElement, "for a conjugator object", [IsDefaultConjugatorObject], obj -> obj![1] ); InstallMethod( \=, "for two conjugator objects", IsIdenticalObj, [IsDefaultConjugatorObject, IsDefaultConjugatorObject], function(l,r) return l![1] = r![1]; end ); InstallMethod( \<, "for two conjugator objects", IsIdenticalObj, [IsDefaultConjugatorObject, IsDefaultConjugatorObject], function(l,r) return l![1] < r![1]; end ); InstallMethod( \*, "for two conjugator objects", IsIdenticalObj, [IsDefaultConjugatorObject, IsDefaultConjugatorObject], function(l,r) return LeftQuotient(l![1],r![1])*l![1]; end ); InstallOtherMethod(LeftQuotient, "for two conjugator objects", IsIdenticalObj, [IsDefaultConjugatorObject,IsDefaultConjugatorObject], function(l,r) return (l*r)/l; end ); InstallMethod(ConjugationQuandle, "for a group", [IsGroup and IsFinite], function(G) local fam, elts; fam := CollectionsFamily(ConjugatorFamily(ElementsFamily(FamilyObj(G)))); # Question: how do we easily/quickly determine a set of generators of # Conj(G) from a set of generators of G, so that we can handle infinite # conj-quandles here? elts := List(Elements(G), g -> ConjugatorObj(g) ); # What we would like to do is # return AsLeftQuandle[NC?](elts); # but that's NIY. return LeftQuandleNC(fam, elts); end);