commit 92a7bff629e23b89ca3a576a1015ae5d4a751940 Author: Glen Whitney Date: Wed Oct 18 12:46:13 2017 +0200 Initial commit: enough to create a left quasigroup from a multiplication table and do left division therein diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 0000000..8eb9882 --- /dev/null +++ b/COPYING.txt @@ -0,0 +1,3 @@ +Code in this package is made available under whatever terms preferred by +Leandro Vendramin and Matias Graña, the authors of the RIG package on which it +is (more or less) based. diff --git a/PackageInfo.g b/PackageInfo.g new file mode 100644 index 0000000..0522b59 --- /dev/null +++ b/PackageInfo.g @@ -0,0 +1,93 @@ +SetPackageInfo( rec( +PackageName := "raq", +Subtitle := "Racks And Quandles in GAP", +Version := "0.1.0", +Date := "2017-Oct-17", +ArchiveURL := "", +ArchiveFormats := "-win.zip .tar.gz", + +Persons := [ + rec( + LastName := "Whitney", + FirstNames := "Glen", + IsAuthor := true, + IsMaintainer := true, + Email := "gwhitney@post.harvard.edu", + WWWHome := "http://mathwalks.org", + PostalAddress := Concatenation( [ + "523 Rialto Ave.\n", + "Venice, CA 90291\n", + "USA" ] ), + Place := "Venice", + Institution := "mathwalks.org" + ), + rec( + LastName := "Vendramin", + FirstNames := "Leandro", + IsAuthor := true, + IsMaintainer := false, + Email := "lvendramin@dm.uba.ar", + WWWHome := "http://mate.dm.uba.ar/~lvendram/", + PostalAddress := Concatenation( [ + "Departamento de matemática, FCEyN, UBA", + "Ciudad Universitaria, Pab. 1,\n", + "Buenos Aires, Argentina" ] ), + Place := "Buenos Aires", + Institution := "UBA" + ) +], + +## Status information. Currently the following cases are recognized: +## "accepted" for successfully refereed packages +## "deposited" for packages for which the GAP developers agreed +## to distribute them with the core GAP system +## "dev" for development versions of packages +## "other" for all other packages +## +Status := "dev", + +README_URL := + "", +PackageInfoURL := + "", + +AbstractHTML := Concatenation( + "The RAQ package provides researchers ", + "with means of representing and computing with general one-sided ", + "quasigroups, but more more particularly with racks and quandles. ", + "This package builds on fundamentals of non-associated algebra ", + "established in the LOOPS package, and ", + "and provides enhanced functionality, libraries, and implementations ", + "as compared to the earlier RIG package ", + "on which RAQ is loosely modeled." + ), + +PackageWWWHome := "", + +PackageDoc := rec( + BookName := "raq", + ArchiveURLSubset := ["doc", "htm"], + HTMLStart := "doc/chap0.html", + PDFFile := "doc/manual.pdf", + SixFile := "doc/manual.six", + LongTitle := "The RAQ Package: Racks And Quandles in GAP", + Autoload := true # only for the documentation, TEMPORARILY TURNED OFF +), + + +Dependencies := rec( + GAP := ">=4.4", + NeededOtherPackages := [["loops","3.3.0"]], + SuggestedOtherPackages := [], + ExternalConditions := [] +), + +AvailabilityTest := ReturnTrue, +BannerString := Concatenation("--\nRAQ, Racks And Quandles in GAP, Version ", + ~.Version, ".\n--\n"), + +Autoload := false, # false for deposited packages +TestFile := "tst/testall.g", +Keywords := ["quasigroup", "self-distributive", "rack", "quandle", + "nichols algebra", "knots"] +)); diff --git a/gap/structure.gd b/gap/structure.gd new file mode 100644 index 0000000..4332b73 --- /dev/null +++ b/gap/structure.gd @@ -0,0 +1,82 @@ +## structure.gd RAQ Definitions, representations, and elementary operations. + +## GAP Categories and representations + +## Self-distributivity +# Note these are properties that should be defined just at the level of +# MultiplicativeElements and Magmas, hence although the LOOPS package defines +# IsLDistributive and IsRDistributive for quasigroups, they would be ambiguous +# in the case of something like a semiring whose multiplicative structure was +# a quasigroup (cf. https://arxiv.org/abs/0910.4760). Hence, we implement them +# in RAQ with new, non-conflicting terms. + +# An element that knows that multiplication in its family is left +# self-distributive: +DeclareCategory("IsLSelfDistElement", IsMultiplicativeElement); +DeclareCategoryCollections("IsLSelfDistElement"); + +# An element that knows that multiplication in its family is right +# self-distributive: +DeclareCategory("IsRSelfDistElement", IsMultiplicativeElement); +DeclareCategoryCollections("IsRSelfDistElement"); + +# Left self-distributive magmas: +DeclareProperty("IsLSelfDistributive", IsMagma); +InstallTrueMethod(IsLSelfDistributive, + IsMagma and IsLSelfDistElementCollection); + +# Right self-distributive magmas: +DeclareProperty("IsRSelfDistributive", IsMagma); +InstallTrueMethod(IsRSelfDistributive, + IsMagma and IsRSelfDistElementCollection); + +# Left and right racks +DeclareSynonym("IsLeftRack", IsLeftQuasigroup and IsLSelfDistributive); +DeclareSynonym("IsRightRack", IsRightQuasigroup and IsRSelfDistributive); + +## One-sided quasigroups + +# Returns the closure of under * and LeftQuotient; +# the family of elements of M may be specified, and must be if +# is empty (in which case M will be empty as well). +DeclareGlobalFunction("LeftQuasigroup"); +DeclareGlobalFunction("RightQuasigroup"); +DeclareGlobalFunction("LeftRack"); +DeclareGlobalFunction("RightRack"); + +# Underlying operation +DeclareOperation("CloneOfTypeByGenerators", + [IsFilter, IsFamily, IsCollection, IsAttribute]); + +# Attributes for the generators + +# Generates the structure by \* and LeftQuotient. Note that for finite +# structures, these are the same as the GeneratorsOfMagma but in general more +# elements might be required to generate the structure just under * +DeclareAttribute("GeneratorsOfLeftQuasigroup", IsLeftQuasigroup); +InstallImmediateMethod(GeneratorsOfMagma, + "finite left quasigroups *-generated by left quasigroup generators", + IsLeftQuasigroup and IsFinite, + q -> GeneratorsOfLeftQuasigroup(q) +); + +# Generates the structure by \* and \/, same considerations as above +DeclareAttribute("GeneratorsOfRightQuasigroup", IsRightQuasigroup); +InstallImmediateMethod(GeneratorsOfMagma, + "finite right quasigroups *-generated by right quasigroup generators", + IsRightQuasigroup and IsFinite, + q -> GeneratorsOfRightQuasigroup(q) +); + +## And now, build them from multiplication tables +# Need attributes on the families to store the sections and division tables +DeclareAttribute("LeftSectionList", IsFamily and HasMultiplicationTable); +DeclareAttribute("RightSectionList", IsFamily and HasMultiplicationTable); +DeclareAttribute("LeftDivisionTable", IsFamily and HasMultiplicationTable); +DeclareAttribute("RightDivisionTable", IsFamily and HasMultiplicationTable); + +# And the builders +DeclareGlobalFunction("LeftQuasigroupByMultiplicationTable"); +DeclareGlobalFunction("LeftRackByMultiplicationTable"); +DeclareGlobalFunction("RightQuasigroupByMultiplicationTable"); +DeclareGlobalFunction("RightRackByMultiplicationTable"); diff --git a/gap/structure.gi b/gap/structure.gi new file mode 100644 index 0000000..f99e830 --- /dev/null +++ b/gap/structure.gi @@ -0,0 +1,134 @@ +## structure.gi RAQ Implementation of definitiions, reps, and elt operations + +## Create structures with generators +InstallMethod(CloneOfTypeByGenerators, + "for generic category of magma, family, collection, gen attrib", + [IsFilter, IsFamily, IsCollection, IsAttribute], + function(cat, fam, gens, genAttrib) + local M; + if not(IsEmpty(gens) or IsIdenticalObj(FamilyObj(gens), fam)) then + Error(" and family of do not match"); + fi; + M := Objectify(NewType( fam, cat and IsAttributeStoringRep), rec()); + Setter(genAttrib)(M, AsList(gens)); + return M; +end); + +## Functions for each of the magma categories here +InstallGlobalFunction(LeftQuasigroup, function(arg) + local fam; + if Length(arg) = 0 then + Error("usage: LeftQuasigroup([], )"); + fi; + # Extract the family + if IsFamily(arg[1]) then + fam = arg[1]; + Remove(arg, 1); + arg = Flat(arg); + else + arg = Flat(arg); + fam = FamilyObj(arg[1]); + fi; + return CloneOfTypeByGenerators(IsLeftQuasigroup, fam, arg, + GeneratorsOfLeftQuasigroup); +end); + +InstallGlobalFunction(LeftRack, function(arg) + local fam; + if Length(arg) = 0 then + Error("usage: LeftRack([], )"); + fi; + # Extract the family + if IsFamily(arg[1]) then + fam = arg[1]; + Remove(arg, 1); + arg = Flat(arg); + else + arg = Flat(arg); + fam = FamilyObj(arg[1]); + fi; + return CloneOfTypeByGenerators(IsLeftRack, fam, arg, + GeneratorsOfLeftQuasigroup); +end); + +InstallGlobalFunction(RightQuasigroup, function(arg) + local fam; + if Length(arg) = 0 then + Error("usage: RightQuasigroup([], )"); + fi; + # Extract the family + if IsFamily(arg[1]) then + fam = arg[1]; + Remove(arg, 1); + arg = Flat(arg); + else + arg = Flat(arg); + fam = FamilyObj(arg[1]); + fi; + return CloneOfTypeByGenerators(IsRightQuasigroup, fam, arg, + GeneratorsOfRightQuasigroup); +end); + +InstallGlobalFunction(RightRack, function(arg) + local fam; + if Length(arg) = 0 then + Error("usage: RightRack([], )"); + fi; + # Extract the family + if IsFamily(arg[1]) then + fam = arg[1]; + Remove(arg, 1); + arg = Flat(arg); + else + arg = Flat(arg); + fam = FamilyObj(arg[1]); + fi; + return CloneOfTypeByGenerators(IsRightRack, fam, arg, + GeneratorsOfRightQuasigroup); +end); + +## And now create them from multiplication tables +InstallGlobalFunction(LeftQuasigroupByMultiplicationTable, + function(T) + if not IsLeftQuasigroupTable(T) then + Error("Multiplication table must have each row a permutation of ", + "the same entries."); + fi; + return MagmaByMultiplicationTableCreatorNC( + CanonicalCayleyTableOfLeftQuasigroupTable(T), + LeftQuasigroup, + IsLeftQuotientElement and IsMagmaByMultiplicationTableObj + ); +end); + +## And define the operation + +InstallOtherMethod(LeftQuotient, + "for two elts in magma by mult table, when left has left quotients", + IsIdenticalObj, + [IsLeftQuotientElement, IsMagmaByMultiplicationTableObj], + function (l,r) + return DivisionTable(FamilyObj(l))[l![1],r![1]]; +end); + +## Create division tables as needed +InstallMethod(LeftDivisionTable, + "for a family with a multiplication table", + [IsFamily and HasMultiplicationTable], + function(fam) + local LS, n; + LS := LeftSectionList(fam); + n := Size(T); + return List(T, x->ListPerm(Inverse(x), n)); +end); + +## Create section lists as needed +InstallMethod(LeftSectionList, + "for a family with a multiplication table", + [IsFamily and HasMultiplicationTable], + function(fam) + return List(MultiplicationTable(fam), x->PermList(x)); +end); + + + diff --git a/init.g b/init.g new file mode 100644 index 0000000..751d185 --- /dev/null +++ b/init.g @@ -0,0 +1,4 @@ +## init.g RAQ + +# Definitions, representations, and elementary operations. +ReadPackage("raq", "gap/structure.gd"); diff --git a/read.g b/read.g new file mode 100644 index 0000000..338c186 --- /dev/null +++ b/read.g @@ -0,0 +1,4 @@ +## read.g RAQ + +# Definitions, representations, and elementary operations. +ReadPackage("raq", "gap/structure.gi");