# byconj.gi RAQ Implementation of quandles by conjugation InstallMethod(ConjugatorFamily, "for a family", [IsFamily], # Does GAP provide any way to get at the name of a family other than # fam!.NAME ? fam -> NewFamily(Concatenation("ConjugatorFamily(", fam!.NAME, ")"), IsConjugatorObject) ); 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(FamilyObj(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 ConjugatorObj(LeftQuotient(l![1],r![1])*l![1]); end ); InstallOtherMethod(LeftQuotient, "for two conjugator objects", IsIdenticalObj, [IsDefaultConjugatorObject,IsDefaultConjugatorObject], function(l,r) return ConjugatorObj((l![1]*r![1])/l![1]); end ); InstallMethod(ConjugationQuandle, "for a group", [IsGroup and IsFinite], function(G) local fam, elts, Q; fam := CollectionsFamily(ConjugatorFamily(ElementsFamily(FamilyObj(G)))); # Question: how do we feasibly 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. Q := LeftQuandleNC(fam, elts); # We know that elts was actually closed under * and LeftQuotient, and # since we are in a method only for finite groups, ergo Q is finite: SetIsFinite(Q, true); return Q; end); ## Methods that are easier in conjugator quandles: InstallMethod(GeneratorsOfMagma, "for a quandle generated by conjugator objects", [IsLeftQuasigroup and HasGeneratorsOfLeftQuasigroup and IsConjugatorObjectCollection], function(Q) local gens, invgens; # idea: ^g^-1: * ^h: = ^g: \ ^h:, so the generators of the quasigroup # together with their inverses generate the quandle as a magma. gens := GeneratorsOfLeftQuasigroup(Q); invgens := Set(gens, g -> ConjugatorObj(Inverse(g![1]))); UniteSet(invgens, gens); return invgens; end);