diff --git a/README.md b/README.md index 578164f..cca8250 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ Perhaps the following &GAP; interactive session, which constructs the conjugation quandle of the symmetric group on three elements and then performs a few simple computations on that quandle, will give the flavor of &RAQ;. (It is presumed that the &RAQ; package has already been loaded with -`LoadPackage("RAQ");` prior to these example commands being executed.) +`LoadPackage("RAQ");` prior to these example commands being executed, and that +remains true throughout the package documentation.) ``` gap> S3 := SymmetricGroup(3); diff --git a/doc/chapters.autodoc b/doc/chapters.autodoc index 6f45f98..d2618fe 100644 --- a/doc/chapters.autodoc +++ b/doc/chapters.autodoc @@ -1,11 +1,29 @@ @Chapter construct @ChapterTitle Constructing One-Sided Quasigroups, Racks, and Quandles. +@Section from_scratch +@SectionTitle Direct constructors + All of the functions in this section produce magmas (of one of the + categories with which &RAQ; is concerned) from data of other (non-domain) + types. @Chapter operate @ChapterTitle Operations on One-Sided Quasigroups, Racks, and Quandles. @Chapter basic @ChapterTitle Basic Notions + In order to build up and define one-sided quasigroups, racks, and + quandles, &RAQ; must define several lower-level objects and properties, + which are documented in this section. Although logically they come before + the domain constructors and operations, they are presented afterwards + because it's rare that one needs to use them directly when working with + &RAQ;. +@Section elements +@SectionTitle Categories of elements +@Section collections +@SectionTitle Categories of collections @Chapter technical + This chapter covers computational/operational aspects of &RAQ; + rather than mathematical ones. + @ChapterTitle Technical Details diff --git a/doc/makedoc.g b/doc/makedoc.g index ac66d4d..d376d73 100644 --- a/doc/makedoc.g +++ b/doc/makedoc.g @@ -3,7 +3,11 @@ LoadPackage("AutoDoc"); AutoDoc(rec( - autodoc := rec(files := ["README.md", "doc/chapters.autodoc"]), - maketest := rec(name := "tst/AutoDoc_tests.g") + autodoc := rec(files := ["README.md", "doc/chapters.autodoc"]), + maketest := rec(name := "tst/AutoDoc_tests.g") )); -QUIT; + +if not IsBound(RAQ_makedoc_no_quit) or + not RAQ_makedoc_no_quit then + QUIT_GAP(); +fi; diff --git a/lib/bytable.gd b/lib/bytable.gd index b4a7946..54f68be 100644 --- a/lib/bytable.gd +++ b/lib/bytable.gd @@ -1,43 +1,192 @@ ## bytable.gd RAQ Quasigroups, racks, and quandles by multiplication tables. -## Self-distributivity -# Predicates on tables: +#! @Chapter basic +#! @Section table_predicates +#! @SectionTitle Predicates on multiplication tables +#! @Arguments matrix +#! @Description This property is true if matrix is the multiplication +#! table of a magma which satisfies the left self-distributive property (see +#! )) +#! for all triples of elements. DeclareProperty( "IsLeftSelfDistributiveTable", IsMatrix ); +#! @Arguments matrix +#! @Description This property is true if matrix is the multiplication +#! table of a magma which satisfies the rightt self-distributive property (see +#! )) +#! for all triples of elements. DeclareProperty( "IsRightSelfDistributiveTable", IsMatrix ); +#! @Arguments matrix +#! @Description This property is true if for all $i$ less than or equal to the +#! number of rows of matrix, the $(i,i)$ entry of matrix is +#! $i$. DeclareProperty( "IsElementwiseIdempotentTable", IsMatrix ); -## Attributes (typically used on the families of elements created from a -## multiplication table) to store sections and division tables +#! @Chapter operate +#! @Section table +#! @Section Information related to the multiplication table. +#! Note that typically the functions in this section will fail unless the +#! argument was either created with a multiplication table, or at least has +#! had its multiplication table explicitly computed. +#! @Arguments obj +#! @Returns a list of permutations of length equal to `Size(obj)`, or fail +#! @Description The $i$th element of the list returned is the permutation +#! determined by the $i$th row of the multiplication table of +#! obj (in the sense of the core &GAP; +#! function `PermList`). Returns fail if any row of the multiplication table +#! does not determine a permuation. DeclareAttribute("LeftPerms", HasMultiplicationTable); -DeclareAttribute("RightPerms", HasMultiplicationTable); -DeclareAttribute("LeftDivisionTable", HasMultiplicationTable); -DeclareAttribute("RightDivisionTable", HasMultiplicationTable); +#! @BeginExampleSession +#! gap> D3 := LeftQuandleByMultiplicationTable([[1,3,2],[3,2,1],[2,1,3]]); +#! +#! gap> LeftPerms(D3); +#! [ (2,3), (1,3), (1,2) ] +#! @EndExampleSession -## Create Quasigroups and racks from multiplication tables +#! @Arguments obj +#! @Returns a list of permutations of length equal to `Size(obj)`, or fail +#! @Description The $i$th element of the list returned is the permutation +#! determined by the $i$th column of the multiplication table of +#! obj (in the sense of the core &GAP; +#! function `PermList`). Returns fail if any column of the multiplication table +#! does not determine a permuation. +DeclareAttribute("RightPerms", HasMultiplicationTable); +#! @Arguments obj +#! @Returns an operation table matrix, or fail +#! @Description Presuming it is well-defined, this produces the operation +#! table (following similar conventions for multiplication tables, e.g., +#! every entry is a natural number less than `Size(obj)`) for `LeftQuotient` +#! on the given obj. Returns fail if `LeftQuotient` is not +#! well-defined for obj. +DeclareAttribute("LeftDivisionTable", HasMultiplicationTable); +#! @Arguments obj +#! @Returns an operation table matrix, or fail +#! @Description Presuming it is well-defined, this produces the operation +#! table for `\/` (the typical elementwise (right) quotient) on the given +#! obj. Returns fail if `\/` is not +#! well-defined for obj. +DeclareAttribute("RightDivisionTable", HasMultiplicationTable); +#! @BeginExampleSession +#! gap> A4 := RightQuandleByMultiplicationTable([[1,4,2,3], +#! > [3,2,4,1], +#! > [4,1,3,2], +#! > [2,3,1,4]]); +#! +#! gap> RightDivisionTable(A4); +#! [ [ 1, 3, 4, 2 ], [ 4, 2, 1, 3 ], [ 2, 4, 3, 1 ], [ 3, 1, 2, 4 ] ] +#! @EndExampleSession +#! @Chapter construct +#! @Section from_scratch +#! @BeginGroup table_constructors +#! @GroupTitle Constructors from tables +#! @Returns a magma of the designated category +#! @Description These functions produce magmas from their multiplication +#! tables, exactly analogously with the core &GAP; function +#! `MagmaByMultiplicationTable` (q.v.); all of the same conventions are +#! followed, such as the table should be an $n\times n$ matrix in which +#! every entry is a natural number less than or equal to $n$. These +#! functions verify that the tables supplied in fact define an example of +#! the designated category. +#! @GroupInitialArguments table DeclareGlobalFunction("LeftQuasigroupByMultiplicationTable"); -DeclareGlobalFunction("LeftQuasigroupByMultiplicationTableNC"); DeclareGlobalFunction("LeftRackByMultiplicationTable"); -DeclareGlobalFunction("LeftRackByMultiplicationTableNC"); DeclareGlobalFunction("LeftQuandleByMultiplicationTable"); -DeclareGlobalFunction("LeftQuandleByMultiplicationTableNC"); DeclareGlobalFunction("RightQuasigroupByMultiplicationTable"); -DeclareGlobalFunction("RightQuasigroupByMultiplicationTableNC"); DeclareGlobalFunction("RightRackByMultiplicationTable"); -DeclareGlobalFunction("RightRackByMultiplicationTableNC"); DeclareGlobalFunction("RightQuandleByMultiplicationTable"); +#! @EndGroup + +#! @BeginExampleSession +#! gap> D3 := LeftQuandleByMultiplicationTable([[1,3,2],[3,2,1],[2,1,3]]); +#! +#! gap> SpecifyElmNamePrefix(D3, "d"); +#! gap> Elements(D3); +#! [ d1, d2, d3 ] +#! gap> IsBound(d1); +#! false +#! gap> BindElmNames(D3); +#! gap> d1 * d2; +#! d3 +#! @EndExampleSession + +#! @BeginGroup unchecked_table_constructors +#! @GroupTitle Unchecked constructors from tables +#! @Returns a magma of the designated category +#! @Description Each of these functions is exactly like its counterpart +#! without the `NC` suffix, except that it does not perform any verification +#! that the supplied table in fact satisfies the necessary axioms for the +#! designated category. (The verification is skipped to save computation +#! time, for use in cases when the properties are known to hold.) Hence, use +#! with caution: the behavior of this +#! package if you supply a table which does not satisfy the appropiate +#! axioms is undefined. +#! @GroupInitialArguments table +DeclareGlobalFunction("LeftQuasigroupByMultiplicationTableNC"); +DeclareGlobalFunction("LeftRackByMultiplicationTableNC"); +DeclareGlobalFunction("LeftQuandleByMultiplicationTableNC"); +DeclareGlobalFunction("RightQuasigroupByMultiplicationTableNC"); +DeclareGlobalFunction("RightRackByMultiplicationTableNC"); DeclareGlobalFunction("RightQuandleByMultiplicationTableNC"); +#! @EndGroup ## Property of a collection that its elements know their multiplication table +#! @Chapter technical +#! @Section reps +#! @SectionTitle Representational issues +#! @Arguments collection +#! @Description True if the family of the elements in the collection possesses +#! a global multiplication table. This value is used to control whether more +#! efficient algorithms are used in particular cases. DeclareProperty("IsBuiltFromMultiplicationTable", IsCollection); ## Create quasigroups etc by permutations +#! @Chapter construct +#! @Section from_scratch +#! @BeginGroup perms_constructors +#! @GroupTitle Constructors from permutations +#! @Returns a magma of the designated category +#! @Description These functions produce magmas from a sequence of +#! permutations. That is to say, because all of the categories supported in +#! &RAQ; are quasigroups on at least one side, either the left +#! multiplicative action of an element on the magma is always a permutation +#! (in the case of left quasigroups) or the right multiplicative action of +#! an element on the magma is always a permutation. Hence, a magma in these +#! categories can always be specified by a list of $n$ permutations on +#! the natural numbers less than or equal to $n$ (i.e., ordinary &GAP; +#! permutations) and that's what these +#! functions do. In effect, the argument to the `Left` functions gives the +#! rows of the multiplication table (as permutation objects), and the to the +#! `Right` functions gives the columns. +#! @GroupInitialArguments permutation-list DeclareGlobalFunction("LeftQuasigroupByPerms"); DeclareGlobalFunction("LeftRackByPerms"); -DeclareGlobalFunction("LeftRackByPermsNC"); DeclareGlobalFunction("LeftQuandleByPerms"); -DeclareGlobalFunction("LeftQuandleByPermsNC"); DeclareGlobalFunction("RightQuasigroupByPerms"); DeclareGlobalFunction("RightRackByPerms"); -DeclareGlobalFunction("RightRackByPermsNC"); DeclareGlobalFunction("RightQuandleByPerms"); +#! @EndGroup + +#! @BeginExampleSession +#! gap> D3 := LeftQuandleByPerms( [ (2,3), (1,3), (1,2) ] ); +#! +#! gap> SpecifyElmNamePrefix(D3, "p"); +#! gap> BindElmNames(D3); +#! gap> p2*p3; +#! p1 +#! @EndExampleSession + +#! @BeginGroup unchecked_perms_constructors +#! @GroupTitle Unchecked constructors from permutations +#! @Returns a magma of the designated category +#! @Description These functions are exactly the same as their counterparts +#! without `NC` except that to save time they do not verify that the given +#! permutations satisfy the appropriate axioms. Hence use caution, as +#! supplying a list of permutations which does not form the proper structure +#! can lead to undefined behavior. Note that there are no unchecked versions +#! for the bare quasigroup constructors because the only properties required +#! are that all of the rows (or columns, in the `Right` case) are permutations. +#! @GroupInitialArguments permutation-list +DeclareGlobalFunction("LeftRackByPermsNC"); +DeclareGlobalFunction("LeftQuandleByPermsNC"); +DeclareGlobalFunction("RightRackByPermsNC"); DeclareGlobalFunction("RightQuandleByPermsNC"); +#! @EndGroup diff --git a/lib/structure.gd b/lib/structure.gd index 7443bf9..d6fea78 100644 --- a/lib/structure.gd +++ b/lib/structure.gd @@ -3,8 +3,6 @@ ## GAP Categories and representations #! @Chapter technical -#! This chapter covers computational/operational aspects of &RAQ; -#! rather than mathematical ones. #! @Section Messages #! @Description Controls the level of verbosity of &RAQ;'s informative #! messages. Use `SetInfoLevel` to set it to 0 to quiet &RAQ; @@ -22,14 +20,7 @@ DeclareInfoClass("InfoRAQ"); # new, non-conflicting terms. #! @Chapter basic -#! In order to build up and define one-sided quasigroups, racks, and -#! quandles, &RAQ; must define several lower-level objects and properties, -#! which are documented in this section. Although logically they come before -#! the domain constructors and operations, they are presented afterwards -#! because it's rare that one needs to use them directly when working with -#! &RAQ;. #! @Section elements -#! @SectionTitle Categories of elements #! @Description An element x with the property #! that for all elements y and z in its family, x*(y*z) = #! (x*y)*(x*z). @@ -46,7 +37,6 @@ DeclareCategory("IsRSelfDistElement", IsMultiplicativeElement); DeclareCategoryCollections("IsRSelfDistElement"); #! @Section collections -#! @SectionTitle Categories of collections #! @Description A collection which satisfies the left self-distributive #! property (see the description of #! ) @@ -80,11 +70,13 @@ InstallTrueMethod(IsElementwiseIdempotent, IsIdempotentCollection); #! (i.e., IsLSelfDistributive(obj) is true). #! @Arguments obj #! @ItemType Filt +#! @Returns true or false DeclareSynonym("IsLeftRack", IsLeftQuasigroup and IsLSelfDistributive); #! @Description Tests whether obj is a right rack, by definition #! precisely that it is a right quasigroup and right self-distributive. #! @Arguments obj #! @ItemType Filt +#! @Returns true or false DeclareSynonym("IsRightRack", IsRightQuasigroup and IsRSelfDistributive); #! @Description Tests whether obj is a left quandle, which by definition @@ -93,20 +85,18 @@ DeclareSynonym("IsRightRack", IsRightQuasigroup and IsRSelfDistributive); #! (i.e., IsElementwiseIdempotent(obj) is true). #! @Arguments obj #! @ItemType Filt +#! @Returns true or false DeclareSynonym("IsLeftQuandle", IsLeftRack and IsElementwiseIdempotent); #! @Description Tests whether obj is a right quandle, by definition #! precisely that it is a right rack and every element is idempotent. #! @Arguments obj #! @ItemType Filt +#! @Returns true or false DeclareSynonym("IsRightQuandle", IsRightRack and IsElementwiseIdempotent); #! @Chapter construct #! @Section from_scratch -#! @SectionTitle Direct constructors -#! All of the functions in this section produce magmas (of one of the -#! categories with which &RAQ; is concerned) from data of other (non-domain) -#! types. #! @BeginAutoDoc #! @BeginGroup basic_constructors #! @GroupTitle Basic constructors (from generators) @@ -123,13 +113,13 @@ DeclareSynonym("IsRightQuandle", IsRightRack and IsElementwiseIdempotent); #! quotients on the specified side must exist; racks must also satisfy the #! appropriate self-distributive law; and quandles must also have every #! element idempotent. -#! @Returns a magma of the named category +#! @Returns a magma of the designated category #! @GroupInitialArguments [family], [generators] DeclareGlobalFunction("LeftQuasigroup"); -DeclareGlobalFunction("RightQuasigroup"); DeclareGlobalFunction("LeftRack"); -DeclareGlobalFunction("RightRack"); DeclareGlobalFunction("LeftQuandle"); +DeclareGlobalFunction("RightQuasigroup"); +DeclareGlobalFunction("RightRack"); DeclareGlobalFunction("RightQuandle"); #! @EndGroup #! @BeginGroup unchecked_basic_constructors @@ -144,10 +134,10 @@ DeclareGlobalFunction("RightQuandle"); #! @Returns a magma of the named category #! @GroupInitialArguments family, generators DeclareGlobalFunction("LeftQuasigroupNC"); -DeclareGlobalFunction("RightQuasigroupNC"); DeclareGlobalFunction("LeftRackNC"); -DeclareGlobalFunction("RightRackNC"); DeclareGlobalFunction("LeftQuandleNC"); +DeclareGlobalFunction("RightQuasigroupNC"); +DeclareGlobalFunction("RightRackNC"); DeclareGlobalFunction("RightQuandleNC"); #! @EndGroup #! @EndAutoDoc diff --git a/tst/testall.g b/tst/testall.g index f4ddfe1..c43f902 100644 --- a/tst/testall.g +++ b/tst/testall.g @@ -9,6 +9,15 @@ TestDirectory(tst_path, testOptions := rec(compareFunction := "uptowhitespace")) ); +# Now make sure the manual tests are up to date + +doc_path := DirectoriesPackageLibrary("RAQ", "doc"); +makedoc_file := Filename(doc_path, "makedoc.g"); + +RAQ_makedoc_no_quit := true; +Info(InfoRAQ, 1, "Generating RAQ documentation..\n\n"); +Read(makedoc_file); + auto_file := Filename(tst_path, "AutoDoc_tests.g"); if auto_file <> fail then