diff --git a/.gaplint.yml b/.gaplint.yml new file mode 100644 index 0000000..a6e81f9 --- /dev/null +++ b/.gaplint.yml @@ -0,0 +1,2 @@ +disable: + - align-assignments diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5ef9dc6..8289505 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -28,7 +28,6 @@ jobs: - stable-4.12 - stable-4.11 - stable-4.10 - - stable-4.9 steps: - uses: actions/checkout@v4 diff --git a/PackageInfo.g b/PackageInfo.g index 7687471..75cf060 100644 --- a/PackageInfo.g +++ b/PackageInfo.g @@ -1,18 +1,18 @@ ############################################################################# ## -#W PackageInfo.g Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2015 Andreas Distler & James D. Mitchell +## PackageInfo.g Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# ## -SetPackageInfo( rec( +SetPackageInfo(rec( PackageName := "Smallsemi", Subtitle := "A library of small semigroups", Version := "0.6.13", -Date := "28/02/2022", # this is in dd/mm/yyyy format +Date := "28/02/2022", # this is in dd/mm/yyyy format License := "GPL-3.0-or-later", Persons := [ @@ -21,7 +21,7 @@ Persons := [ IsAuthor := true, IsMaintainer := false, Email := "a.distler@tu-bs.de", - ), +), rec( LastName := "Mitchell", FirstNames := "James", @@ -29,26 +29,26 @@ Persons := [ IsMaintainer := true, Email := "jdm3@st-and.ac.uk", WWWHome := "http://tinyurl.com/jdmitchell", - PostalAddress := Concatenation( [ + PostalAddress := Concatenation([ "Mathematical Institute\n", "North Haugh\n", - "St Andrews\n", "Fife\n", "KY16 9SS\n", "Scotland"] ), + "St Andrews\n", "Fife\n", "KY16 9SS\n", "Scotland"]), Place := "St Andrews", Institution := "University of St Andrews" - ) +) ], Status := "deposited", PackageWWWHome := "https://gap-packages.github.io/smallsemi/", -README_URL := Concatenation( ~.PackageWWWHome, "README" ), -PackageInfoURL := Concatenation( ~.PackageWWWHome, "PackageInfo.g" ), +README_URL := Concatenation(~.PackageWWWHome, "README"), +PackageInfoURL := Concatenation(~.PackageWWWHome, "PackageInfo.g"), SourceRepository := rec( Type := "git", URL := "https://github.com/gap-packages/smallsemi", ), -IssueTrackerURL := Concatenation( ~.SourceRepository.URL, "/issues" ), -ArchiveURL := Concatenation( ~.SourceRepository.URL, +IssueTrackerURL := Concatenation(~.SourceRepository.URL, " / issues"), +ArchiveURL := Concatenation(~.SourceRepository.URL, "/releases/download/v", ~.Version, - "/smallsemi-", ~.Version ), + " / smallsemi -", ~.Version), ArchiveFormats := ".tar.gz", AbstractHTML := @@ -66,32 +66,31 @@ PackageDoc := rec( ), Dependencies := rec( - GAP := ">=4.8", + GAP := ">=4.10", NeededOtherPackages := [], SuggestedOtherPackages := [], ExternalConditions := ["gzip is needed in standard location if data files are used uncompressed"]), AvailabilityTest := ReturnTrue, BannerString := Concatenation( - ListWithIdenticalEntries(SizeScreen()[1]-3, '-'), "\n", ~.PackageName, + ListWithIdenticalEntries(SizeScreen()[1] - 3, '-'), "\n", ~.PackageName, " - ", ~.Subtitle, "\n", "by ", ~.Persons[1].FirstNames, " ", ~.Persons[1].LastName, - " & " , ~.Persons[2].FirstNames, " ", ~.Persons[2].LastName, "\n", - "For contents, type: ?Smallsemi:\n" , + " & ", ~.Persons[2].FirstNames, " ", ~.Persons[2].LastName, "\n", + "For contents, type: ?Smallsemi:\n", "Loading ", ~.PackageName, " ", ~.Version, " ...\n", - ListWithIdenticalEntries(SizeScreen()[1]-3, '-'), "\n" ), + ListWithIdenticalEntries(SizeScreen()[1] - 3, '-'), "\n"), TestFile := "tst/testall.g", Keywords := ["small semigroups", "data library", "multiplication tables"], AutoDoc := rec( entities := rec( VERSION := ~.Version, - ARCHIVENAME := Remove( SplitString( ~.ArchiveURL, "/" ) ), - ), + ARCHIVENAME := Remove(SplitString(~.ArchiveURL, " / "))), TitlePage := rec( - Version := Concatenation( "Version ", ~.Version ), + Version := Concatenation("Version ", ~.Version), Copyright := """ - ©right; 2008-19 A. Distler & J. D. Mitchell.

+ ©right; 2008-24 A. Distler & J. D. Mitchell.

Smallsemi is free software: you can redistribute it and/or modify it under the terms of the GNU @@ -116,7 +115,8 @@ AutoDoc := rec( Colophon := """ If you find any bugs or have any suggestions or comments, we would very much appreciate it if you would let us know via our - issue tracker (see https://github.com/gap-packages/smallsemi/issues). + issue tracker (see + https://github.com/gap-packages/smallsemi/issues). """, Acknowledgements := """ @@ -127,8 +127,6 @@ AutoDoc := rec( The first author acknowledges financial support of the University of St Andrews. The second author acknowledges support of EPSRC grant number GR/S/56085/01. - """, - ), + """), ), )); - diff --git a/doc/functionality.xml b/doc/functionality.xml index 71056f9..b777acf 100644 --- a/doc/functionality.xml +++ b/doc/functionality.xml @@ -4,23 +4,23 @@ -The semigroups of sizes 1 to 8 are available up to isomorphism -and anti-isomorphism in Smallsemi. Every semigroup -in the library is identified by its size -m and a number n lying between 1 and the number of -semigroups of size m (see Table ). We -call the pair (m,n) the ID of the semigroup. +The semigroups of sizes 1 to 8 are available up to isomorphism and +anti-isomorphism in Smallsemi. Every semigroup in the +library is identified by its size m and a number n lying between +1 and the number of semigroups of size m (see Table ). We call the pair (m,n) the ID of the +semigroup.

-In this section we give details about the functions relating to -individual semigroups in Smallsemi. This includes -how to access semigroups in the library and how to identify the -semigroup in the library equivalent to an arbitrary semigroup (of size +In this section we give details about the functions relating to individual +semigroups in Smallsemi. This includes how to access +semigroups in the library and how to identify the semigroup in the library +equivalent to an arbitrary semigroup (of size 1 to 8).

-If you are interested in the properties of a semigroup in the library -or would like to find all the semigroups satisfying a given set of -properties please see Section or Section respectively.

+If you are interested in the properties of a semigroup in the library or would +like to find all the semigroups satisfying a given set of properties please see +Section or Section respectively. +

<#Include Label="SmallSemigroup"> <#Include Label="IsSmallSemigroup"> @@ -36,45 +36,82 @@ Sect="enums"/> respectively.

Properties of Semigroups - + In this section we detail the &GAP; functions that can be used to determine whether a small semigroup satisfies a certain property. Let S be a -semigroup. Then +semigroup. Then - S is a left zero semigroup if xy=x for all - x,y in S. - - S is a right zero semigroup if xy=y for all x,y in S. -S is commutative if xy=yx for all x,y in S. - S is simple if it has no proper two-sided ideals. - S is zero simple if the only 2-sided ideals are {0} and S. - S is regular if for all x in S there exists y in -S such that xyx=x. - S is completely regular if every element of S lies in a subgroup. - S is an inverse semigroup if every element x in S has a unique semigroup -inverse, that is, a unique element y such that xyx=x and yxy=y. - S is a Clifford semigroup if it is a regular semigroup whose idempotents are central, -that is, for all e,x in S where e^2=e we have that ex=xe. - S is a band if every element is an idempotent, that is, x^2=x -for all x in S. - S is a Brandt semigroup if it is inverse and zero simple. - S is a rectangular band if for all x,y,z in S -we have that x^2=x and xyz=xz. - S is a semiband if it is generated by its idempotent elements, -that is, elements satisfying x^2=x. - S is an orthodox -semigroup if it is regular and its idempotents (elements satisfying x^2=x) -form a subsemigroup. -S is a zero semigroup if there exists an element 0 in -S such that xy=0 for all x,y in S. -S is a zero group if there exists an element 0 in -S such that S without 0 is a group and for all x in S we have that -x0=0x=0. + + S is a left zero semigroup if xy=x for all + x,y in S. + + + S is a right zero semigroup if xy=y for all + x,y in S. + + + S is commutative if xy=yx for all x,y in + S. + + + S is simple if it has no proper two-sided ideals. + + + S is zero simple if the only 2-sided ideals are + {0} and S. + + + S is regular if for all x in S there exists + y in S such that xyx=x. + + + S is completely regular if every element of S + lies in a subgroup. + + + S is an inverse semigroup if every element x in + S has a unique semigroup inverse, that is, a unique element + y such that xyx=x and yxy=y. + + + S is a Clifford semigroup if it is a regular semigroup + whose idempotents are central, that is, for all e,x in S + where e^2=e we have that ex=xe. + + + S is a band if every element is an idempotent, that is, + x^2=x for all x in S. + + + S is a Brandt semigroup if it is inverse and zero simple. + + + S is a rectangular band if for all x,y,z in S + we have that x^2=x and xyz=xz. + + + S is a semiband if it is generated by its idempotent + elements, that is, elements satisfying x^2=x. + + + S is an orthodox semigroup if it is regular and its + idempotents (elements satisfying x^2=x) form a subsemigroup. + + + S is a zero semigroup if there exists an element 0 + in S such that xy=0 for all x,y in S. + + + S is a zero group if there exists an element 0 in + S such that S without 0 is a group and for all + x in S we have that x0=0x=0. + - The MONOID package was used to determined which semigroups in the library satisfy the properties above. - All of the resulting information is stored in the library. + The MONOID package was used to determined which + semigroups in the library satisfy the properties above. All of the + resulting information is stored in the library. <#Include Label="Annihilators"> <#Include Label="DiagonalOfMultiplicationTable"> @@ -114,20 +151,17 @@ form a subsemigroup.
Nilpotent semigroups by coclass - A useful parameter in the classification of nilpotent semigroups is - their coclass. For a finite nilpotent semigroup of order n and - nilpotency degree d the coclass is defined as n-d. In - lists up to (anti-)isomorphism are provided for - nilpotent semigroups of coclass 0, 1, and 2. The semigroups in the - lists are given by finite presentations. In this section we describe - a function that allows to access such lists in &GAP;. -

- A further invariant of a nilpotent semigroup S is the size of - its unique minimal generating set S\backslash S^2. The possible - sizes for a particular coclass are restricted. Monogenic nilpotent - semigroups are precisely those of coclass 0. For coclass - d \geq 1 the size of the minimal generating set is at least 2 - and at most d+1. + A useful parameter in the classification of nilpotent semigroups is their + coclass. For a finite nilpotent semigroup of order n and nilpotency + degree d the coclass is defined as n-d. In + lists up to (anti-)isomorphism are provided for nilpotent semigroups of coclass + 0, 1, and 2. The semigroups in the lists are given by finite presentations. In + this section we describe a function that allows to access such lists in &GAP;. +

A further invariant of a nilpotent semigroup S is the size of its + unique minimal generating set S\backslash S^2. The possible sizes for a + particular coclass are restricted. Monogenic nilpotent semigroups are precisely + those of coclass 0. For coclass d \geq 1 the size of the minimal + generating set is at least 2 and at most d+1. <#Include Label="NilpotentSemigroupsByCoclass"> @@ -136,30 +170,30 @@ form a subsemigroup.

Starred Green's relations In this section functionality around the starred Green's relations is - described. The five starred Green's relations are R^*, - L^*, J^*, H^*, and D^*; - two elements a, b from a semigroup S are - R^*-related if for all x, y \in S^1: xa=ya if and only if - xb = yb; and a and b are L^*-related if - for all x, y \in S^1: - ax=ay if and only if bx = by. In parallel to the classical - Green's relations - H^*=R^* \wedge L^* and - D^*= R^* \vee L^* (but R^* \circ L^* = L^* \circ R^* - does not hold in general). To describe J^* is a bit - more technical. For a,b \in S one can show that b lies in - J^*(a), the principal *-ideal of a, if and only if there - exist c_0,c_1\ldots,c_n\in S and x_1,\ldots,x_n,y_1,\ldots, - y_n\in S^1 such that a=c_0, b=c_n and - c_iD^*x_ic_{i-1}y_i for 1\leq i\leq n. Then aJ^*b - if and only if both a\in J^*(b) and b\in J^*(a) -

+ described. The five starred Green's relations are R^*, + L^*, J^*, H^*, and D^*; + two elements a, b from a semigroup S are + R^*-related if for all x, y \in S^1: xa=ya if and only if + xb = yb; and a and b are L^*-related if + for all x, y \in S^1: + ax=ay if and only if bx = by. In parallel to the classical + Green's relations + H^*=R^* \wedge L^* and + D^*= R^* \vee L^* (but R^* \circ L^* = L^* \circ R^* + does not hold in general). To describe J^* is a bit + more technical. For a,b \in S one can show that b lies in + J^*(a), the principal *-ideal of a, if and only if there + exist c_0,c_1\ldots,c_n\in S and x_1,\ldots,x_n,y_1,\ldots, + y_n\in S^1 such that a=c_0, b=c_n and + c_iD^*x_ic_{i-1}y_i for 1\leq i\leq n. Then aJ^*b + if and only if both a\in J^*(b) and b\in J^*(a) +

- Note that even for finite semigroups J^* does not always equal - D^* (in contrast to the situation for classical Green's - relations). Using Smallsemi it was shown that there - exist semigroups of order 8 with J^*\neq D^* - . + Note that even for finite semigroups J^* does not always equal + D^* (in contrast to the situation for classical Green's + relations). Using Smallsemi it was shown that there + exist semigroups of order 8 with J^*\neq D^* + . <#Include Label="IsStarRelation"> <#Include Label="RStarRelation"> @@ -170,71 +204,103 @@ form a subsemigroup.

Families of Semigroups - - In this section we describe how to find semigroups in the library satisfying a given set of - parameters.

- - The following functions have the same usage but may return different - values: , , - , , - , , - , , + + In this section we describe how to find semigroups in the library + satisfying a given set of parameters.

+ + The following functions have the same usage but may return different + values: , + , + , + , + , + , + , + , .

- - The number of arguments should be odd: + + The number of arguments should be odd: - the first argument arg[1] should be a positive integer, a list of positive integers, or - an enumerator or iterator of small semigroups satisfying or - - the even arguments arg[2i], if present, should be a function - the odd arguments arg[2i+1] argument should be a possible value that can be returned by the function - arg[2i]. + + the first argument arg[1] should be a positive integer, a list + of positive integers, or an enumerator or iterator of small semigroups + satisfying or + + + + the even arguments arg[2i], if present, should be a function + + + the odd arguments arg[2i+1] argument should be a possible value + that can be returned by the function arg[2i]. + - - In the case that the function is and arg[1] is a positive integer, then - the returned value is a list of all semigroups S with arg[1] - elements such that arg[2i](S)=arg[2i+1].

- - For example, to obtain all the commutative semigroups with 3 idempotents of - sizes 2 to 5 use one of , , - , with argument + + In the case that the function is and + arg[1] is a positive integer, then the returned value is a list of + all semigroups S with arg[1] elements such that + arg[2i](S)=arg[2i+1].

+ + For example, to obtain all the commutative semigroups with 3 + idempotents of sizes 2 to 5 use one of , , + , + with argument [2..5], IsCommutative, true, Is3IdempotentGenerated, true - returns a list of all such semigroups, , - , and - return an enumerator and an iterator of all such semigroups, respectively. - For more information on enumerators and iterators see , - , or . The following are - rules of thumb regarding the different situations when these functions should be used in order of slowest to fastest and greatest - memory use to least: + returns a list of all such semigroups, + , , and return an enumerator and an iterator of + all such semigroups, respectively. For more information on enumerators and + iterators see , , or . The following are rules of thumb regarding the + different situations when these functions should be used in order of + slowest to fastest and greatest memory use to least: - should be used if the number of semigroups is not too large and you want to keep the - created semigroups in a list. - - or should be used when - the functions in even indexed positions are those stored in the library (see ) or you want - repeatedly search the same set of semigroups and there are too many to store in a list. Note that the enumerator stores the - id numbers of its elements but not the semigroups themselves. Hence every time an element of the - enumerator is required it must be recreated from the multiplication table data. - - should be used if the functions in even indexed positions are not stored in the - library (see ) or if you just want to run through all the semigroups satisfying the specified - parameters once only. Note that each new call of requires &GAP; to recompute its elements - which may be slow if the functions are user-defined or not stored in the library. + + should be used if the number of + semigroups is not too large and you want to keep the created semigroups + in a list. + + + or + should be used when the + functions in even indexed positions are those stored in the library + (see ) or you want repeatedly + search the same set of semigroups and there are too many to store in a + list. Note that the enumerator stores the id numbers of its elements + but not the semigroups themselves. Hence every time an element of the + enumerator is required it must be recreated from the multiplication + table data. + + + should be used if the functions + in even indexed positions are not stored in the library (see ) or if you just want to run + through all the semigroups satisfying the specified parameters once + only. Note that each new call of + requires &GAP; to recompute its elements which may be slow if the + functions are user-defined or not stored in the library. + - Further information on the - relative virtues of these different commands can be found in Chapter .

- - As a further example, if we want to obtain a single non-simple semigroup with 7 elements and trivial automorphism group, - then we would use one of the functions or with argument

+ Further information on the relative virtues of these different commands can + be found in Chapter .

+ + As a further example, if we want to obtain a single non-simple semigroup + with 7 elements and trivial automorphism group, then we would use + one of the functions or with argument

7, IsSimpleSemigroup, false, x-> IsTrivial(AutomorphismGroup(x)), true - should return an answer more quickly than . Also note that - will always return the same semigroup, i.e. the first semigroup in the library with the given - parameters. - + should return an answer more quickly than + . Also note that will always return the same semigroup, i.e. the + first semigroup in the library with the given parameters. + <#Include Label="AllSmallSemigroups"> <#Include Label="EnumeratorOfSmallSemigroups"> <#Include Label="EnumeratorOfSmallSemigroupsByIds"> @@ -258,6 +324,6 @@ form a subsemigroup. <#Include Label="SizesOfSmallSemisInEnum"> <#Include Label="SizesOfSmallSemisInIter"> <#Include Label="UpToIsomorphism"> - +

diff --git a/gap/3nil.gd b/gap/3nil.gd new file mode 100644 index 0000000..36f714e --- /dev/null +++ b/gap/3nil.gd @@ -0,0 +1,39 @@ +############################################################################# +## +## 3nil.gd Smallsemi - a GAP library of semigroups +## Copyright (C) 2024 Andreas Distler & James D. Mitchell +## +## Licensing information can be found in the README file of this package. +## +############################################################################# +## + +# <#GAPDoc Label="Nr3NilpotentSemigroups"> +# +# +# +# returns the number of 3-nilpotent semigroups on a set with n +# elements. If the optional argument type is given it must be one +# of "UpToEquivalence", "UpToIsomorphism", "SelfDual", "Commutative", +# "Labelled", "Labelled-Commutative". +# The number will be returned for the respective type of semigroup. +# By default type is "UpToEquivalence". +#

+# The function implements the formulae calculating the number of +# 3-nilpotent semigroups developed in +# Nr3NilpotentSemigroups( 4 ); +# 8 +# gap> Nr3NilpotentSemigroups( 9, "UpToIsomorphism" ); +# 105931872028455 +# gap> Nr3NilpotentSemigroups( 9, "Labelled" ); +# 38430603831264883632 +# gap> Nr3NilpotentSemigroups( 16, "SelfDual" ); +# 4975000837941847814744710290469890455985530 +# gap> Nr3NilpotentSemigroups( 19, "Commutative" ); +# 12094270656160403920767935604624748908993169949317454767617795 +# ]]> +# +# +# <#/GAPDoc> +DeclareGlobalFunction("Nr3NilpotentSemigroups"); diff --git a/gap/3nil.gi b/gap/3nil.gi new file mode 100644 index 0000000..cd830b1 --- /dev/null +++ b/gap/3nil.gi @@ -0,0 +1,370 @@ +############################################################################# +## +## 3nil.gi Smallsemi - a GAP library of semigroups +## Copyright (C) 2024 Andreas Distler & James D. Mitchell +## +## Licensing information can be found in the README file of this package. +## +############################################################################# +## + +InstallGlobalFunction(Nr3NilpotentSemigroups, function(arg...) + local size, # input, order of semigroups + type, # optional input, type of semigroups + types, # list of valid second (optional) arguments + i, # loop counter + smallc, + + nr3NilIso, + # takes a positive integer as input and returns the number of + # 3-nilpotent semigroups with elements up to isomorphism + + nr3NilSelfDual, + # takes a positive integer as input and returns the number of + # self-dual 3-nilpotent semigroups with elements + + nr3NilComm, + # takes a positive integer as input and returns the number of + # commutative 3-nilpotent semigroups with elements up to iso + + nr3NilAll, + # takes a positive integer as input and returns the number of + # all different 3-nilpotent semigroups on a set with elements + + nr3NilAllComm, + # takes a positive integer as input and returns the number of + # all different, commutative 3-nilpotent semigroups on a set with + # elements + + sizeConjugacyClass, + # returns for a partition of the number of permutations + # in the symmetric group on elements with disjoint cycle + # notation given by (corresponds to a conjugacy class) + + transformPart; + # takes a partition as a list of summands and returns a vector with + # the number of summands with value i in the i-th position + + ################################################################## + ### local functions + + sizeConjugacyClass := function(partition) + return Factorial(Sum(partition)) / + Product(Collected(partition), pair -> Factorial(pair[2]) + * pair[1] ^ pair[2]); + end; + + transformPart := function(part) + local n, coll, i, jvec; + + n := Sum(part); + jvec := []; + coll := Collected(part); + for i in [1 .. n] do + if IsBound(coll[1]) and coll[1][1] = i then + Add(jvec, coll[1][2]); + Remove(coll, 1); + else + Add(jvec, 0); + fi; + od; + return jvec; + end; + + nr3NilIso := function(n) + local NrIsomorphismClasses; + + NrIsomorphismClasses := function(n, m) + local parts, nrs, Produkt; + + Produkt := function(p1, p2) + local prod, i, j; + + prod := 1; + + for i in [1 .. Length(p1)] do + # if exponent is 0, prod is multiplied by 1 => omit + if p1[i] <> 0 then + for j in [1 .. Length(p1)] do + # if exponent is 0, prod is multiplied by 1 => omit + if p1[j] <> 0 then + prod := prod * (1 + Sum(Filtered(DivisorsInt(Lcm(i, j)), + x -> x <= Length(p2)), d -> d * p2[d])) + ^ (p1[i] * p1[j] * Gcd(i, j)); + fi; + od; + fi; + od; + return prod; + end; + + # only the zero semigroup in the case |B|=1 + if m = 1 then + return 1; + fi; + + # the elements in the Cartesian product are pairs of partitions + # they stand for elements in a conjugacy class of S_{n-m} x S_{m-1} + parts := Cartesian(Partitions(n - m), Partitions(m - 1)); + + # pp is a partition pair + nrs := List(parts, + pp -> Produkt(transformPart(pp[1]), + Concatenation(transformPart(pp[2]), [0])) * + sizeConjugacyClass(pp[1]) * sizeConjugacyClass(pp[2])); + return Sum(nrs) / (Factorial(n - m) * Factorial(m - 1)); + end; + + return Sum([2 .. n - 1], + m -> NrIsomorphismClasses(n, m) - + NrIsomorphismClasses(n - 1, m - 1)); + end; + + smallc := function(int, part) + return 1 + Sum(Filtered(DivisorsInt(int), + x -> x <= Length(part)), + d -> d * part[d]); + end; + + nr3NilSelfDual := function(n) + local NrEquivalenceClasses; + NrEquivalenceClasses := function(n, m) + local parts, nrs, Produkt, Prod1, Prod2, Prod3, Prod4; + + Prod1 := function(p1, p2) + local prod, i; + prod := 1; + for i in [1 .. Minimum(Int((Length(p1) + 1) / 2), + Int((n + 1) / 2))] do + # if exponent is 0, prod is multiplied by 1 => omit + if p1[2 * i - 1] <> 0 then + prod := prod * + (smallc(2 * i - 1, p2) * + smallc(4 * i - 2, p2) ^ (i - 1)) ^ + (p1[2 * i - 1]); + fi; + od; + return prod; + end; + + Prod2 := function(p1, p2) + local prod, i; + prod := 1; + for i in [1 .. Minimum(Int(Length(p1) / 4), Int(n / 4))] do + # if exponent is 0, prod is multiplied by 1 => omit + if p1[4 * i] <> 0 then + prod := prod * smallc(4 * i, p2) ^ (4 * i * p1[4 * i]); + fi; + od; + + return prod; + end; + + Prod3 := function(p1, p2) + local prod, i; + prod := 1; + for i in [1 .. Minimum(Int((Length(p1) + 2) / 4), Int(n + 2 / 4))] do + # if exponent is 0, prod is multiplied by 1 => omit + if p1[4 * i - 2] <> 0 then + prod := prod * + (smallc(2 * i - 1, p2) ^ 2 + * smallc(4 * i - 2, p2) ^ (4 * i - 3)) ^ + p1[4 * i - 2]; + fi; + od; + return prod; + end; + + Prod4 := function(p1, p2) + local prod, i, j; + + prod := 1; + + for i in [1 .. Length(p1)] do + # if exponent is 0, prod is multiplied by 1 => omit + if p1[i] <> 0 then + prod := prod * smallc(Lcm(2, i), p2) ^ + (i * Gcd(2, i) * (p1[i] ^ 2 - p1[i]) / 2); + for j in [1 .. Minimum(Length(p1), i - 1)] do + # if exponent is 0, prod is multiplied by 1 = > omit + if p1[j] <> 0 then + prod := prod * smallc(Lcm(2, i, j), p2) ^ + (p1[i] * p1[j] * 2 * i * j / Lcm(2, i, j)); + fi; + od; + fi; + od; + + return prod; + end; + + Produkt := {p1, p2} -> + Prod1(p1, p2) * Prod2(p1, p2) * Prod3(p1, p2) * Prod4(p1, p2); + + # only the zero semigroup in the case |B|=1, counted half + if m = 1 then + return 1; + fi; + + # the elements in the Cartesian product are pairs of partitions + # they stand for elements in a conjugacy class of S_{n-m} x S_{m-1} + parts := Cartesian(Partitions(n - m), Partitions(m - 1)); + + # pp is a partition pair + nrs := List(parts, + pp -> Produkt(transformPart(pp[1]), + Concatenation(transformPart(pp[2]), [0])) * + sizeConjugacyClass(pp[1]) * sizeConjugacyClass(pp[2])); + + return Sum(nrs) / (Factorial(n - m) * Factorial(m - 1)); + end; + + return Sum([2 .. n - 1], + m -> NrEquivalenceClasses(n, m) - + NrEquivalenceClasses(n - 1, m - 1)); + end; + + nr3NilComm := function(n) + local NrIsomorphismClasses; + + NrIsomorphismClasses := function(n, m) + local parts, nrs, Produkt, Produkt1, Produkt2, Produkt3; + + Produkt1 := function(p1, p2) + local prod, i; + + prod := 1; + + for i in [1 .. Minimum(Int(Length(p1) / 2), Int(n / 2))] do + # if exponent is 0, prod is multiplied by 1 = > omit + if p1[2 * i] <> 0 then + prod := prod * + (smallc(i, p2) * smallc(2 * i, p2) ^ i) ^ p1[2 * i]; + fi; + od; + + return prod; + end; + + Produkt2 := function(p1, p2) + local prod, i; + prod := 1; + for i in [1 .. Minimum(Int((Length(p1) + 1) / 2), Int((n + 1) / 2))] do + # if exponent is 0, prod is multiplied by 1 => omit + if p1[2 * i - 1] <> 0 then + prod := prod * + (smallc(2 * i - 1, p2)) ^ (i * p1[2 * i - 1]); + fi; + od; + + return prod; + end; + + Produkt3 := function(p1, p2) + local prod, i, j; + prod := 1; + for i in [1 .. Length(p1)] do + # if exponent is 0, prod is multiplied by 1 => omit + if p1[i] <> 0 then + prod := prod * smallc(i, p2) ^ (i * (p1[i] ^ 2 - p1[i]) / 2); + for j in [1 .. Minimum(Length(p1), i - 1)] do + # if exponent is 0, prod is multiplied by 1 => omit + if p1[j] <> 0 then + prod := prod * smallc(Lcm(i, j), p2) ^ + (p1[i] * p1[j] * Gcd(i, j)); + fi; + od; + fi; + od; + + return prod; + end; + + Produkt := {p1, p2} -> + Produkt1(p1, p2) * Produkt2(p1, p2) * Produkt3(p1, p2); + + # only the zero semigroup in the case |B|=1 + if m = 1 then + return 1; + fi; + + # the elements in the Cartesian product are pairs of partitions + # they stand for elements in a conjugacy class of S_{n-m} x S_{m-1} + parts := Cartesian(Partitions(n - m), Partitions(m - 1)); + + # pp is a partition pair + nrs := List(parts, + pp -> Produkt(transformPart(pp[1]), + Concatenation(transformPart(pp[2]), [0])) * + sizeConjugacyClass(pp[1]) * sizeConjugacyClass(pp[2])); + + return Sum(nrs) / (Factorial(n - m) * Factorial(m - 1)); + end; + + return Sum([2 .. n - 1], + m -> NrIsomorphismClasses(n, m) - + NrIsomorphismClasses(n - 1, m - 1)); + end; + + nr3NilAll := function(n) + return Sum([2 .. Int(n + 1 / 2 - RootInt(n - 1))], + k -> Binomial(n, k) * k + * Sum([0 .. k - 1], + i -> (- 1) ^ i * Binomial(k - 1, i) + * (k - i) ^ ((n - k) ^ 2))); + end; + + nr3NilAllComm := function(n) + return Sum([1 .. Int(n + 3 / 2 - RootInt(2 * n))], + k -> Binomial(n, k) * k + * Sum([0 .. k - 1], + i -> (- 1) ^ i * Binomial(k - 1, i) + * (k - i) ^ ((n - k) * (n - k + 1) / 2))); + end; + + ################################################################## + # MAIN FUNCTION + ################################################################## + + types := ["UpToEquivalence", "UpToIsomorphism", "SelfDual", "Commutative", + "Labelled", "Labelled-Commutative"]; + + # check input + if Length(arg) > 2 then + Error("number of arguments must be two"); + elif not IsPosInt(arg[1]) then + Error("first argument must be a positive integer"); + elif Length(arg) = 2 and not IsString(arg[2]) then + Error("second argument must be a string"); + elif Length(arg) = 2 and not arg[2] in types then + Error("invalid second argument, string must be in ", types); + fi; + + # get input + size := arg[1]; + if Length(arg) = 2 then + type := arg[2]; + else + type := types[1]; + fi; + + if type = types[1] then + # up to equivalence + return (nr3NilSelfDual(size) + nr3NilIso(size)) / 2; + elif type = types[2] then + # up to isomorphism + return nr3NilIso(size); + elif type = types[3] then + # self dual semigroups + return nr3NilSelfDual(size); + elif type = types[4] then + # commutative semigroups + return nr3NilComm(size); + elif type = types[5] then + # labelled semigroups + return nr3NilAll(size); + else + # labelled commutative semigroups + return nr3NilAllComm(size); + fi; +end); diff --git a/gap/autovars.g b/gap/autovars.g index 521f199..ef146b9 100644 --- a/gap/autovars.g +++ b/gap/autovars.g @@ -1,50 +1,77 @@ ############################################################################# ## -#W autovars.g Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2012 Andreas Distler & James D. Mitchell +## autovars.g Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2012 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# ## +# <#GAPDoc Label="MOREDATA2TO8"> +# +# +# +# contains the precomputed information stored in the files infon.g +# for n in \{1,...,8\} in a list where the nth entry +# is a record with components named after the function values they store. +# For example, to retrieve the stored value of the function +# MinimalGeneratorsOfSemigroup for a semigroup S of size +# 5 do +# +# MOREDATA2TO8[5].MinimalGeneratorsOfSemigroup[IdSmallSemigroup(S)[2]]; +# +# +# +# <#/GAPDoc> +BindGlobal("MOREDATA2TO8", READ_MOREDATA2TO8()); -##################### +# <#GAPDoc Label="BLUEPRINT_MATS"> +# +# +# +# see . +# Display( BLUEPRINT_MATS[3] ); +# [ [ 1, 1, 1, 1, 1, 1, 1, 1 ], +# [ 1, 1, 1, 1, 1, 1, 1, 1 ], +# [ 1, 1, 1, 1, 1, 1, 1, 1 ], +# [ 1, 1, 1 ], +# [ 1, 1, 1 ], +# [ 1, 1, 1 ], +# [ 1, 1, 1 ], +# [ 1, 1, 1 ] ] +# ]]> +# +# +# <#/GAPDoc> +BindGlobal("BLUEPRINT_MATS", GENERATE_BLUEPRINT_MATS()); -BindGlobal("MOREDATA2TO8", READ_MOREDATA2TO8( ) ); - -##################### - -BindGlobal("BLUEPRINT_MATS", GENERATE_BLUEPRINT_MATS( ) ); - -########################################################################### -## -## <#GAPDoc Label="PrecomputedSmallSemisInfo"> -## -## -## -## the global variable PrecomputedSmallSemisInfo contains a list of all -## the names of precomputed properties stored in the library. The ith -## element of the list contains the list of properties that have been -## precomputed for all semigroups in the library of order i. -## PrecomputedSmallSemisInfo[3]; -## [ "Is2GeneratedSemigroup", "Is3GeneratedSemigroup", "Is4GeneratedSemigroup", -## "Is5GeneratedSemigroup", "Is6GeneratedSemigroup", "Is7GeneratedSemigroup", -## "Is8GeneratedSemigroup", "IsBand", "IsCommutative", -## "IsCompletelyRegularSemigroup", "IsFullTransformationSemigroupCopy", -## "IsGroupAsSemigroup", "IsIdempotentGenerated", "IsInverseSemigroup", -## "IsMonogenicSemigroup", "IsMonoidAsSemigroup", "IsMultSemigroupOfNearRing", -## "IsMunnSemigroup", "IsRegularSemigroup", "IsSelfDualSemigroup", -## "IsSemigroupWithoutClosedIdempotents", "IsSimpleSemigroup", -## "IsSingularSemigroupCopy", "IsZeroSemigroup", "IsZeroSimpleSemigroup" ] -## ]]> -## -## -## <#/GAPDoc> - -BindGlobal("PrecomputedSmallSemisInfo", - List([1..8], - n->AsSet(Concatenation(Filtered(RecNames(MOREDATA2TO8[n]), - x->IsUpperAlphaChar(x[1])), - ["IsBand"])))); +# <#GAPDoc Label="PrecomputedSmallSemisInfo"> +# +# +# +# the global variable PrecomputedSmallSemisInfo contains a list of all +# the names of precomputed properties stored in the library. The ith +# element of the list contains the list of properties that have been +# precomputed for all semigroups in the library of order i. +# PrecomputedSmallSemisInfo[3]; +# [ "Is2GeneratedSemigroup", "Is3GeneratedSemigroup", "Is4GeneratedSemigroup", +# "Is5GeneratedSemigroup", "Is6GeneratedSemigroup", "Is7GeneratedSemigroup", +# "Is8GeneratedSemigroup", "IsBand", "IsCommutative", +# "IsCompletelyRegularSemigroup", "IsFullTransformationSemigroupCopy", +# "IsGroupAsSemigroup", "IsIdempotentGenerated", "IsInverseSemigroup", +# "IsMonogenicSemigroup", "IsMonoidAsSemigroup", "IsMultSemigroupOfNearRing", +# "IsMunnSemigroup", "IsRegularSemigroup", "IsSelfDualSemigroup", +# "IsSemigroupWithoutClosedIdempotents", "IsSimpleSemigroup", +# "IsSingularSemigroupCopy", "IsZeroSemigroup", "IsZeroSimpleSemigroup" ] +# ]]> +# +# +# <#/GAPDoc> +BindGlobal("PrecomputedSmallSemisInfo", + List([1 .. 8], + n -> AsSet(Concatenation(Filtered(RecNames(MOREDATA2TO8[n]), + x -> IsUpperAlphaChar(x[1])), + ["IsBand"])))); diff --git a/gap/coclass.gd b/gap/coclass.gd index f2150a4..3addabb 100644 --- a/gap/coclass.gd +++ b/gap/coclass.gd @@ -1,166 +1,143 @@ ############################################################################# ## -#W coclass.gd Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2014 Andreas Distler & James D. Mitchell +## coclass.gd Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# -########################################################################### -## -## <#GAPDoc Label="NilpotentSemigroupsByCoclass"> -## -## -## -## returns for a positive integer n and an integer d with value -## 0, 1, or 2 a list of nilpotent semigroups of order n and coclass -## d up to (anti-)isomorphism. If the optional third argument r -## is given then only semigroups of rank r are returned. The semigroups -## in the list are given by finite presentations. -## NilpotentSemigroupsByCoclass(5,1); -## [ , -## , -## , -## , -## , -## , -## ] -## gap> NilpotentSemigroupsByCoclass(7,0); -## [ ] -## gap> NilpotentSemigroupsByCoclass(4,2,3); -## [ ] -## ]]> -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="NilpotentSemigroupsByCoclass"> +# +# +# +# returns for a positive integer n and an integer d with value +# 0, 1, or 2 a list of nilpotent semigroups of order n and coclass +# d up to (anti-)isomorphism. If the optional third argument r +# is given then only semigroups of rank r are returned. The semigroups +# in the list are given by finite presentations. +# NilpotentSemigroupsByCoclass(5, 1); +# [ , +# , +# , +# , +# , +# , +# ] +# gap> NilpotentSemigroupsByCoclass(7, 0); +# [ ] +# gap> NilpotentSemigroupsByCoclass(4, 2, 3); +# [ ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("NilpotentSemigroupsByCoclass"); -########################################################################### -## -## <#GAPDoc Label="NilpotentSemigroupsCoclass0"> -## -## -## -## returns for a positive integer n a list of length one containing -## a finitely presented semigroup of coclass 0, that is a nilpotent, -## monogenic semigroup, of order n. -## NilpotentSemigroupsCoclass0(513); -## [ ] -## ]]> -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="NilpotentSemigroupsCoclass0"> +# +# +# +# returns for a positive integer n a list of length one containing +# a finitely presented semigroup of coclass 0, that is a nilpotent, +# monogenic semigroup, of order n. +# NilpotentSemigroupsCoclass0(513); +# [ ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("NilpotentSemigroupsCoclass0"); -########################################################################### -## -## <#GAPDoc Label="NilpotentSemigroupsCoclass1"> -## -## -## -## returns for a positive integer n a list of nilpotent semigroups of -## coclass 1 up to (anti-)isomorphism as finitely presented semigroups. -## NilpotentSemigroupsCoclass1(2); -## [ ] -## gap> NilpotentSemigroupsCoclass1(3); -## [ ] -## gap> NilpotentSemigroupsCoclass1(5); -## [ , -## , -## , -## , -## , -## , -## ] -## ]]> -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="NilpotentSemigroupsCoclass1"> +# +# +# +# returns for a positive integer n a list of nilpotent semigroups of +# coclass 1 up to (anti-)isomorphism as finitely presented semigroups. +# NilpotentSemigroupsCoclass1(2); +# [ ] +# gap> NilpotentSemigroupsCoclass1(3); +# [ ] +# gap> NilpotentSemigroupsCoclass1(5); +# [ , +# , +# , +# , +# , +# , +# ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("NilpotentSemigroupsCoclass1"); -########################################################################### -## -## <#GAPDoc Label="NilpotentSemigroupsCoclass2"> -## -## -## -## returns for a positive integer n a list of nilpotent semigroups of -## coclass 2 up to (anti-)isomorphism as finitely presented semigroups. -## NilpotentSemigroupsCoclass2(3); -## [ ] -## gap> NilpotentSemigroupsCoclass2(4); -## [ ] -## ]]> -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="NilpotentSemigroupsCoclass2"> +# +# +# +# returns for a positive integer n a list of nilpotent semigroups o +# coclass 2 up to (anti-)isomorphism as finitely presented semigroups. +# NilpotentSemigroupsCoclass2(3); +# [ ] +# gap> NilpotentSemigroupsCoclass2(4); +# [ ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("NilpotentSemigroupsCoclass2"); - DeclareGlobalFunction("IsomorphicFpSemigroup"); -########################################################################### -## -## <#GAPDoc Label="NilpotentSemigroupsCoclass2Rank2"> -## -## -## -## returns for a positive integer n a list of nilpotent 2-generated -## semigroups of coclass 2 up to (anti-)isomorphism as finitely presented -## semigroups. -## NilpotentSemigroupsCoclass2Rank2(4); -## [ ] -## gap> NilpotentSemigroupsCoclass2Rank2(5); -## [ , -## , -## , -## , -## , -## , -## , -## , -## , -## , -## ] -## ]]> -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="NilpotentSemigroupsCoclass2Rank2"> +# +# +# +# returns for a positive integer n a list of nilpotent 2-generated +# semigroups of coclass 2 up to (anti-)isomorphism as finitely presented +# semigroups. +# NilpotentSemigroupsCoclass2Rank2(4); +# [ ] +# gap> NilpotentSemigroupsCoclass2Rank2(5); +# [ , +# , +# , +# , +# , +# , +# , +# , +# , +# , +# ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("NilpotentSemigroupsCoclass2Rank2"); -########################################################################### -## -## <#GAPDoc Label="NilpotentSemigroupsCoclass2Rank3"> -## -## -## -## returns for a positive integer n a list of nilpotent 3-generated -## semigroups of coclass 2 up to (anti-)isomorphism as finitely presented -## semigroups. -## NilpotentSemigroupsCoclass2Rank3(3); -## [ ] -## gap> NilpotentSemigroupsCoclass2Rank3(4); -## [ ] -## ]]> -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="NilpotentSemigroupsCoclass2Rank3"> +# +# +# +# returns for a positive integer n a list of nilpotent 3-generated +# semigroups of coclass 2 up to (anti-)isomorphism as finitely presented +# semigroups. +# NilpotentSemigroupsCoclass2Rank3(3); +# [ ] +# gap> NilpotentSemigroupsCoclass2Rank3(4); +# [ ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("NilpotentSemigroupsCoclass2Rank3"); - DeclareGlobalFunction("NilpotentSemigroupsCoclassD_NC"); - DeclareGlobalFunction("NilpotentSemigroupsCoclassD"); - - diff --git a/gap/coclass.gi b/gap/coclass.gi index fe053ad..4120865 100644 --- a/gap/coclass.gi +++ b/gap/coclass.gi @@ -1,272 +1,223 @@ ############################################################################# ## -#W coclass.gi Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2014 Andreas Distler & James D. Mitchell +## coclass.gi Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# -############################################################################# - InstallGlobalFunction(NilpotentSemigroupsByCoclass, -function(arg) - local n, d, r; # INPUT: order , coclass (and rank ) - - ### test input - - if Length(arg) < 2 or Length(arg) > 3 then - Error("number of arguments must be 2 or 3"); +function(arg...) + local n, d, r; + # INPUT: order , coclass (and rank ) + + if Length(arg) < 2 or Length(arg) > 3 then + Error("number of arguments must be 2 or 3"); + fi; + + n := arg[1]; + if not IsPosInt(n) then + Error("the order must be a positive integer"); + fi; + + d := arg[2]; + if not d in [0, 1, 2] then + Error("admissible values for the coclass are 0, 1 and 2"); + elif n <= d then + Info(InfoSmallsemi, 1, "Order does not exceed coclass."); + return []; + fi; + + if Length(arg) = 3 then + r := arg[3]; + if not r in [1, 2, 3] then + Error("admissable values for the rank are 1, 2 and 3"); + elif r = 1 and d <> 0 then + Info(InfoSmallsemi, 1, "Nilpotent semigroups are 1-generated ", + "if and only if they have coclass 0."); + return []; + elif d + 1 < r then + Info(InfoSmallsemi, 1, + "The rank is larger than the coclass plus one, +1."); + return []; fi; - - n := arg[1]; - if not IsPosInt(n) then - Error("the order must be a positive integer"); - fi; - - d := arg[2]; -# if not (IsPosInt(d) or d = 0) then -# Error("the coclass must be a non-negative integer"); - if not d in [0, 1, 2] then - Error("admissible values for the coclass are 0, 1 and 2"); - elif n <= d then - Info(InfoSmallsemi, 1, "Order does not exceed coclass."); - return [ ]; - fi; - - if Length(arg) = 3 then - r := arg[3]; - if not r in [1, 2, 3] then - Error("admissable values for the rank are 1, 2 and 3"); - fi; - if r = 1 and d <> 0 then - Info(InfoSmallsemi, 1, "Nilpotent semigroups are 1-generated ", - "if and only if they have coclass 0."); - return [ ]; - elif d+1 < r then - Info(InfoSmallsemi, 1, - "The rank is larger than the coclass plus one, +1."); - return [ ]; - fi; - fi; - - ### cases covered by current implementation - if d = 0 then - return NilpotentSemigroupsCoclass0(n); - elif d = 1 then - return NilpotentSemigroupsCoclass1(n); - elif d = 2 then - if Length(arg) = 2 then - return NilpotentSemigroupsCoclass2(n); - elif Length(arg) = 3 then - if r = 2 then - return NilpotentSemigroupsCoclass2Rank2(n); - elif r = 3 then - return NilpotentSemigroupsCoclass2Rank3(n); - fi; - fi; + fi; + + ### cases covered by current implementation + if d = 0 then + return NilpotentSemigroupsCoclass0(n); + elif d = 1 then + return NilpotentSemigroupsCoclass1(n); + elif d = 2 then + if Length(arg) = 2 then + return NilpotentSemigroupsCoclass2(n); + elif Length(arg) = 3 then + if r = 2 then + return NilpotentSemigroupsCoclass2Rank2(n); + elif r = 3 then + return NilpotentSemigroupsCoclass2Rank3(n); + fi; fi; + fi; end); - -############################################################################# -## ## returns a list with the presentation for the semigroup of order and ## coclass 0 -## -InstallGlobalFunction( NilpotentSemigroupsCoclass0, -function( n ) - local f, # free semigroup on one element - x; # generator of - - # catch input error - if not IsPosInt( n ) then - Error( "the size has to be a positive integer" ); - fi; +InstallGlobalFunction(NilpotentSemigroupsCoclass0, +function(n) + local f, # free semigroup on one element + x; # generator of - f := FreeSemigroup( 1 ); - x := GeneratorsOfSemigroup( f ); + # catch input error + if not IsPosInt(n) then + Error("the size has to be a positive integer"); + fi; - return [ f / [[ x[1]^n, x[1]^(n+1) ]] ]; -end); + f := FreeSemigroup(1); + x := GeneratorsOfSemigroup(f); + return [f / [[x[1] ^ n, x[1] ^ (n + 1)]]]; +end); -############################################################################# -## ## returns presentations for all semigroups of order and coclass 1 ## up to equivalence -## -InstallGlobalFunction( NilpotentSemigroupsCoclass1, -function( n ) - local sgrps, # list of all semigroups - f, # free semigroup on two elements - x, # generators of - k; # loop counter - - # catch input error - if not IsPosInt( n ) then - Error( "the size has to be a positive integer" ); - fi; - - f := FreeSemigroup( 2 ); - x := GeneratorsOfSemigroup( f ); - - # catch exceptional cases - if n <= 2 then - return [ ]; - - elif n = 3 then # the zero semigroup - return [ f / [[ x[1]^2, x[1]^3 ], # u^2 = u^3 - [ x[1]^2, x[2]^2 ], # u^2 = v^2 - [ x[1]^2, x[1]*x[2] ], # u^2 = uv - [ x[1]^2, x[2]*x[1] ] ]]; # u^2 = vu - fi; - - sgrps := NilpotentSemigroupsCoclassD_NC(n, 1); - - if n = 4 then # additional semigroups since 3-nilpotent - Add( sgrps, f / [[ x[1]^2, x[1]^3 ], # u^2 = u^3 - [ x[1]^2, x[2]^2 ], # u^2 = v^2 - [ x[1]^2, x[1]*x[2] ], # u^2 = uv - [ x[1]^2, x[2]^3 ] ] ); # u^2 = v^3 - Add( sgrps, f / [[ x[1]^2, x[1]^3 ], # u^2 = u^3 - [ x[1]^2, x[2]^2 ], # u^2 = v^2 - [ x[1]*x[2], x[2]*x[1] ], # uv = vu - [ x[1]^2, x[2]^3 ] ] ); # u^2 = v^3 - - fi; - - return sgrps; - # -# for k in [ 2..n-Int(n/2)-1 ] do -# Add( sgrps, f / [[ x[1]^(n-1), x[1]^n ], # u^n = u^(n-1) -# [ x[1]*x[2], x[2]*x[1]], # uv = vu -# [ x[1]*x[2], x[1]^k ], # uv = u^k -# [ x[2]^2, x[1]^(2*k-2) ]] ); # v^2 = u^(2k-2) -# od; -# -# for k in [ n-Int(n/2)..n-1 ] do # \{ \lceil n/2 \rceil, \dots, n-1 \} -# Add( sgrps, f / [[ x[1]^(n-1), x[1]^n ], # u^n = u^(n-1) -# [ x[1]*x[2], x[2]*x[1]], # uv = vu -# [ x[1]*x[2], x[1]^k ], # uv = u^k -# [ x[2]^2, x[1]^(n-2) ]] ); # v^2 = u^(n-2) -# Add( sgrps, f / [[ x[1]^(n-1), x[1]^n ], # u^n = u^(n-1) -# [ x[1]*x[2], x[2]*x[1]], # uv = vu -# [ x[1]*x[2], x[1]^k ], # uv = u^k -# [ x[2]^2, x[1]^(n-1) ]] ); # v^2 = u^(n-1) -# od; -# -# Add( sgrps, f / [[ x[1]^(n-1), x[1]^n ], # u^n = u^(n-1) -# [ x[1]*x[2], x[1]^(n-2) ], # uv = u^(n-2) -# [ x[2]*x[1], x[1]^(n-1) ], # vu = u^(n-1) -# [ x[2]^2, x[1]^(n-2) ]] ); # v^2 = u^(n-2) -# -# Add( sgrps, f / [[ x[1]^(n-1), x[1]^n ], # u^n = u^(n-1) -# [ x[1]*x[2], x[1]^(n-2) ], # uv = u^(n-2) -# [ x[2]*x[1], x[1]^(n-1) ], # vu = u^(n-1) -# [ x[2]^2, x[1]^(n-1) ]] ); # v^2 = u^(n-1) - +InstallGlobalFunction(NilpotentSemigroupsCoclass1, +function(n) + local sgrps, # list of all semigroups + f, # free semigroup on two elements + x; # generators of + + # catch input error + if not IsPosInt(n) then + Error("the size has to be a positive integer"); + fi; + + f := FreeSemigroup(2); + x := GeneratorsOfSemigroup(f); + + # catch exceptional cases + if n <= 2 then + return []; + + elif n = 3 then # the zero semigroup + return [f / [[x[1] ^ 2, x[1] ^ 3], # u ^ 2 = u ^ 3 + [x[1] ^ 2, x[2] ^ 2], # u ^ 2 = v ^ 2 + [x[1] ^ 2, x[1] * x[2]], # u ^ 2 = uv + [x[1] ^ 2, x[2] * x[1]]]]; # u ^ 2 = vu + fi; + + sgrps := NilpotentSemigroupsCoclassD_NC(n, 1); + + # additional semigroups since 3 - nilpotent + if n = 4 then + Add(sgrps, f / [[x[1] ^ 2, x[1] ^ 3], # u ^ 2 = u ^ 3 + [x[1] ^ 2, x[2] ^ 2], # u ^ 2 = v ^ 2 + [x[1] ^ 2, x[1] * x[2]], # u ^ 2 = uv + [x[1] ^ 2, x[2] ^ 3]]); # u ^ 2 = v ^ 3 + Add(sgrps, f / [[x[1] ^ 2, x[1] ^ 3], # u ^ 2 = u ^ 3 + [x[1] ^ 2, x[2] ^ 2], # u ^ 2 = v ^ 2 + [x[1] * x[2], x[2] * x[1]], # uv = vu + [x[1] ^ 2, x[2] ^ 3]]); # u ^ 2 = v ^ 3 + + fi; + + return sgrps; end); - -############################################################################# -## ## returns presentations for all semigroups of order and coclass 2 ## up to equivalence -## InstallGlobalFunction(NilpotentSemigroupsCoclass2, -function( n ) +function(n) return Concatenation(NilpotentSemigroupsCoclass2Rank3(n), NilpotentSemigroupsCoclass2Rank2(n)); end); - -############################################################################# -## ## returns presentations for all semigroups up to equivalence of order ## and coclass with +1 generators and (at least?) of those ## generating a monogenic semigroup of coclass -## -InstallGlobalFunction( NilpotentSemigroupsCoclassD_NC, -function( n, d ) - local sgrps, # list of all semigroups - f, # free semigroup on two elements - x, # generators of - basrels, # relations appearing for each semigroup - rels, # relations of a specific semigroup - i, j, k, m; # loop counter - - f := FreeSemigroup( d+1 ); - x := GeneratorsOfSemigroup( f ); - - sgrps := EmptyPlist( 5*n + Int(n/2) - 1 ); # HOW MANY? - - basrels := [ [ x[1]^(n-d), x[1]^(n-d+1) ] ]; - for i in [ 2..d ] do - Add( basrels, [ x[1]^2, x[i]^2 ] ); # u_1^2 = u_i^2 - Add( basrels, [ x[1]^2, x[1]*x[i] ] ); # u_1^2 = u_1u_i - Add( basrels, [ x[1]^2, x[i]*x[1] ] ); # u_1^2 = u_iu_1 - for j in [ i+1..d ] do - Add( basrels, [ x[1]^2, x[i]*x[j] ] ); # u_1^2 = u_iu_j - Add( basrels, [ x[1]^2, x[j]*x[i] ] ); # u_1^2 = u_ju_i +InstallGlobalFunction(NilpotentSemigroupsCoclassD_NC, +function(n, d) + local sgrps, # list of all semigroups + f, # free semigroup on two elements + x, # generators of + basrels, # relations appearing for each semigroup + rels, # relations of a specific semigroup + i, j, k, m; # loop counter + + f := FreeSemigroup(d + 1); + x := GeneratorsOfSemigroup(f); + + sgrps := EmptyPlist(5 * n + Int(n / 2) - 1); # HOW MANY? + + basrels := [[x[1] ^ (n - d), x[1] ^ (n - d + 1)]]; + for i in [2 .. d] do + Add(basrels, [x[1] ^ 2, x[i] ^ 2]); # u_1 ^ 2 = u_i ^ 2 + Add(basrels, [x[1] ^ 2, x[1] * x[i]]); # u_1 ^ 2 = u_1u_i + Add(basrels, [x[1] ^ 2, x[i] * x[1]]); # u_1 ^ 2 = u_iu_1 + for j in [i + 1 .. d] do + Add(basrels, [x[1] ^ 2, x[i] * x[j]]); # u_1 ^ 2 = u_iu_j + Add(basrels, [x[1] ^ 2, x[j] * x[i]]); # u_1 ^ 2 = u_ju_i od; od; - # - for k in [ 2..Int((n-d)/2) ] do - rels := ShallowCopy( basrels ); - for i in [ 1..d ] do - Add( rels, [ x[i]*x[d+1], x[d+1]*x[i] ] ); # u_iv = vu_i - Add( rels, [ x[i]*x[d+1], x[1]^k ] ); # u_iv = u_1^k + # + for k in [2 .. Int((n - d) / 2)] do + rels := ShallowCopy(basrels); + for i in [1 .. d] do + Add(rels, [x[i] * x[d + 1], x[d + 1] * x[i]]); # u_iv = vu_i + Add(rels, [x[i] * x[d + 1], x[1] ^ k]); # u_iv = u_1 ^ k od; - Add( rels, [ x[d+1]^2, x[1]^(2*k-2) ] ); # v^2 = u_1^(2k-2) - Add( sgrps, f / rels ); + Add(rels, [x[d + 1] ^ 2, x[1] ^ (2 * k - 2)]); # v ^ 2 = u_1 ^ (2k - 2) + Add(sgrps, f / rels); od; - for k in [ Int((n-d)/2)+1..n-d-2 ] do + for k in [Int((n - d) / 2) + 1 .. n - d - 2] do - rels := ShallowCopy( basrels ); - for i in [ 1..d ] do - Add( rels, [ x[i]*x[d+1], x[d+1]*x[i] ] ); # u_iv = vu_i - Add( rels, [ x[i]*x[d+1], x[1]^k ] ); # u_iv = u_1^k + rels := ShallowCopy(basrels); + for i in [1 .. d] do + Add(rels, [x[i] * x[d + 1], x[d + 1] * x[i]]); # u_iv = vu_i + Add(rels, [x[i] * x[d + 1], x[1] ^ k]); # u_iv = u_1 ^ k od; - Add( rels, [ x[d+1]^2, x[1]^(n-d) ] ); # v^2 = u_1^(n-d) - Add( sgrps, f / rels ); + Add(rels, [x[d + 1] ^ 2, x[1] ^ (n - d)]); # v ^ 2 = u_1 ^ (n - d) + Add(sgrps, f / rels); - Remove( rels ); - Add( rels, [ x[d+1]^2, x[1]^(n-d-1) ] ); # v^2 = u_1^(n-d-1) - Add( sgrps, f / rels ); + Remove(rels); + # v ^ 2 = u_1 ^ (n - d - 1) + Add(rels, [x[d + 1] ^ 2, x[1] ^ (n - d - 1)]); + Add(sgrps, f / rels); od; # 0 <= j <= k <= m <= d - for j in [ 0..d ] do - for k in [ j..d ] do - for m in [ Int((d+k+1)/2)..d ] do - - rels := ShallowCopy( basrels ); - for i in [ 1..j ] do - Add( rels, [ x[i]*x[d+1], x[1]^(n-d-1) ] ); - Add( rels, [ x[d+1]*x[i], x[1]^(n-d-1) ] ); + for j in [0 .. d] do + for k in [j .. d] do + for m in [Int((d + k + 1) / 2) .. d] do + + rels := ShallowCopy(basrels); + for i in [1 .. j] do + Add(rels, [x[i] * x[d + 1], x[1] ^ (n - d - 1)]); + Add(rels, [x[d + 1] * x[i], x[1] ^ (n - d - 1)]); od; - for i in [ j+1..k ] do - Add( rels, [ x[i]*x[d+1], x[1]^(n-d) ] ); - Add( rels, [ x[d+1]*x[i], x[1]^(n-d) ] ); + for i in [j + 1 .. k] do + Add(rels, [x[i] * x[d + 1], x[1] ^ (n - d)]); + Add(rels, [x[d + 1] * x[i], x[1] ^ (n - d)]); od; - for i in [ k+1..m ] do - Add( rels, [ x[i]*x[d+1], x[1]^(n-d) ] ); - Add( rels, [ x[d+1]*x[i], x[1]^(n-d-1) ] ); + for i in [k + 1 .. m] do + Add(rels, [x[i] * x[d + 1], x[1] ^ (n - d)]); + Add(rels, [x[d + 1] * x[i], x[1] ^ (n - d - 1)]); od; - for i in [ m+1..d ] do - Add( rels, [ x[i]*x[d+1], x[1]^(n-d-1) ] ); - Add( rels, [ x[d+1]*x[i], x[1]^(n-d) ] ); + for i in [m + 1 .. d] do + Add(rels, [x[i] * x[d + 1], x[1] ^ (n - d - 1)]); + Add(rels, [x[d + 1] * x[i], x[1] ^ (n - d)]); od; - Add( rels, [ x[d+1]^2, x[1]^(n-d) ] ); # v^2 = u_1^(n-d) - Add( sgrps, f / rels ); + Add(rels, [x[d + 1] ^ 2, x[1] ^ (n - d)]); # v ^ 2 = u_1 ^ (n - d) + Add(sgrps, f / rels); - Remove( rels ); - Add( rels, [ x[d+1]^2, x[1]^(n-d-1) ] ); # v^2 = u_1^(n-d-1) - Add( sgrps, f / rels ); + Remove(rels); + # v ^ 2 = u_1 ^ (n - d - 1) + Add(rels, [x[d + 1] ^ 2, x[1] ^ (n - d - 1)]); + Add(sgrps, f / rels); od; od; @@ -275,445 +226,441 @@ function( n, d ) return sgrps; end); - -############################################################################# -## ## returns presentations for all semigroups of order and coclass ## with +1 generators and of those generating a monogenic semigroup ## of coclass up to equivalence -## -InstallGlobalFunction( NilpotentSemigroupsCoclassD, -function( n, d ) - - # catch input errors - if not IsPosInt( n ) then - Error( "the size has to be a positive integer" ); - fi; - - if not IsPosInt( d ) then - Error( "the coclass has to be a positive integer" ); - fi; - # catch restriction of coclass value depending on order - if n < 4+d then - Error( "the difference of the order and the coclass ", - " must be at least 4" ); - fi; - - return NilpotentSemigroupsCoclassD_NC(n, d); +InstallGlobalFunction(NilpotentSemigroupsCoclassD, +function(n, d) + if not IsPosInt(n) then + Error("the size has to be a positive integer"); + elif not IsPosInt(d) then + Error("the coclass has to be a positive integer"); + # catch restriction of coclass value < d > depending on order < n > + elif n < 4 + d then + Error("the difference of the order and the coclass ", + " must be at least 4"); + fi; + + return NilpotentSemigroupsCoclassD_NC(n, d); end); -############################################################################# -## + ## obtain f.p.-presentation for a nilpotent semigroup of degree 3 from ## the library -## ## AD: WORKS ONLY FOR 3-GENERATED SEMIGROUPS OF ORDER 5 AT THE MOMENT -## -InstallGlobalFunction(IsomorphicFpSemigroup, -function( sgrp ) - local erz, # minimal generating set of - d, # minimal number of generators of - f, # free semigroup on generators - x, # generating set of - z, # multiplicative zero of - pairs, # list of 2-tuples with entries in [1..] - pos, # position of

in unmodified - p, # a pair that corresponds to a non-zero product in - rels, # relations of output semigroup isomorphic to - q; # loop counter, element in modified - - erz := MinimalGeneratingSet(sgrp); - d := Length(erz); - - f := FreeSemigroup(d); - x := GeneratorsOfSemigroup( f ); - - pairs := Reversed(Tuples([1..d], 2)); - - z := MultiplicativeZero(sgrp); - pos := PositionProperty(pairs, p-> z <> erz[p[1]]*erz[p[2]]); - p := Remove(pairs, pos); - - rels := EmptyPlist(d^2); - Add(rels, [ x[p[1]]*x[p[1]]*x[p[2]], x[p[1]]*x[p[1]]*x[p[1]]*x[p[2]] ]); - - for q in pairs do - if z = erz[q[1]]*erz[q[2]] then - Add(rels, [ x[p[1]]*x[p[1]]*x[p[2]], x[q[1]]*x[q[2]] ]); - else - Add(rels, [ x[p[1]]*x[p[2]], x[q[1]]*x[q[2]] ]); - fi; - od; - return f/rels; -end); +InstallGlobalFunction(IsomorphicFpSemigroup, +function(sgrp) + local erz, # minimal generating set of + d, # minimal number of generators of + f, # free semigroup on generators + x, # generating set of + z, # multiplicative zero of + pairs, # list of 2-tuples with entries in [1 .. ] + pos, # position of

in unmodified + p, # a pair that corresponds to a non - zero product in + rels, # relations of output semigroup isomorphic to < sgrp > + q; # loop counter, element in modified < pairs > + + erz := MinimalGeneratingSet(sgrp); + d := Length(erz); + + f := FreeSemigroup(d); + x := GeneratorsOfSemigroup(f); + + pairs := Reversed(Tuples([1 .. d], 2)); + + z := MultiplicativeZero(sgrp); + pos := PositionProperty(pairs, p -> z <> erz[p[1]] * erz[p[2]]); + p := Remove(pairs, pos); + + rels := EmptyPlist(d ^ 2); + Add(rels, + [x[p[1]] * x[p[1]] * x[p[2]], x[p[1]] * x[p[1]] * x[p[1]] * x[p[2]]]); + + for q in pairs do + if z = erz[q[1]] * erz[q[2]] then + Add(rels, [x[p[1]] * x[p[1]] * x[p[2]], x[q[1]] * x[q[2]]]); + else + Add(rels, [x[p[1]] * x[p[2]], x[q[1]] * x[q[2]]]); + fi; + od; + return f / rels; +end); -############################################################################# -## ## returns presentations for all semigroups of order and coclass 2 ## which have a minimal generating set of size 3 up to equivalence ## ## - implementing list from small coclass paper for n >= 6 ## - using the semigroups from the library for n = 5 -## -InstallGlobalFunction( NilpotentSemigroupsCoclass2Rank3, -function( n ) - local sgrps, # list of all semigroups - f, # free semigroup on two elements - x, # generators of - k, l, # loop counters - subsgrps, # list of candidates for V and W - v, w, # loop counters - V, W, # subsemigroups of size n-1 and coclass 1 - Vgens, # generators of the subsemigroup V - Wgens, # generators of the subsemigroup W - Vrels, # relations of the subsemigroup V - Wrels, # relations of the subsemigroup W - rels; # relations of a semigroup - - # catch input error - if not IsPosInt( n ) then - Error( "the size has to be a positive integer" ); - fi; - f := FreeSemigroup( 3 ); - x := GeneratorsOfSemigroup( f ); - - # catch exceptional cases - if n <= 3 then - return [ ]; - - elif n = 4 then # the zero semigroup - return [ f / [[ x[1]^2, x[1]^3 ], # u^2 = u^3 - [ x[1]^2, x[2]^2 ], # u^2 = v^2 - [ x[1]^2, x[1]*x[2] ], # u^2 = uv - [ x[1]^2, x[2]*x[1] ], # u^2 = vu - [ x[1]^2, x[3]^2 ], # u^2 = w^2 - [ x[1]^2, x[1]*x[3] ], # u^2 = uw - [ x[1]^2, x[3]*x[1] ], # u^2 = wu - [ x[1]^2, x[2]*x[3] ], # u^2 = vw - [ x[1]^2, x[3]*x[2] ], # u^2 = wv - [ x[1]^2, x[3]^2 ] ]]; # u^2 = w^2 - - elif n = 5 then # just take the semigroups from the library - return List(AllSmallSemigroups(5, - Is3GeneratedSemigroup, true, - NilpotencyDegree, 3), - IsomorphicFpSemigroup); - fi; +InstallGlobalFunction(NilpotentSemigroupsCoclass2Rank3, +function(n) + local sgrps, # list of all semigroups + f, # free semigroup on two elements + x, # generators of + k, l, # loop counters + subsgrps, # list of candidates for V and W + v, w, # loop counters + V, W, # subsemigroups of size n-1 and coclass 1 + Vgens, # generators of the subsemigroup V + Wgens, # generators of the subsemigroup W + Vrels, # relations of the subsemigroup V + Wrels, # relations of the subsemigroup W + rels; # relations of a semigroup + + # catch input error + if not IsPosInt(n) then + Error("the size < n > has to be a positive integer"); + fi; + + f := FreeSemigroup(3); + x := GeneratorsOfSemigroup(f); + + # catch exceptional cases + if n <= 3 then + return []; + elif n = 4 then + # the zero semigroup + return [f / [[x[1] ^ 2, x[1] ^ 3], # u ^ 2 = u ^ 3 + [x[1] ^ 2, x[2] ^ 2], # u ^ 2 = v ^ 2 + [x[1] ^ 2, x[1] * x[2]], # u ^ 2 = uv + [x[1] ^ 2, x[2] * x[1]], # u ^ 2 = vu + [x[1] ^ 2, x[3] ^ 2], # u ^ 2 = w ^ 2 + [x[1] ^ 2, x[1] * x[3]], # u ^ 2 = uw + [x[1] ^ 2, x[3] * x[1]], # u ^ 2 = wu + [x[1] ^ 2, x[2] * x[3]], # u ^ 2 = vw + [x[1] ^ 2, x[3] * x[2]], # u ^ 2 = wv + [x[1] ^ 2, x[3] ^ 2]]]; # u ^ 2 = w ^ 2 + elif n = 5 then + # just take the semigroups from the library + return List(AllSmallSemigroups(5, + Is3GeneratedSemigroup, true, + NilpotencyDegree, 3), + IsomorphicFpSemigroup); + fi; + + if IsEvenInt(n) then + sgrps := EmptyPlist((21 * n ^ 2 + 22 * n - 96) / 8); + else + sgrps := EmptyPlist((21 * n ^ 2 + 36 * n - 81) / 8); + fi; + + sgrps := NilpotentSemigroupsCoclassD_NC(n, 2); + + # get semigroups of size n - 1 and coclass 1 .. . + subsgrps := NilpotentSemigroupsCoclass1(n - 1); + # .. . in which the two generators are not interchangeable + Remove(subsgrps, 1); + + for v in [1 .. Length(subsgrps)] do + V := subsgrps[v]; + + # relations from V translated to new generators + Vgens := FreeGeneratorsOfFpSemigroup(V); + Vrels := List(RelationsOfFpSemigroup(V), + rel -> [MappedWord(rel[1], Vgens, x{[1, 2]}), + MappedWord(rel[2], Vgens, x{[1, 2]})]); + # u * v = u ^ k + k := ExtRepOfObj(Vrels[Length(Vrels) - 1][2])[2]; + + for w in [1 .. Length(subsgrps)] do + W := subsgrps[w]; + + # relations from W translated to new generators + Wgens := FreeGeneratorsOfFpSemigroup(W); + Wrels := List(RelationsOfFpSemigroup(W), + rel -> [MappedWord(rel[1], Wgens, x{[1, 3]}), + MappedWord(rel[2], Wgens, x{[1, 3]})]); + # first relation is already contained in + Remove(Wrels, 1); + # u * w = u ^ l + l := ExtRepOfObj(Wrels[Length(Wrels) - 1][2])[2]; + + rels := Concatenation(Vrels, Wrels); + + # Case 2.d + if w >= v and IsCommutative(V) and IsCommutative(W) then + if k + l <= n - 2 then + # vw = wv + Add(rels, [x[2] * x[3], x[3] * x[2]]); + # vw = u ^ (k + l - 2) + Add(rels, [x[2] * x[3], x[1] ^ (k + l - 2)]); + Add(sgrps, f / rels); + else + # vw = u ^ (k + l - 2) + Add(rels, [x[3] * x[2], x[1] ^ (n - 3)]); + # vw = u ^ (k + l - 2) + Add(rels, [x[2] * x[3], x[1] ^ (n - 3)]); + Add(sgrps, f / rels); + + Remove(rels); + + # vw = u ^ (k + l - 2) + Add(rels, [x[2] * x[3], x[1] ^ (n - 2)]); + Add(sgrps, f / rels); + + Remove(rels); + Remove(rels); + + # vw = u ^ (k + l - 2) + Add(rels, [x[3] * x[2], x[1] ^ (n - 2)]); + # vw = u ^ (k + l - 2) + Add(rels, [x[2] * x[3], x[1] ^ (n - 2)]); + Add(sgrps, f / rels); + fi; + elif not IsCommutative(V) and IsCommutative(W) then + # se 2.b and part of Case 2.a + Add(rels, [x[2] * x[3], x[1] ^ (n - 3)]); # vw = u ^ (n - 3) + Add(rels, [x[3] * x[2], x[1] ^ (n - 3)]); # wv = u ^ (n - 3) + Add(sgrps, f / rels); + + Remove(rels); + Add(rels, [x[3] * x[2], x[1] ^ (n - 2)]); # wv = u ^ (n - 2) + Add(sgrps, f / rels); + + Remove(rels); + Remove(rels); + Add(rels, [x[2] * x[3], x[1] ^ (n - 2)]); # vw = u ^ (n - 2) + Add(rels, [x[3] * x[2], x[1] ^ (n - 2)]); # wv = u ^ (n - 2) + Add(sgrps, f / rels); + + Remove(rels); + Add(rels, [x[3] * x[2], x[1] ^ (n - 3)]); # wv = u ^ (n - 3) + Add(sgrps, f / rels); + + elif v >= w and not IsCommutative(V) and not IsCommutative(W) then + # Case 2.a + Add(rels, [x[2] * x[3], x[1] ^ (n - 3)]); # vw = u ^ (n - 3) + Add(rels, [x[3] * x[2], x[1] ^ (n - 3)]); # wv = u ^ (n - 3) + Add(sgrps, f / rels); + + Remove(rels); + Add(rels, [x[3] * x[2], x[1] ^ (n - 2)]); # wv = u ^ (n - 2) + Add(sgrps, f / rels); + + Remove(rels); + Remove(rels); + Add(rels, [x[2] * x[3], x[1] ^ (n - 2)]); # vw = u ^ (n - 2) + Add(rels, [x[3] * x[2], x[1] ^ (n - 2)]); # wv = u ^ (n - 2) + Add(sgrps, f / rels); + + Remove(rels); + Add(rels, [x[3] * x[2], x[1] ^ (n - 3)]); # wv = u ^ (n - 3) + Add(sgrps, f / rels); + + if v = w then + Remove(sgrps); + fi; - if IsEvenInt( n ) then - sgrps := EmptyPlist( (21*n^2 + 22*n - 96) / 8 ); - else - sgrps := EmptyPlist( (21*n^2 + 36*n - 81) / 8 ); - fi; + # take dual of W + Wrels[Length(Wrels) - 2][2] := x[1] ^ (n - 3); + Wrels[Length(Wrels) - 1][2] := x[1] ^ (n - 2); - sgrps := NilpotentSemigroupsCoclassD_NC( n, 2 ); - - # get semigroups of size n-1 and coclass 1 ... - subsgrps := NilpotentSemigroupsCoclass1( n-1 ); - # ... in which the two generators are not interchangeable - Remove( subsgrps, 1 ); - - for v in [ 1..Length(subsgrps) ] do - V := subsgrps[v]; - - # relations from V translated to new generators - Vgens := FreeGeneratorsOfFpSemigroup(V); - Vrels := List( RelationsOfFpSemigroup(V), - rel-> [ MappedWord( rel[1], Vgens, x{[1,2]} ), - MappedWord( rel[2], Vgens, x{[1,2]} ) ]); - # u*v = u^k - k := ExtRepOfObj( Vrels[ Length(Vrels)-1 ][2] )[2]; - - for w in [ 1..Length(subsgrps) ] do - W := subsgrps[w]; - - # relations from W translated to new generators - Wgens := FreeGeneratorsOfFpSemigroup(W); - Wrels := List( RelationsOfFpSemigroup(W), - rel-> [ MappedWord( rel[1], Wgens, x{[1,3]} ), - MappedWord( rel[2], Wgens, x{[1,3]} ) ]); - # first relation is already contained in - Remove( Wrels, 1 ); - # u*w = u^l - l := ExtRepOfObj( Wrels[ Length(Wrels)-1 ][2] )[2]; - - rels := Concatenation( Vrels, Wrels ); - - # Case 2.d - if w >= v and IsCommutative(V) and IsCommutative(W) then - if k+l <= n-2 then - Add( rels, [ x[2]*x[3], x[3]*x[2] ] ); # vw = wv - Add( rels, [ x[2]*x[3], x[1]^(k+l-2) ] ); # vw = u^(k+l-2) - Add( sgrps, f / rels ); - - else - Add( rels, [ x[3]*x[2], x[1]^(n-3) ] ); # vw = u^(k+l-2) - Add( rels, [ x[2]*x[3], x[1]^(n-3) ] ); # vw = u^(k+l-2) - Add( sgrps, f / rels ); - - Remove( rels ); - Add( rels, [ x[2]*x[3], x[1]^(n-2) ] ); # vw = u^(k+l-2) - Add( sgrps, f / rels ); - - Remove( rels ); Remove( rels ); - Add( rels, [ x[3]*x[2], x[1]^(n-2) ] ); # vw = u^(k+l-2) - Add( rels, [ x[2]*x[3], x[1]^(n-2) ] ); # vw = u^(k+l-2) - Add( sgrps, f / rels ); - fi; - - # Case 2.b and part of Case 2.a - elif not IsCommutative(V) and IsCommutative(W) then - Add( rels, [ x[2]*x[3], x[1]^(n-3) ] ); # vw = u^(n-3) - Add( rels, [ x[3]*x[2], x[1]^(n-3) ] ); # wv = u^(n-3) - Add( sgrps, f / rels ); - - Remove( rels ); - Add( rels, [ x[3]*x[2], x[1]^(n-2) ] ); # wv = u^(n-2) - Add( sgrps, f / rels ); - - Remove( rels ); Remove( rels ); - Add( rels, [ x[2]*x[3], x[1]^(n-2) ] ); # vw = u^(n-2) - Add( rels, [ x[3]*x[2], x[1]^(n-2) ] ); # wv = u^(n-2) - Add( sgrps, f / rels ); - - Remove( rels ); - Add( rels, [ x[3]*x[2], x[1]^(n-3) ] ); # wv = u^(n-3) - Add( sgrps, f / rels ); - - # Case 2.a - elif v >= w and not IsCommutative(V) and not IsCommutative(W) then - Add( rels, [ x[2]*x[3], x[1]^(n-3) ] ); # vw = u^(n-3) - Add( rels, [ x[3]*x[2], x[1]^(n-3) ] ); # wv = u^(n-3) - Add( sgrps, f / rels ); - - Remove( rels ); - Add( rels, [ x[3]*x[2], x[1]^(n-2) ] ); # wv = u^(n-2) - Add( sgrps, f / rels ); - - Remove( rels ); Remove( rels ); - Add( rels, [ x[2]*x[3], x[1]^(n-2) ] ); # vw = u^(n-2) - Add( rels, [ x[3]*x[2], x[1]^(n-2) ] ); # wv = u^(n-2) - Add( sgrps, f / rels ); - - Remove( rels ); - Add( rels, [ x[3]*x[2], x[1]^(n-3) ] ); # wv = u^(n-3) - Add( sgrps, f / rels ); - - if v = w then - Remove( sgrps ); - fi; - - # take dual of W - Wrels[ Length(Wrels)-2 ][2] := x[1]^(n-3); - Wrels[ Length(Wrels)-1 ][2] := x[1]^(n-2); - - rels := Concatenation( Vrels, Wrels ); - - Add( rels, [ x[2]*x[3], x[1]^(n-3) ] ); # vw = u^(n-3) - Add( rels, [ x[3]*x[2], x[1]^(n-3) ] ); # wv = u^(n-3) - Add( sgrps, f / rels ); - - Remove( rels ); - Add( rels, [ x[3]*x[2], x[1]^(n-2) ] ); # wv = u^(n-2) - Add( sgrps, f / rels ); - - Remove( rels ); Remove( rels ); - Add( rels, [ x[2]*x[3], x[1]^(n-2) ] ); # vw = u^(n-2) - Add( rels, [ x[3]*x[2], x[1]^(n-2) ] ); # wv = u^(n-2) - Add( sgrps, f / rels ); - - Remove( rels ); - Add( rels, [ x[3]*x[2], x[1]^(n-3) ] ); # wv = u^(n-3) - Add( sgrps, f / rels ); - fi; - od; + rels := Concatenation(Vrels, Wrels); + + Add(rels, [x[2] * x[3], x[1] ^ (n - 3)]); # vw = u ^ (n - 3) + Add(rels, [x[3] * x[2], x[1] ^ (n - 3)]); # wv = u ^ (n - 3) + Add(sgrps, f / rels); + + Remove(rels); + Add(rels, [x[3] * x[2], x[1] ^ (n - 2)]); # wv = u ^ (n - 2) + Add(sgrps, f / rels); + + Remove(rels); + Remove(rels); + Add(rels, [x[2] * x[3], x[1] ^ (n - 2)]); # vw = u ^ (n - 2) + Add(rels, [x[3] * x[2], x[1] ^ (n - 2)]); # wv = u ^ (n - 2) + Add(sgrps, f / rels); + + Remove(rels); + Add(rels, [x[3] * x[2], x[1] ^ (n - 3)]); # wv = u ^ (n - 3) + Add(sgrps, f / rels); + fi; od; + od; - return sgrps; + return sgrps; end); -############################################################################# -## ## returns presentations for all semigroups of order and coclass 2 ## which have a minimal generating set of size 2 up to equivalence ## ## Implementing list from small coclass paper for n >= 7 -## -InstallGlobalFunction( NilpotentSemigroupsCoclass2Rank2, -function( n ) - local sgrps, # list of all semigroups - f, # free semigroup on two elements - x, # generators of - rels, # relations of a semigroup - k; # loop counter - - # catch input error - if not IsPosInt( n ) then - Error( "the size has to be a positive integer" ); - fi; - - # catch exceptional cases; for n > 4 see end of function - if n <= 4 then - return [ ]; - fi; - - f := FreeSemigroup( 2 ); - x := GeneratorsOfSemigroup( f ); - sgrps := EmptyPlist( 5*n + Int(n/2) - Int(n/3) - 1 ); # might be 1 too big - - # y = v^2 = uv = vu (third semigroup in Case 4, y = v^2) - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[2]*x[1]], # uv = vu - [ x[2]^2, x[1]*x[2] ], # v^2 = uv - [ x[2]^3, x[1]^(n-3) ]] ); # v^3 = u^(n-3) - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[2]*x[1]], # uv = vu - [ x[2]^2, x[1]*x[2] ], # v^2 = uv - [ x[2]^3, x[1]^(n-2) ]] ); # v^3 = u^(n-2) - - # y = uv = vu - for k in [ 3,4..Int( (n-1)/2 ) ] do - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[2]*x[1]], # uv = vu - [ x[2]^2, x[1]^(2*k-4) ], # v^2 = u^(2k-4) - [ x[1]^2*x[2], x[1]^k ]] ); # u^2v = u^k - od; - for k in [ n-Int(n/2)..n-2 ] do - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[2]*x[1]], # uv = vu - [ x[2]^2, x[1]^(n-4) ], # v^2 = u^(n-4) - [ x[1]^2*x[2], x[1]^k ]] ); # u^2v = u^k - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[2]*x[1]], # uv = vu - [ x[2]^2, x[1]^(n-3) ], # v^2 = u^(n-3) - [ x[1]^2*x[2], x[1]^k ]] ); # u^2v = u^k - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[2]*x[1]], # uv = vu - [ x[2]^2, x[1]^(n-2) ], # v^2 = u^(n-2) - [ x[1]^2*x[2], x[1]^k ]] ); # u^2v = u^k - od; - - # y = uv = v^2 - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[2]^2, x[1]*x[2] ], # v^2 = uv - [ x[2]*x[1], x[1]^2 ], # vu = u^2 - [ x[1]*x[2]^2, x[1]^3 ]] ); # uv^2 = u^3 - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[2]^2, x[1]*x[2] ], # v^2 = uv - [ x[2]*x[1], x[1]^(n-3) ], # vu = u^(n-3) - [ x[1]*x[2]^2, x[1]^(n-2) ]] ); # uv^2 = u^(n-2) - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[2]^2, x[1]*x[2] ], # v^2 = uv - [ x[2]*x[1], x[1]^(n-2) ], # vu = u^(n-2) - [ x[1]*x[2]^2, x[1]^(n-2) ]] ); # uv^2 = u^(n-2) - - # y = v^2 - for k in [ 2..n-2 ] do - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[2]*x[1]], # uv = vu - [ x[1]*x[2], x[1]^k ], # uv = u^k - [ x[2]^3, x[1]^(3*k-3) ]] ); # v^3 = u^(3k-3) - od; - for k in [ n-Int(2*n/3)..n-2 ] do - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[2]*x[1]], # uv = vu - [ x[1]*x[2], x[1]^k ], # uv = u^k - [ x[2]^3, x[1]^(n-3) ]] ); # v^3 = u^(n-3) - od; - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[1]^(n-3) ], # uv = u^(n-3) - [ x[2]*x[1], x[1]^(n-2) ], # vu = u^(n-2) - [ x[2]^3, x[1]^(n-3) ]] ); # v^3 = u^(n-3) - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[1]^(n-3) ], # uv = u^(n-3) - [ x[2]*x[1], x[1]^(n-2) ], # vu = u^(n-2) - [ x[2]^3, x[1]^(n-2) ]] ); # v^3 = u^(n-2) - - # y = vu - for k in [ 2..n-Int((n+1)/2)-1 ] do - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[1]^k ], # uv = u^k - [ x[2]^2, x[1]^(2*k-2) ], # v^2 = u^(2k-2) - [ x[2]*x[1]^2, x[1]^(k+1) ]] ); # vu^2 = u^(k+1) - od; - for k in [ n-Int((n+1)/2)..n-2 ] do - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[1]^k ], # uv = u^k - [ x[2]^2, x[1]^(n-2) ], # v^2 = u^(n-2) - [ x[2]*x[1]^2, x[1]^(k+1) ]] ); # vu^2 = u^(k+1) - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[1]^k ], # uv = u^k - [ x[2]^2, x[1]^(n-3) ], # v^2 = u^(n-3) - [ x[2]*x[1]^2, x[1]^(k+1) ]] ); # vu^2 = u^(k+1) - od; - for k in [ n-3..n-2 ] do - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[1]^(n-4) ], # uv = u^(n-4) - [ x[2]^2, x[1]^k ], # v^2 = u^k - [ x[2]*x[1]^2, x[1]^(n-2) ]] ); # vu^2 = u^(n-2) - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[1]^(n-3) ], # uv = u^(n-3) - [ x[2]^2, x[1]^k ], # v^2 = u^k - [ x[2]*x[1]^2, x[1]^(n-3) ]] ); # vu^2 = u^(n-3) - Add( sgrps, f / [[ x[1]^(n-1), x[1]^(n-2) ], # u^(n-2) = u^(n-1) - [ x[1]*x[2], x[1]^(n-2) ], # uv = u^(n-2) - [ x[2]^2, x[1]^k ], # v^2 = u^k - [ x[2]*x[1]^2, x[1]^(n-3) ]] ); # vu^2 = u^(n-3) - od; - - if n = 5 then - sgrps := sgrps{[ 17, 15, 5, 18, 16, 4, 10, 8, 2, 6 ]}; - Add(sgrps, f / [[ x[1]^2, x[1]^2*x[2] ], # u^2 = u^2v - [ x[2]^2, x[1]^2*x[2] ], # v^2 = u^2v - [ x[1]*x[2]*x[1], x[1]^2*x[2] ], # uvu = u^2v - [ x[2]*x[1]*x[2], (x[1]*x[2])^2 ]] ); # vuv = (uv)^2 - fi; - - if n = 6 then - sgrps := sgrps{[ 23, 21, 8, 30, 29, 5, 6, 20, 3, 24, 22, 7, 27, 26, 14, - 11, 19, 2, 10, 13, 4, 17, 18, 16, 1, 9 ]}; - rels := [[ x[1]^2, x[1]^3 ], # u^2 = u^3 - [ x[1]^2, x[2]^2 ], # u^2 = v^2 - [ x[1]^2, x[1]*x[2]*x[1] ], # u^2 = uvu - [ x[1]*x[2]*x[1], x[2]*x[1]*x[2] ], # uvu = vuv - [ x[1]^2, x[2]^3 ], # u^2 = v^3 - [ x[2]^2, x[2]*x[1]*x[2] ], # v^2 = vuv - [ x[1]^2, x[2]*x[1] ], # u^2 = vu - [ x[2]*x[1], x[1]*x[2]^2 ], # vu = uv^2 - [ x[2]^2, x[1]*x[2]*x[1] ], # v^2 = uvu - [ x[1]^2, x[2]*x[1]*x[2] ], # u^2 = vuv - [ x[2]^2, x[2]*x[1] ], # v^2 = vu - [ x[1]*x[2], x[2]*x[1] ], # uv = vu - [ x[1]^2*x[2], x[1]^2 ], # u^2v = u^2 - [ x[1]^3, x[1]*x[2]*x[1] ], # u^3 = uvu - [ x[1]^3, x[2]^3 ], # u^3 = v^3 - [ x[1]*x[2]^2, x[1]^2 ], # uv^2 = u^2 - [ x[2]*x[1], x[2]*x[1]^2 ], # vu = vu^2 - [ x[1]^2*x[2], x[1]^3 ], # u^2v = u^3 - [ x[1]*x[2], x[1]^2 ], # uv = u^2 - [ x[2]*x[1]^3, x[1]^3 ]]; # vu^3 = u^3 - - Add(sgrps, f / rels{[1, 2, 3]}); # [6, 42] - Add(sgrps, f / rels{[1, 2, 4]}); # [6, 141] - Add(sgrps, f / rels{[3, 5, 6]}); # [6, 338] - Add(sgrps, f / rels{[1, 5, 7]}); # [6, 413] - Add(sgrps, f / rels{[1, 5, 8]}); # [6, 414] - Add(sgrps, f / rels{[5, 9, 10]}); # [6, 481] - Add(sgrps, f / rels{[1, 5, 11]}); # [6, 583] - Add(sgrps, f / rels{[5, 6, 9]}); # [6, 659] - Add(sgrps, f / rels{[1, 5, 12, 13]}); # [6, 880] - Add(sgrps, f / rels{[2, 10, 14]}); # [6, 1485] - Add(sgrps, f / rels{[2, 3, 10]}); # [6, 1865] - Add(sgrps, f / rels{[15, 16, 17]}); # [6, 2416] - Add(sgrps, f / rels{[7, 15, 16]}); # [6, 2417] - Add(sgrps, f / rels{[11, 15, 16]}); # [6, 2494] - Add(sgrps, f / rels{[12, 15, 16, 18]}); # [6, 2556] - Add(sgrps, f / rels{[11, 19, 20]}); # [6, 2558] - Add(sgrps, f / rels{[11, 12, 20]}); # [6, 2559] - fi; - - return sgrps; +InstallGlobalFunction(NilpotentSemigroupsCoclass2Rank2, +function(n) + local sgrps, # list of all semigroups + f, # free semigroup on two elements + x, # generators of + rels, # relations of a semigroup + k; # loop counter + + if not IsPosInt(n) then + Error("the size < n > has to be a positive integer"); + fi; + + # catch exceptional cases; for n > 4 see end of function + if n <= 4 then + return []; + fi; + + f := FreeSemigroup(2); + x := GeneratorsOfSemigroup(f); + + # might be 1 too big + sgrps := EmptyPlist(5 * n + Int(n / 2) - Int(n / 3) - 1); + + # y = v^2 = uv = vu (third semigroup in Case 4, y = v^2) + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n - 2) = u ^ (n - 1) + [x[1] * x[2], x[2] * x[1]], # uv = vu + [x[2] ^ 2, x[1] * x[2]], # v ^ 2 = uv + [x[2] ^ 3, x[1] ^ (n - 3)]]); # v ^ 3 = u ^ (n - 3) + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n - 2) = u ^ (n - 1) + [x[1] * x[2], x[2] * x[1]], # uv = vu + [x[2] ^ 2, x[1] * x[2]], # v ^ 2 = uv + [x[2] ^ 3, x[1] ^ (n - 2)]]); # v ^ 3 = u ^ (n - 2) + + # y = uv = vu + for k in [3, 4 .. Int((n - 1) / 2)] do + # u ^ (n - 2) = u ^ (n - 1) + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], + [x[1] * x[2], x[2] * x[1]], # uv = vu + [x[2] ^ 2, x[1] ^ (2 * k - 4)], # v ^ 2 = u ^ (2k - 4) + [x[1] ^ 2 * x[2], x[1] ^ k]]); # u ^ 2v = u ^ k + od; + for k in [n - Int(n / 2) .. n - 2] do + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[2] * x[1]], # uv=vu + [x[2] ^ 2, x[1] ^ (n - 4)], # v^2 =u^(n-4) + [x[1] ^ 2 * x[2], x[1] ^ k]]); # u^2v=u^k + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[2] * x[1]], # uv=vu + [x[2] ^ 2, x[1] ^ (n - 3)], # v^2=u^(n-3) + [x[1] ^ 2 * x[2], x[1] ^ k]]); # u^2v=u^k + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n - 1) + [x[1] * x[2], x[2] * x[1]], # uv=vu + [x[2] ^ 2, x[1] ^ (n - 2)], # v^2=u^(n-2) + [x[1] ^ 2 * x[2], x[1] ^ k]]); # u^2v=u^k + od; + + # y = uv = v ^ 2 + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[2] ^ 2, x[1] * x[2]], # v^2=uv + [x[2] * x[1], x[1] ^ 2], # vu=u^2 + [x[1] * x[2] ^ 2, x[1] ^ 3]]); # uv^2=u^3 + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[2] ^ 2, x[1] * x[2]], # v^2=uv + [x[2] * x[1], x[1] ^ (n - 3)], # vu=u^(n-3) + [x[1] * x[2] ^ 2, x[1] ^ (n - 2)]]); # uv^2=u^(n-2) + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[2] ^ 2, x[1] * x[2]], # v^2=uv + [x[2] * x[1], x[1] ^ (n - 2)], # vu=u^(n-2) + [x[1] * x[2] ^ 2, x[1] ^ (n - 2)]]); # uv^2=u^(n-2) + + # y = v ^ 2 + for k in [2 .. n - 2] do + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[2] * x[1]], # uv=vu + [x[1] * x[2], x[1] ^ k], # uv=u^k + [x[2] ^ 3, x[1] ^ (3 * k - 3)]]); # v^3=u^(3k-3) + od; + for k in [n - Int(2 * n / 3) .. n - 2] do + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[2] * x[1]], # uv=vu + [x[1] * x[2], x[1] ^ k], # uv=u^k + [x[2] ^ 3, x[1] ^ (n - 3)]]); # v^3=u^(n-3) + od; + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[1] ^ (n - 3)], # uv=u^(n-3) + [x[2] * x[1], x[1] ^ (n - 2)], # vu=u^(n-2) + [x[2] ^ 3, x[1] ^ (n - 3)]]); # v^3=u^(n-3) + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[1] ^ (n - 3)], # uv=u^(n-3) + [x[2] * x[1], x[1] ^ (n - 2)], # vu=u^(n-2) + [x[2] ^ 3, x[1] ^ (n - 2)]]); # v^3=u^(n-2) + + # y=vu + for k in [2 .. n - Int((n + 1) / 2) - 1] do + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[1] ^ k], # uv=u^k + [x[2] ^ 2, x[1] ^ (2 * k - 2)], # v^2=u^(2k-2) + [x[2] * x[1] ^ 2, x[1] ^ (k + 1)]]); # vu^2=u^(k+1) + od; + for k in [n - Int((n + 1) / 2) .. n - 2] do + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[1] ^ k], # uv=u^k + [x[2] ^ 2, x[1] ^ (n - 2)], # v^2=u^(n-2) + [x[2] * x[1] ^ 2, x[1] ^ (k + 1)]]); # vu^2=u^(k+1) + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[1] ^ k], # uv=u^k + [x[2] ^ 2, x[1] ^ (n - 3)], # v^2=u^(n-3) + [x[2] * x[1] ^ 2, x[1] ^ (k + 1)]]); # vu^2=u^(k+1) + od; + for k in [n - 3 .. n - 2] do + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[1] ^ (n - 4)], # uv=u^(n-4) + [x[2] ^ 2, x[1] ^ k], # v^2=u^k + [x[2] * x[1] ^ 2, x[1] ^ (n - 2)]]); # vu^2=u^(n-2) + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[1] ^ (n - 3)], # uv=u^(n-3) + [x[2] ^ 2, x[1] ^ k], # v^2=u^k + [x[2] * x[1] ^ 2, x[1] ^ (n - 3)]]); # vu^2=u^(n-3) + Add(sgrps, f / [[x[1] ^ (n - 1), x[1] ^ (n - 2)], # u^(n-2)=u^(n-1) + [x[1] * x[2], x[1] ^ (n - 2)], # uv=u^(n-2) + [x[2] ^ 2, x[1] ^ k], # v^2=u^k + [x[2] * x[1] ^ 2, x[1] ^ (n - 3)]]); # vu^2=u^(n-3) + od; + + if n = 5 then + sgrps := sgrps{[17, 15, 5, 18, 16, 4, 10, 8, 2, 6]}; + Add(sgrps, f / [[x[1] ^ 2, x[1] ^ 2 * x[2]], # u^2=u^2v + [x[2] ^ 2, x[1] ^ 2 * x[2]], # v^2=u^2v + [x[1] * x[2] * x[1], x[1] ^ 2 * x[2]], # uvu=u^2v + [x[2] * x[1] * x[2], (x[1] * x[2]) ^ 2]]); # vuv=(uv)^2 + fi; + + if n = 6 then + sgrps := sgrps{[23, 21, 8, 30, 29, 5, 6, 20, 3, 24, 22, 7, 27, 26, 14, + 11, 19, 2, 10, 13, 4, 17, 18, 16, 1, 9]}; + rels := [[x[1] ^ 2, x[1] ^ 3], # u^2=u^3 + [x[1] ^ 2, x[2] ^ 2], # u^2=v^2 + [x[1] ^ 2, x[1] * x[2] * x[1]], # u^2=uvu + [x[1] * x[2] * x[1], x[2] * x[1] * x[2]], # uvu=vuv + [x[1] ^ 2, x[2] ^ 3], # u^2=v^3 + [x[2] ^ 2, x[2] * x[1] * x[2]], # v^2=vuv + [x[1] ^ 2, x[2] * x[1]], # u^2=vu + [x[2] * x[1], x[1] * x[2] ^ 2], # vu=uv^2 + [x[2] ^ 2, x[1] * x[2] * x[1]], # v^2=uvu + [x[1] ^ 2, x[2] * x[1] * x[2]], # u^2=vuv + [x[2] ^ 2, x[2] * x[1]], # v^2=vu + [x[1] * x[2], x[2] * x[1]], # uv=vu + [x[1] ^ 2 * x[2], x[1] ^ 2], # u^2v=u^2 + [x[1] ^ 3, x[1] * x[2] * x[1]], # u^3=uvu + [x[1] ^ 3, x[2] ^ 3], # u^3=v^3 + [x[1] * x[2] ^ 2, x[1] ^ 2], # uv^2=u^2 + [x[2] * x[1], x[2] * x[1] ^ 2], # vu=vu^2 + [x[1] ^ 2 * x[2], x[1] ^ 3], # u^2v=u^3 + [x[1] * x[2], x[1] ^ 2], # uv=u^2 + [x[2] * x[1] ^ 3, x[1] ^ 3]]; # vu^3=u^3 + + Add(sgrps, f / rels{[1, 2, 3]}); # [6, 42] + Add(sgrps, f / rels{[1, 2, 4]}); # [6, 141] + Add(sgrps, f / rels{[3, 5, 6]}); # [6, 338] + Add(sgrps, f / rels{[1, 5, 7]}); # [6, 413] + Add(sgrps, f / rels{[1, 5, 8]}); # [6, 414] + Add(sgrps, f / rels{[5, 9, 10]}); # [6, 481] + Add(sgrps, f / rels{[1, 5, 11]}); # [6, 583] + Add(sgrps, f / rels{[5, 6, 9]}); # [6, 659] + Add(sgrps, f / rels{[1, 5, 12, 13]}); # [6, 880] + Add(sgrps, f / rels{[2, 10, 14]}); # [6, 1485] + Add(sgrps, f / rels{[2, 3, 10]}); # [6, 1865] + Add(sgrps, f / rels{[15, 16, 17]}); # [6, 2416] + Add(sgrps, f / rels{[7, 15, 16]}); # [6, 2417] + Add(sgrps, f / rels{[11, 15, 16]}); # [6, 2494] + Add(sgrps, f / rels{[12, 15, 16, 18]}); # [6, 2556] + Add(sgrps, f / rels{[11, 19, 20]}); # [6, 2558] + Add(sgrps, f / rels{[11, 12, 20]}); # [6, 2559] + fi; + return sgrps; end); diff --git a/gap/enums.gd b/gap/enums.gd index 982d3c9..346c683 100644 --- a/gap/enums.gd +++ b/gap/enums.gd @@ -1,1026 +1,918 @@ ############################################################################# ## -#W enums.gd Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2014 Andreas Distler & James D. Mitchell +## enums.gd Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# ## - -########################################################################### -## -## <#GAPDoc Label="AllSmallSemigroups"> -## -## -## -## the number of argument of this function should be odd. The first argument -## arg[1] should be a positive integer, an -## enumerator of small semigroups with , or an iterator -## of small semigroup with .

-## -## The even -## arguments arg[2i], if present, should be functions, and the odd -## arguments arg[2i+1] should be a value that the preceeding function -## can have. For example, a typical input might be -## 3, IsRegularSemigroup, true. The functions arg[2i] can be user -## defined or existing &GAP; functions.

-## -## Please see Section or Chapter for more details.

-## -## If arg[1] is a positive integer, then AllSmallSemigroups returns -## a list of all the small semigroups S in the -## library with Size(S)=arg[1] and arg[2i](S)=arg[2i+1] for all i.

-## -## If arg[1] is a list of positive integers, then AllSmallSemigroups returns -## a list of all the small semigroups S in the -## library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] for all i.

-## -## If arg[1] is an enumerator or iterator of small semigroups, then -## AllSmallSemigroups returns -## a list of all the small semigroups S in the -## library with S in arg[1] and arg[2i](S)=arg[2i+1] for all i.

-## AllSmallSemigroups(2); -## [ , , -## , ] -## gap> AllSmallSemigroups([2,3], IsRegularSemigroup, true, -## > x-> Length(GreensRClasses(x)), 1); -## [ , ] -## gap> enum:=EnumeratorOfSmallSemigroups(8, IsInverseSemigroup, true, -## > IsCommutativeSemigroup, true);; -## gap> AllSmallSemigroups(enum, x-> Length(GreensRClasses(x)), 1); -## [ , , -## ] -## gap> iter:=IteratorOfSmallSemigroups(7, x-> Length(GreensRClasses(x)), 1);; -## gap> AllSmallSemigroups(iter, IsCommutative, true, -## > IsSimpleSemigroup, true); -## [ ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="AllSmallSemigroups"> +# +# +# +# the number of argument of this function should be odd. The first argument +# arg[1] should be a positive integer, an enumerator of small semigroups +# with , or an iterator of small +# semigroup with . +#

+# +# The even arguments arg[2i], if present, should be functions, and the +# odd arguments arg[2i+1] should be a value that the preceeding function +# can have. For example, a typical input might be 3, IsRegularSemigroup, +# true. The functions arg[2i] can be user defined or existing &GAP; +# functions. +#

+# +# Please see Section or Chapter for +# more details. +#

+# +# If arg[1] is a positive integer, then AllSmallSemigroups +# returns a list of all the small semigroups S in the library with +# Size(S)=arg[1] and arg[2i](S)=arg[2i+1] for all i. +#

+# +# If arg[1] is a list of positive integers, then +# AllSmallSemigroups returns a list of all the small semigroups S +# in the library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] +# for all i. +#

+# +# If arg[1] is an enumerator or iterator of small semigroups, then +# AllSmallSemigroups returns a list of all the small semigroups S +# in the library with S in arg[1] and arg[2i](S)=arg[2i+1] for +# all i. +# +# AllSmallSemigroups(2); +# [ , , +# , ] +# gap> AllSmallSemigroups([2,3], IsRegularSemigroup, true, +# > x-> Length(GreensRClasses(x)), 1); +# [ , ] +# gap> enum:=EnumeratorOfSmallSemigroups(8, IsInverseSemigroup, true, +# > IsCommutativeSemigroup, true);; +# gap> AllSmallSemigroups(enum, x-> Length(GreensRClasses(x)), 1); +# [ , , +# ] +# gap> iter:=IteratorOfSmallSemigroups(7, x-> Length(GreensRClasses(x)), 1);; +# gap> AllSmallSemigroups(iter, IsCommutative, true, +# > IsSimpleSemigroup, true); +# [ ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("AllSmallSemigroups"); -########################################################################### -## -## <#GAPDoc Label="EmptyEnumeratorOfSmallSemigroups"> -## -## -## -## the argument should be empty and the returned enumerator is too.

-## -## EmptyEnumeratorOfSmallSemigroups(); -## -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="EmptyEnumeratorOfSmallSemigroups"> +# +# +# +# the argument should be empty and the returned enumerator is too. +# +# EmptyEnumeratorOfSmallSemigroups(); +# +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("EmptyEnumeratorOfSmallSemigroups"); -########################################################################### -## -## <#GAPDoc Label="EmptyIteratorOfSmallSemigroups"> -## -## -## -## the argument should be empty and the returned iterator is too.

-## -## EmptyIteratorOfSmallSemigroups(); -## -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="EmptyIteratorOfSmallSemigroups"> +# +# +# +# the argument should be empty and the returned iterator is too. +# +# EmptyIteratorOfSmallSemigroups(); +# +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("EmptyIteratorOfSmallSemigroups"); -########################################################################### -## -## <#GAPDoc Label="EnumeratorOfSmallSemigroups"> -## -## -## -## the number of argument of this function should be odd. The first argument -## arg[1] should be a positive integer, an -## enumerator of small semigroups with , or an iterator -## of small semigroup with .

-## -## The even -## arguments arg[2i], if present, should be functions, and the odd -## arguments arg[2i+1] should be a value that the preceeding function -## can have. For example, a typical input might be -## 3, IsRegularSemigroup, true. The functions arg[2i] can be user -## defined or existing &GAP; functions.

-## -## Please see Section or Chapter for more details.

-## -## If arg[1] is a positive integer, then EnumeratorOfSmallSemigroups returns -## an enumerator of all the small semigroups S in the -## library with Size(S)=arg[1] and arg[2i](S)=arg[2i+1] for all i.

-## -## If arg[1] is a list of positive integers, then EnumeratorOfSmallSemigroups returns -## an enumerator of all the small semigroups S in the -## library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] for all i.

-## -## If arg[1] is an enumerator or iterator of small semigroups, then -## EnumeratorOfSmallSemigroups returns -## an enumerator of all the small semigroups S in the -## library with S in arg[1] and arg[2i](S)=arg[2i+1] for all i.

-## enum:=EnumeratorOfSmallSemigroups(7); -## -## gap> EnumeratorOfSmallSemigroups([2,3], IsRegularSemigroup, true); -## -## gap> enum:=EnumeratorOfSmallSemigroups(8, IsInverseSemigroup, true, -## > IsCommutativeSemigroup, true); -## -## gap> EnumeratorOfSmallSemigroups(enum, IsCommutativeSemigroup, true, -## > IsSimpleSemigroup, false); -## -## gap> iter:=IteratorOfSmallSemigroups(8); -## -## gap> EnumeratorOfSmallSemigroups(iter, IsCommutativeSemigroup, true, -## > IsSimpleSemigroup, false); -## -## ]]> -## -## -## <#/GAPDoc> +# <#GAPDoc Label="EnumeratorOfSmallSemigroups"> +# +# +# +# the number of argument of this function should be odd. The first argument +# arg[1] should be a positive integer, an enumerator of small semigroups +# with , or an iterator of small +# semigroup with . +#

+# +# The even arguments arg[2i], if present, should be functions, and the +# odd arguments arg[2i+1] should be a value that the preceeding function +# can have. For example, a typical input might be 3, IsRegularSemigroup, +# true. The functions arg[2i] can be user defined or existing &GAP; +# functions. +#

+# +# Please see Section or Chapter for +# more details. +#

+# +# If arg[1] is a positive integer, then +# EnumeratorOfSmallSemigroups returns an enumerator of all the small +# semigroups S in the library with Size(S)=arg[1] and +# arg[2i](S)=arg[2i+1] for all i. +#

+# +# If arg[1] is a list of positive integers, then +# EnumeratorOfSmallSemigroups returns an enumerator of all the small +# semigroups S in the library with Size(S) in arg[1] and +# arg[2i](S)=arg[2i+1] for all i. +#

+# +# If arg[1] is an enumerator or iterator of small semigroups, then +# EnumeratorOfSmallSemigroups returns an enumerator of all the small +# semigroups S in the library with S in arg[1] and +# arg[2i](S)=arg[2i+1] for all i. +# +# enum:=EnumeratorOfSmallSemigroups(7); +# +# gap> EnumeratorOfSmallSemigroups([2,3], IsRegularSemigroup, true); +# +# gap> enum:=EnumeratorOfSmallSemigroups(8, IsInverseSemigroup, true, +# > IsCommutativeSemigroup, true); +# +# gap> EnumeratorOfSmallSemigroups(enum, IsCommutativeSemigroup, true, +# > IsSimpleSemigroup, false); +# +# gap> iter:=IteratorOfSmallSemigroups(8); +# +# gap> EnumeratorOfSmallSemigroups(iter, IsCommutativeSemigroup, true, +# > IsSimpleSemigroup, false); +# +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("EnumeratorOfSmallSemigroups"); -########################################################################### -## -## <#GAPDoc Label="EnumeratorOfSmallSemigroupsByIds"> -## -## -## -## -## the argument of this function should be one of the following: -## -## a positive integer arg[1] and a set of positive integers less -## than with argument arg[1]. For -## example, the argument 3, [1..10] yields the first 10 semigroups with -## 3 elements. -## -## a set of positive integers arg[1] and a list of sets of -## positive integers arg[2] such that x is at most -## with argument arg[1][i] for all -## x in arg[2][i]. For example, -## [2,3], [[1..2],[1..10]] yields the first 2 semigroups of size 2, -## and the first 10 semigroups of size 3. -## a list of id numbers, for example, [[7,1], [6,1], [5,1]]. -## -## The no check version does not check that the arguments are valid and may return unpredictable -## results. -## -## enum:=EnumeratorOfSmallSemigroupsByIds([[7,1],[6,1],[5,1]]); -## -## gap> enum:=EnumeratorOfSmallSemigroupsByIds(7, [1..1000]); -## -## gap> enum:=EnumeratorOfSmallSemigroupsByIds([2,3], [[1..2],[1..10]]); -## -## ]]> -## -## -## <#/GAPDoc> - -DeclareOperation("EnumeratorOfSmallSemigroupsByIds", [IsCyclotomicCollection , IsCyclotomicCollColl]); - -DeclareOperation("EnumeratorOfSmallSemigroupsByIdsNC", [IsCyclotomicCollection , IsCyclotomicCollColl]); - -############################################################################# -## -## EnumeratorOfSmallSemigroupsByDiagonals -## -## should become obsolete in 0.7 and is therefore undocumented -## - +# <#GAPDoc Label="EnumeratorOfSmallSemigroupsByIds"> +# +# +# +# +# the argument of this function should be one of the following: +# +# +# a positive integer arg[1] and a set of positive integers less than +# with argument arg[1]. For example, +# the argument 3, [1..10] yields the first 10 semigroups with +# 3 elements. +# +# +# a set of positive integers arg[1] and a list of sets of positive +# integers arg[2] such that x is at most with argument arg[1][i] for all +# x in arg[2][i]. For example, [2,3], [[1..2],[1..10]] +# yields the first 2 semigroups of size 2, and the first 10 semigroups of +# size 3. +# +# +# a list of id numbers, for example, [[7,1], [6,1], [5,1]]. +# +# +# The no check version does not check that the arguments are valid and may +# return unpredictable results. +# +# enum:=EnumeratorOfSmallSemigroupsByIds([[7,1],[6,1],[5,1]]); +# +# gap> enum:=EnumeratorOfSmallSemigroupsByIds(7, [1..1000]); +# +# gap> enum:=EnumeratorOfSmallSemigroupsByIds([2,3], [[1..2],[1..10]]); +# +# ]]> +# +# +# <#/GAPDoc> +DeclareOperation("EnumeratorOfSmallSemigroupsByIds", + [IsCyclotomicCollection, IsCyclotomicCollColl]); +DeclareOperation("EnumeratorOfSmallSemigroupsByIds", + [IsPosInt, IsCyclotomicCollection]); +DeclareOperation("EnumeratorOfSmallSemigroupsByIds", + [IsList]); + +DeclareOperation("EnumeratorOfSmallSemigroupsByIdsNC", + [IsCyclotomicCollection, IsCyclotomicCollColl]); +DeclareOperation("EnumeratorOfSmallSemigroupsByIdsNC", + [IsPosInt, IsCyclotomicCollection]); + +## TODO document DeclareGlobalFunction("EnumeratorOfSmallSemigroupsByDiagonals"); -########################################################################### -## -## <#GAPDoc Label="EnumeratorSortedOfSmallSemigroups"> -## -## -## -## accepts the same arguments and returns the same values as -## . -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="EnumeratorSortedOfSmallSemigroups"> +# +# +# +# accepts the same arguments and returns the same values as +# . +# +# +# <#/GAPDoc> DeclareGlobalFunction("EnumeratorSortedOfSmallSemigroups"); -########################################################################### -## -## <#GAPDoc Label="IdsOfSmallSemigroups"> -## -## -## -## the number of argument of this function should be odd. The first argument -## arg[1] should be a positive integer, an -## enumerator of small semigroups with , or an iterator -## of small semigroup with .

-## -## The even -## arguments arg[2i], if present, should be functions, and the odd -## arguments arg[2i+1] should be a value that the preceeding function -## can have. For example, a typical input might be -## 3, IsRegularSemigroup, true. The functions arg[2i] can be user -## defined or existing &GAP; functions.

-## -## Please see Section or Chapter for more details.

-## -## If arg[1] is a positive integer, then IdsOfSmallSemigroups returns -## a list of the id numbers of all the small semigroups S in the -## library with Size(S)=arg[1] and arg[2i](S)=arg[2i+1] for all i.

-## -## If arg[1] is a list of positive integers, then IdsOfSmallSemigroups returns -## a list of the id numbers of all the small semigroups S in the -## library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] for all i.

-## -## If arg[1] is an enumerator or iterator of small semigroups, then -## IdsOfSmallSemigroups returns -## a list of the id numbers of all the small semigroups S in the -## library with S in arg[1] and arg[2i](S)=arg[2i+1] for all i.

-## enum:=EnumeratorOfSmallSemigroups(5, x-> Length(GreensRClasses(x)), 1);; -## gap> IdsOfSmallSemigroups(enum, IsCommutativeSemigroup, true, -## > IsSimpleSemigroup, false); -## [ ] -## gap> IdsOfSmallSemigroups([2,3], IsRegularSemigroup, true); -## [ [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], -## [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 3, 17 ], [ 3, 18 ] ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="IdsOfSmallSemigroups"> +# +# +# +# the number of argument of this function should be odd. The first argument +# arg[1] should be a positive integer, an enumerator of small semigroups +# with , or an iterator of small +# semigroup with . +#

+# +# The even arguments arg[2i], if present, should be functions, and the +# odd arguments arg[2i+1] should be a value that the preceeding function +# can have. For example, a typical input might be 3, IsRegularSemigroup, +# true. The functions arg[2i] can be user defined or existing &GAP; +# functions. +#

+# +# Please see Section or Chapter for +# more details. +#

+# +# If arg[1] is a positive integer, then IdsOfSmallSemigroups +# returns a list of the id numbers of all the small semigroups S in the +# library with Size(S)=arg[1] and arg[2i](S)=arg[2i+1] for all +# i. +#

+# +# If arg[1] is a list of positive integers, then +# IdsOfSmallSemigroups returns a list of the id numbers of all the small +# semigroups S in the library with Size(S) in arg[1] and +# arg[2i](S)=arg[2i+1] for all i. +#

+# +# If arg[1] is an enumerator or iterator of small semigroups, then +# IdsOfSmallSemigroups returns a list of the id numbers of all the small +# semigroups S in the library with S in arg[1] and +# arg[2i](S)=arg[2i+1] for all i. +# +# enum:=EnumeratorOfSmallSemigroups(5, x-> Length(GreensRClasses(x)), 1);; +# gap> IdsOfSmallSemigroups(enum, IsCommutativeSemigroup, true, +# > IsSimpleSemigroup, false); +# [ ] +# gap> IdsOfSmallSemigroups([2,3], IsRegularSemigroup, true); +# [ [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], +# [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 3, 17 ], [ 3, 18 ] ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("IdsOfSmallSemigroups"); -########################################################################### -## -## <#GAPDoc Label="IsEnumeratorOfSmallSemigroups"> -## -## -## -## returns true if enum is an enumerator of small semigroups -## created using , -## . -## enum:=EnumeratorOfSmallSemigroupsByIds([[2,1], [3,1], [4,1]]);; -## gap> IsEnumeratorOfSmallSemigroups(enum); -## true -## ]]> -## -## -## <#/GAPDoc> - -DeclareProperty("IsEnumeratorOfSmallSemigroups", IsEnumeratorByFunctions); - -########################################################################### -## -## <#GAPDoc Label="FuncsOfSmallSemisInEnum"> -## -## -## -## returns a list of the functions and their values that were used to create -## the enumerator of small semigroups enum. If you only want the -## names of these functions use . -## enum:=EnumeratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, -## > IsRegularSemigroup, true);; -## gap> FuncsOfSmallSemisInEnum(enum); -## [ , true, , -## false ] -## ]]> -## -## -## <#/GAPDoc> - -## JDM this is out of sequence it requires IsEnumeratorOfSmallSemigroups +# <#GAPDoc Label="IsEnumeratorOfSmallSemigroups"> +# +# +# +# returns true if enum is an enumerator of small semigroups +# created using , . +# enum:=EnumeratorOfSmallSemigroupsByIds([[2,1], [3,1], [4,1]]);; +# gap> IsEnumeratorOfSmallSemigroups(enum); +# true +# ]]> +# +# +# <#/GAPDoc> +DeclareProperty("IsEnumeratorOfSmallSemigroups", IsObject); + +# <#GAPDoc Label="FuncsOfSmallSemisInEnum"> +# +# +# +# returns a list of the functions and their values that were used to create the +# enumerator of small semigroups enum. If you only want the names of +# these functions use . +# enum:=EnumeratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, +# > IsRegularSemigroup, true);; +# gap> FuncsOfSmallSemisInEnum(enum); +# [ , true, , +# false ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("FuncsOfSmallSemisInEnum"); -########################################################################### -## -## <#GAPDoc Label="IsIdSmallSemigroup"> -## -## -## -## return true if the arg is the id of a small semigroup or -## [arg[1], arg[2]] is the id of a small semigroup. -## IsIdSmallSemigroup(8,1); -## true -## gap> IsIdSmallSemigroup([1,2]); -## false -## gap> IsIdSmallSemigroup([3,18]); -## true -## ]]> -## -## -## <#/GAPDoc> +# <#GAPDoc Label="IsIdSmallSemigroup"> +# +# +# +# return true if the arg is the id of a small semigroup or +# [arg[1], arg[2]] is the id of a small semigroup. +# IsIdSmallSemigroup(8,1); +# true +# gap> IsIdSmallSemigroup([1,2]); +# false +# gap> IsIdSmallSemigroup([3,18]); +# true +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("IsIdSmallSemigroup"); -########################################################################### -## -## <#GAPDoc Label="IsIteratorOfSmallSemigroups"> -## -## -## -## returns true if iter is an iterator of small semigroups -## created using . -## iter:=IteratorOfSmallSemigroups(8);; -## gap> IsIteratorOfSmallSemigroups(iter); -## true -## ]]> -## -## -## <#/GAPDoc> +# <#GAPDoc Label="IsIteratorOfSmallSemigroups"> +# +# +# +# returns true if iter is an iterator of small semigroups created +# using . +# iter:=IteratorOfSmallSemigroups(8);; +# gap> IsIteratorOfSmallSemigroups(iter); +# true +# ]]> +# +# +# <#/GAPDoc> DeclareProperty("IsIteratorOfSmallSemigroups", IsIteratorByFunctions); -########################################################################### -## -## <#GAPDoc Label="FuncsOfSmallSemisInIter"> -## -## -## -## returns a list of the functions and their values that were used to create -## the iterator of small semigroups iter. If you only want the names -## of these functions use . -## enum:=IteratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, -## > IsRegularSemigroup, true);; -## gap> FuncsOfSmallSemisInIter(enum); -## [ , true, , -## false ] -## ]]> -## -## -## <#/GAPDoc> - -## JDM this is out of sequence it requires IsIteratorOfSmallSemigroups +# <#GAPDoc Label="FuncsOfSmallSemisInIter"> +# +# +# +# returns a list of the functions and their values that were used to create the +# iterator of small semigroups iter. If you only want the names of these +# functions use . +# enum:=IteratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, +# > IsRegularSemigroup, true);; +# gap> FuncsOfSmallSemisInIter(enum); +# [ , true, , +# false ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("FuncsOfSmallSemisInIter"); -########################################################################### -## -## <#GAPDoc Label="IteratorOfSmallSemigroups"> -## -## -## -## the number of argument of this function should be odd. The first argument -## arg[1] should be a positive integer, an -## enumerator of small semigroups with , -## or an iterator of small semigroup with . -##

-## -## The even -## arguments arg[2i], if present, should be functions, and the odd -## arguments arg[2i+1] should be a value that the preceeding function -## can have. For example, a typical input might be -## 3, IsRegularSemigroup, true. The functions arg[2i] can be user -## defined or existing &GAP; functions.

-## -## Please see Section or Chapter -## for more details.

-## -## If arg[1] is a positive integer, then IteratorOfSmallSemigroups -## returns an iterator of all the small semigroups S in the -## library with Size(S)=arg[1] and arg[2i](S)=arg[2i+1] -## for all i.

-## -## If arg[1] is a list of positive integers, then -## IteratorOfSmallSemigroups returns -## an iterator of all the small semigroups S in the -## library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] -## for all i.

-## -## If arg[1] is an enumerator or iterator of small semigroups, then -## IteratorOfSmallSemigroups returns -## an iterator of all the small semigroups S in the -## library with S in arg[1] and arg[2i](S)=arg[2i+1] for all i. -##

-## iter:=IteratorOfSmallSemigroups(8); -## -## gap> NextIterator(iter); -## -## gap> IsDoneIterator(iter); -## false -## gap> iter:=IteratorOfSmallSemigroups([2,3], IsRegularSemigroup, true, -## > x-> Length(Idempotents(x))=1, true); -## -## gap> NextIterator(iter); -## -## gap> NextIterator(iter); -## -## gap> NextIterator(iter); -## fail -## gap> enum:=EnumeratorOfSmallSemigroups(5, x-> Length(Idempotents(x))=1, true); -## -## gap> iter:=IteratorOfSmallSemigroups(enum, x-> Length(GreensRClasses(x))=2, true); -## -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="IteratorOfSmallSemigroups"> +# +# +# +# the number of argument of this function should be odd. The first argument +# arg[1] should be a positive integer, an enumerator of small semigroups +# with , or an iterator of small +# semigroup with . +#

+# +# The even arguments arg[2i], if present, should be functions, and the +# odd arguments arg[2i+1] should be a value that the preceeding function +# can have. For example, a typical input might be 3, IsRegularSemigroup, +# true. The functions arg[2i] can be user defined or existing &GAP; +# functions. +#

+# +# Please see Section or Chapter for +# more details. +#

+# +# If arg[1] is a positive integer, then IteratorOfSmallSemigroups +# returns an iterator of all the small semigroups S in the library with +# Size(S)=arg[1] and arg[2i](S)=arg[2i+1] for all i. +#

+# +# If arg[1] is a list of positive integers, then +# IteratorOfSmallSemigroups returns an iterator of all the small +# semigroups S in the library with Size(S) in arg[1] and +# arg[2i](S)=arg[2i+1] for all i. +#

+# +# If arg[1] is an enumerator or iterator of small semigroups, then +# IteratorOfSmallSemigroups returns an iterator of all the small +# semigroups S in the library with S in arg[1] and +# arg[2i](S)=arg[2i+1] for all i. +# +# iter:=IteratorOfSmallSemigroups(8); +# +# gap> NextIterator(iter); +# +# gap> IsDoneIterator(iter); +# false +# gap> iter:=IteratorOfSmallSemigroups([2,3], IsRegularSemigroup, true, +# > x-> Length(Idempotents(x))=1, true); +# +# gap> NextIterator(iter); +# +# gap> NextIterator(iter); +# +# gap> NextIterator(iter); +# fail +# gap> enum:=EnumeratorOfSmallSemigroups(5, x-> Length(Idempotents(x))=1, true); +# +# gap> iter:=IteratorOfSmallSemigroups(enum, +# > x-> Length(GreensRClasses(x))=2, true); +# +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("IteratorOfSmallSemigroups"); -########################################################################### -## -## <#GAPDoc Label="NamesFuncsSmallSemisInEnum"> -## -## -## -## returns a list of the names of functions and their values that were used -## to create the enumerator of small semigroups enum. If you only want the -## actual functions themselves then use . -## enum:=EnumeratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, -## > IsRegularSemigroup, true);; -## gap> NamesFuncsSmallSemisInEnum(enum); -## [ "IsRegularSemigroup", true, "IsSimpleSemigroup", false ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="NamesFuncsSmallSemisInEnum"> +# +# +# +# returns a list of the names of functions and their values that were used to +# create the enumerator of small semigroups enum. If you only want the +# actual functions themselves then use . +# enum:=EnumeratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, +# > IsRegularSemigroup, true);; +# gap> NamesFuncsSmallSemisInEnum(enum); +# [ "IsRegularSemigroup", true, "IsSimpleSemigroup", false ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("NamesFuncsSmallSemisInEnum"); -########################################################################### -## -## <#GAPDoc Label="NamesFuncsSmallSemisInIter"> -## -## -## -## returns a list of the names of functions and their values that were used -## to create the iterator of small semigroups iter. If you only want the -## actual functions themselves then use -## . -## iter:=IteratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, -## > IsRegularSemigroup, true);; -## gap> NamesFuncsSmallSemisInIter(iter); -## [ "IsRegularSemigroup", true, "IsSimpleSemigroup", false ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="NamesFuncsSmallSemisInIter"> +# +# +# +# returns a list of the names of functions and their values that were used to +# create the iterator of small semigroups iter. If you only want the +# actual functions themselves then use . +# iter:=IteratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, +# > IsRegularSemigroup, true);; +# gap> NamesFuncsSmallSemisInIter(iter); +# [ "IsRegularSemigroup", true, "IsSimpleSemigroup", false ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("NamesFuncsSmallSemisInIter"); -########################################################################### -## -## <#GAPDoc Label="Nr3NilpotentSemigroups"> -## -## -## -## returns the number of 3-nilpotent semigroups on a set with n -## elements. If the optional argument type is given it must be one -## of "UpToEquivalence", "UpToIsomorphism", "SelfDual", "Commutative", -## "Labelled", "Labelled-Commutative". -## The number will be returned for the respective type of semigroup. -## By default type is "UpToEquivalence". -##

-## The function implements the formulae calculating the number of -## 3-nilpotent semigroups developed in -## Nr3NilpotentSemigroups( 4 ); -## 8 -## gap> Nr3NilpotentSemigroups( 9, "UpToIsomorphism" ); -## 105931872028455 -## gap> Nr3NilpotentSemigroups( 9, "Labelled" ); -## 38430603831264883632 -## gap> Nr3NilpotentSemigroups( 16, "SelfDual" ); -## 4975000837941847814744710290469890455985530 -## gap> Nr3NilpotentSemigroups( 19, "Commutative" ); -## 12094270656160403920767935604624748908993169949317454767617795 -## ]]> -## -## -## <#/GAPDoc> -## - -DeclareGlobalFunction("Nr3NilpotentSemigroups"); - -########################################################################### -## -## <#GAPDoc Label="NrSmallSemigroups"> -## -## -## -## the number of argument of this function should be odd. The first argument -## arg[1] should be a positive integer, an -## enumerator of small semigroups with , -## or an iterator of small semigroup with . -##

-## -## The even -## arguments arg[2i], if present, should be functions, and the odd -## arguments arg[2i+1] should be a value that the preceeding function -## can have. For example, a typical input might be -## 3, IsRegularSemigroup, true. The functions arg[2i] can be user -## defined or existing &GAP; functions.

-## -## Please see Section or Chapter -## for more details.

-## -## If arg[1] is a positive integer, then NrSmallSemigroups -## returns the number of small semigroups S in the -## library with Size(S)=arg[1] and arg[2i](S)=arg[2i+1] -## for all i.

-## -## If arg[1] is a list of positive integers, then -## NrSmallSemigroups returns -## the number of small semigroups S in the -## library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] -## for all i.

-## -## If arg[1] is an enumerator or iterator of small semigroups, then -## NrSmallSemigroups returns -## the number of small semigroups S in the -## library with S in arg[1] and arg[2i](S)=arg[2i+1] for all i. -##

-## List([1..8], NrSmallSemigroups); -## [ 1, 4, 18, 126, 1160, 15973, 836021, 1843120128 ] -## gap> NrSmallSemigroups(8, IsCommutative, true, IsInverseSemigroup, true); -## 4443 -## gap> NrSmallSemigroups([1..8], IsCliffordSemigroup, true); -## 5610 -## gap> NrSmallSemigroups(8, IsRegularSemigroup, true, -## > IsCompletelyRegularSemigroup, false); -## 1164 -## gap> NrSmallSemigroups(5, NilpotencyDegree, 3); -## 84 -## ]]> -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="NrSmallSemigroups"> +# +# +# +# the number of argument of this function should be odd. The first argument +# arg[1] should be a positive integer, an enumerator of small semigroups +# with , or an iterator of small +# semigroup with . +#

+# +# The even arguments arg[2i], if present, should be functions, and the +# odd arguments arg[2i+1] should be a value that the preceeding function +# can have. For example, a typical input might be 3, IsRegularSemigroup, +# true. The functions arg[2i] can be user defined or existing &GAP; +# functions. +#

+# +# Please see Section or Chapter for +# more details. +#

+# +# If arg[1] is a positive integer, then NrSmallSemigroups returns +# the number of small semigroups S in the library with +# Size(S)=arg[1] and arg[2i](S)=arg[2i+1] for all i. +#

+# +# If arg[1] is a list of positive integers, then +# NrSmallSemigroups returns the number of small semigroups S in +# the library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] for +# all i. +#

+# +# If arg[1] is an enumerator or iterator of small semigroups, then +# NrSmallSemigroups returns the number of small semigroups S in +# the library with S in arg[1] and arg[2i](S)=arg[2i+1] for all +# i. +# +# List([1..8], NrSmallSemigroups); +# [ 1, 4, 18, 126, 1160, 15973, 836021, 1843120128 ] +# gap> NrSmallSemigroups(8, IsCommutative, true, IsInverseSemigroup, true); +# 4443 +# gap> NrSmallSemigroups([1..8], IsCliffordSemigroup, true); +# 5610 +# gap> NrSmallSemigroups(8, IsRegularSemigroup, true, +# > IsCompletelyRegularSemigroup, false); +# 1164 +# gap> NrSmallSemigroups(5, NilpotencyDegree, 3); +# 84 +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("NrSmallSemigroups"); -########################################################################### -## -## <#GAPDoc Label="OneSmallSemigroup"> -## -## -## -## the number of argument of this function should be odd. The first argument -## arg[1] should be a positive integer, an -## enumerator of small semigroups with , -## or an iterator of small semigroup with . -##

-## -## The even -## arguments arg[2i], if present, should be functions, and the odd -## arguments arg[2i+1] should be a value that the preceeding function -## can have. For example, a typical input might be -## 3, IsRegularSemigroup, true. The functions arg[2i] can be user -## defined or existing &GAP; functions.

-## -## Please see Section or Chapter -## for more details.

-## -## If arg[1] is a positive integer, then OneSmallSemigroup -## returns the first small semigroup S in the -## library with Size(S)=arg[1] and arg[2i](S)=arg[2i+1] -## for all i.

-## -## If arg[1] is a list of positive integers, then -## OneSmallSemigroup returns -## the first small semigroup S in the -## library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] -## for all i.

-## -## If arg[1] is an enumerator or iterator of small semigroups, then -## OneSmallSemigroup returns -## the first small semigroup S in the -## library with S in arg[1] and arg[2i](S)=arg[2i+1] for all i. -##

-## OneSmallSemigroup(8, IsCommutative, true, IsInverseSemigroup, true); -## -## gap> OneSmallSemigroup([1..8], IsCliffordSemigroup, true); -## -## gap> iter:=IteratorOfSmallSemigroups(8, IsCommutative, false); -## -## gap> OneSmallSemigroup(iter); -## -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="OneSmallSemigroup"> +# +# +# +# the number of argument of this function should be odd. The first argument +# arg[1] should be a positive integer, an enumerator of small semigroups +# with , or an iterator of small +# semigroup with . +#

+# +# The even arguments arg[2i], if present, should be functions, and the +# odd arguments arg[2i+1] should be a value that the preceeding function +# can have. For example, a typical input might be 3, IsRegularSemigroup, +# true. The functions arg[2i] can be user defined or existing &GAP; +# functions. +#

+# +# Please see Section or Chapter for +# more details. +#

+# +# If arg[1] is a positive integer, then OneSmallSemigroup returns +# the first small semigroup S in the library with Size(S)=arg[1] +# and arg[2i](S)=arg[2i+1] for all i. +#

+# +# If arg[1] is a list of positive integers, then +# OneSmallSemigroup returns the first small semigroup S in the +# library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] for all +# i. +#

+# +# If arg[1] is an enumerator or iterator of small semigroups, then +# OneSmallSemigroup returns the first small semigroup S in the +# library with S in arg[1] and arg[2i](S)=arg[2i+1] for all +# i. +# +# OneSmallSemigroup(8, IsCommutative, true, IsInverseSemigroup, true); +# +# gap> OneSmallSemigroup([1..8], IsCliffordSemigroup, true); +# +# gap> iter:=IteratorOfSmallSemigroups(8, IsCommutative, false); +# +# gap> OneSmallSemigroup(iter); +# +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("OneSmallSemigroup"); -########################################################################### -## -## <#GAPDoc Label="PositionsOfSmallSemigroups"> -## -## -## -## the number of argument of this function should be odd. The first argument -## arg[1] should be a positive integer or an -## enumerator with , the even -## arguments arg[2i], if present, should be functions, and the odd -## arguments arg[2i+1] should be a value that the preceeding function -## can have. For example, a typical input might be -## 3, IsRegularSemigroup, true. The functions arg[2i] can be user -## defined or existing &GAP; functions. The argument can be a list arg -## with the same components as given above.

-## -## The function returns a list of the second components of the -## of all the small semigroups S in the -## library satisfying Size(S) in arg[1] or Size(S) in -## SizesOfSmallSemisInEnum(arg[1]) and arg[2i](S)=arg[2i+1] -## for all i partitioned by size of the semigroups. -## -## PositionsOfSmallSemigroups(3); -## [ [ 1 .. 18 ] ] -## gap> PositionsOfSmallSemigroups(3, IsRegularSemigroup, false); -## [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ] -## gap> enum:=EnumeratorOfSmallSemigroups(3, IsRegularSemigroup, false);; -## gap> PositionsOfSmallSemigroups(enum); -## [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ] -## gap> PositionsOfSmallSemigroups([1..4], IsBand, true); -## [ [ 1 ], [ 3, 4 ], [ 12 .. 17 ], [ 98 .. 123 ] ] -## gap> PositionsOfSmallSemigroups(enum, Is1IdempotentSemigroup, true, -## > Is2GeneratedSemigroup, true, IsCliffordSemigroup, false); -## [ [ 1, 2 ] ] -## ]]> -## -## -## <#/GAPDoc> -## - +# <#GAPDoc Label="PositionsOfSmallSemigroups"> +# +# +# +# the number of argument of this function should be odd. The first argument +# arg[1] should be a positive integer or an enumerator with , the even arguments arg[2i], if +# present, should be functions, and the odd arguments arg[2i+1] should +# be a value that the preceeding function can have. For example, a typical +# input might be 3, IsRegularSemigroup, true. The functions +# arg[2i] can be user defined or existing &GAP; functions. The argument +# can be a list arg with the same components as given above. +#

+# +# The function returns a list of the second components of the of all the small semigroups S in the +# library satisfying Size(S) in arg[1] or Size(S) in +# SizesOfSmallSemisInEnum(arg[1]) and arg[2i](S)=arg[2i+1] for +# all i partitioned by size of the semigroups. +# +# PositionsOfSmallSemigroups(3); +# [ [ 1 .. 18 ] ] +# gap> PositionsOfSmallSemigroups(3, IsRegularSemigroup, false); +# [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ] +# gap> enum:=EnumeratorOfSmallSemigroups(3, IsRegularSemigroup, false);; +# gap> PositionsOfSmallSemigroups(enum); +# [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ] +# gap> PositionsOfSmallSemigroups([1..4], IsBand, true); +# [ [ 1 ], [ 3, 4 ], [ 12 .. 17 ], [ 98 .. 123 ] ] +# gap> PositionsOfSmallSemigroups(enum, Is1IdempotentSemigroup, true, +# > Is2GeneratedSemigroup, true, IsCliffordSemigroup, false); +# [ [ 1, 2 ] ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("PositionsOfSmallSemigroups"); -########################################################################### -## -## <#GAPDoc Label="PositionsOfSmallSemisInEnum"> -## -## -## -## returns the second components of the id numbers of the small semigroups -## in the enumerator of small semigroups enum in a list partitioned -## according the size of the semigroup. The same value is returned by -## using . -## enum := EnumeratorOfSmallSemigroups([2..4],IsSimpleSemigroup,true);; -## gap> PositionsOfSmallSemisInEnum -## > (enum); -## [ [ 2, 4 ], [ 17, 18 ], [ 7, 37, 52, 122, 123 ] ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="PositionsOfSmallSemisInEnum"> +# +# +# +# returns the second components of the id numbers of the small semigroups in +# the enumerator of small semigroups enum in a list partitioned +# according the size of the semigroup. The same value is returned by using +# . +# enum := EnumeratorOfSmallSemigroups([2..4],IsSimpleSemigroup,true);; +# gap> PositionsOfSmallSemisInEnum +# > (enum); +# [ [ 2, 4 ], [ 17, 18 ], [ 7, 37, 52, 122, 123 ] ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("PositionsOfSmallSemisInEnum"); -########################################################################### -## -## <#GAPDoc Label="RandomSmallSemigroup"> -## -## -## -## the number of argument of this function should be odd. The first -## argument arg[1] should be a positive integer, an enumerator -## of small semigroups with , -## or an iterator of small semigroup with -## . -##

-## The even arguments arg[2i], if present, should be functions, -## and the odd arguments arg[2i+1] should be a value that the -## preceeding function can have. For example, a typical input might be -## 3, IsRegularSemigroup, true. The functions arg[2i] can -## be user defined or existing &GAP; functions. -##

-## Please see Section or Chapter -## for more details. -##

-## If arg[1] is a positive integer, then RandomSmallSemigroup -## returns a random small semigroup S in the library with -## Size(S)=arg[1] and arg[2i](S)=arg[2i+1] for all i. -##

-## If arg[1] is a list of positive integers, then -## RandomSmallSemigroup returns the a random small semigroup -## S in the library with Size(S) in arg[1] and -## arg[2i](S)=arg[2i+1] for all i. -##

-## If arg[1] is an enumerator or iterator of small semigroups, then -## RandomSmallSemigroup returns the a random small semigroup -## S in the library with S in arg[1] and -## arg[2i](S)=arg[2i+1] for all i. -## RandomSmallSemigroup(8, IsCommutative, true, -## > IsInverseSemigroup, true); -## -## gap> RandomSmallSemigroup([1..8], IsCliffordSemigroup, true); -## -## gap> iter:=IteratorOfSmallSemigroups([1..7]); -## -## gap> RandomSmallSemigroup(iter); -## -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="RandomSmallSemigroup"> +# +# +# +# the number of argument of this function should be odd. The first argument +# arg[1] should be a positive integer, an enumerator of small semigroups +# with , or an iterator of small +# semigroup with . +#

+# +# The even arguments arg[2i], if present, should be functions, and the +# odd arguments arg[2i+1] should be a value that the preceeding function +# can have. For example, a typical input might be 3, IsRegularSemigroup, +# true. The functions arg[2i] can be user defined or existing &GAP; +# functions. +#

+# +# Please see Section or Chapter for +# more details. +#

+# +# If arg[1] is a positive integer, then RandomSmallSemigroup +# returns a random small semigroup S in the library with +# Size(S)=arg[1] and arg[2i](S)=arg[2i+1] for all i. +#

+# +# If arg[1] is a list of positive integers, then +# RandomSmallSemigroup returns the a random small semigroup S in +# the library with Size(S) in arg[1] and arg[2i](S)=arg[2i+1] for +# all i. +#

+# +# If arg[1] is an enumerator or iterator of small semigroups, then +# RandomSmallSemigroup returns the a random small semigroup S in +# the library with S in arg[1] and arg[2i](S)=arg[2i+1] for all +# i. +# +# RandomSmallSemigroup(8, IsCommutative, true, +# > IsInverseSemigroup, true); +# +# gap> RandomSmallSemigroup([1..8], IsCliffordSemigroup, true); +# +# gap> iter:=IteratorOfSmallSemigroups([1..7]); +# +# gap> RandomSmallSemigroup(iter); +# +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("RandomSmallSemigroup"); -########################################################################### -## -## <#GAPDoc Label="SizesOfSmallSemisInEnum"> -## -## -## -## returns the sizes of the semigroups in the enumerator of small semigroups -## enum. -## enum:=EnumeratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false); -## -## gap> SizesOfSmallSemisInEnum(enum); -## [ 2, 3, 4 ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="SizesOfSmallSemisInEnum"> +# +# +# +# returns the sizes of the semigroups in the enumerator of small semigroups +# enum. +# +# enum:=EnumeratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false); +# +# gap> SizesOfSmallSemisInEnum(enum); +# [ 2, 3, 4 ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("SizesOfSmallSemisInEnum"); -########################################################################### -## -## <#GAPDoc Label="SizesOfSmallSemisInIter"> -## -## -## -## returns the sizes of the semigroups in the iterator iter -## of small semigroups. -## iter:=IteratorOfSmallSemigroups(7, IsCommutative, false); -## -## gap> SizesOfSmallSemisInIter(iter); -## [ 7 ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="SizesOfSmallSemisInIter"> +# +# +# +# returns the sizes of the semigroups in the iterator iter of small +# semigroups. +# +# iter:=IteratorOfSmallSemigroups(7, IsCommutative, false); +# +# gap> SizesOfSmallSemisInIter(iter); +# [ 7 ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("SizesOfSmallSemisInIter"); -########################################################################### -## -## <#GAPDoc Label="UpToIsomorphism"> -## -## -## -## takes a list sgrps of non-equivalent semigroups from the -## library as input and returns a list of non-isomorphic semigroups -## containing an isomorphic -## semigroup and an anti-isomorphic semigroup for every semigroup -## in sgrps. -## UpToIsomorphism([SmallSemigroup(5,126),SmallSemigroup(6,2)]); -## [ , ] -## gap> UpToIsomorphism([SmallSemigroup(5,126),SmallSemigroup(5,3)]); -## [ , , -## ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation("UpToIsomorphism", [ IsList ]); -DeclareOperation("UpToIsomorphism", [ IsSmallSemigroup ]); - -#Internal Functions -################### - +# <#GAPDoc Label="UpToIsomorphism"> +# +# +# +# takes a list sgrps of non-equivalent semigroups from the library as +# input and returns a list of non-isomorphic semigroups containing an +# isomorphic semigroup and an anti-isomorphic semigroup for every semigroup in +# sgrps. +# +# UpToIsomorphism([SmallSemigroup(5,126),SmallSemigroup(6,2)]); +# [ , ] +# gap> UpToIsomorphism([SmallSemigroup(5,126),SmallSemigroup(5,3)]); +# [ , , +# ] +# ]]> +# +# +# <#/GAPDoc> +DeclareOperation("UpToIsomorphism", [IsList]); +DeclareOperation("UpToIsomorphism", [IsSmallSemigroup]); + +########################################################################### +# Internal Functions ########################################################################### # undocumented: required by iterators. DeclareGlobalFunction("SHALLOWCOPYITERATORSMALLSEMI"); -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_ARG_OK"> -## -## -## -## checks that the argument arg is valid for any of the functions -## , -## , -## , -## , -## , -## , -## , -## , -## .

-## -## Currently a valid argument is one with: -## -## odd length -## arg[1] is a positive integer between 1 and 8, a list of positive integers -## between 1 and 8, an enumerator of small semigroups or an iterator of small semigroups -## arg[2i] (the even indexed arguments) should be functions. -## -## -## -## -## <#/GAPDoc> - -DeclareGlobalFunction("SMALLSEMI_ARG_OK"); - -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_CAN_CREATE_ENUM_NC"> -## -## -## -## checks that the argument arg can be used to produce an enumerator. -## This function does not check is true with -## argument arg and it is assumed that arg is of this form.

-## -## Currently a valid argument is one with: -## -## the maximum size of semigroup satisfying arg at most 7; OR -## the maximum size of semigroup satisfying arg equal 8 and there exists -## i such that arg[2i] in -## [8] -## and arg[2i+1] is true. -## -## The reason for this is that on a 32-bit computer the maximum length of a list is -## smaller than the number of semigroups with 8 elements. Enumerators use lists of id numbers -## to specify their elements and so it is not currently possible to create arbitrary -## enumerators of small semigroups containing semigroups with 8 elements. -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="SMALLSEMI_ValidateArgs"> +# +# +# +# checks that the argument arg is valid for any of the functions +# , +# , +# , +# , +# , +# , +# , +# , +# .

+# +# Currently a valid argument is one with: +# +# +# odd length; +# +# +# arg[1] is a positive integer between 1 and 8; a list of positive +# integers between 1 and 8; an enumerator of small semigroups; or an iterator +# of small semigroups; +# +# +# arg[2i] (the even indexed arguments) should be functions. +# +# +# +# +# <#/GAPDoc> +DeclareGlobalFunction("SMALLSEMI_ValidateArgs"); + +# <#GAPDoc Label="SMALLSEMI_CAN_CREATE_ENUM_NC"> +# +# +# +# checks that the argument arg can be used to produce an enumerator. +# This function does not check is +# true with argument arg and it is assumed that arg is of +# this form. +#

+# +# Currently a valid argument is one with: +# +# +# the maximum size of semigroup satisfying arg at most 7; OR +# +# +# the maximum size of semigroup satisfying arg equal 8 and there +# exists i such that arg[2i] in [8] and +# arg[2i+1] is true. +# +# +# The reason for this is that on a 32-bit computer the maximum length of a list +# is smaller than the number of semigroups with 8 elements. Enumerators use +# lists of id numbers to specify their elements and so it is not currently +# possible to create arbitrary enumerators of small semigroups containing +# semigroups with 8 elements. +# +# +# <#/GAPDoc> DeclareGlobalFunction("SMALLSEMI_CAN_CREATE_ENUM_NC"); -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_CONVERT_ARG_NC"> -## -## -## -## arg is assumed to satisfy -## (arg)=true but this is not checked. -## -## SMALLSEMI_CONVERT_ARG_NC replaces every function arg[2i] -## by an equivalent function in -## if it exists.

-## -## See for -## more details. -## SMALLSEMI_CONVERT_ARG_NC(5, IsCommutativeSemigroup, true); -## [ 5, , true ] -## gap> SMALLSEMI_CONVERT_ARG_NC(7, Is4GeneratedSemigroup, true); -## [ 7, , false, -## , false, -## , false, -## , false, -## , false, -## , false ] -## gap> SMALLSEMI_CONVERT_ARG_NC(5, IsCommutative, true); -## [ 5, , true ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="SMALLSEMI_CONVERT_ARG_NC"> +# +# +# +# arg is assumed to satisfy +# (arg)=true but this is not checked. +# +# SMALLSEMI_CONVERT_ARG_NC replaces every function arg[2i] by an +# equivalent function in if it exists. +#

+# +# See for more details. +# SMALLSEMI_CONVERT_ARG_NC(5, IsCommutativeSemigroup, true); +# [ 5, , true ] +# gap> SMALLSEMI_CONVERT_ARG_NC(7, Is4GeneratedSemigroup, true); +# [ 7, , false, +# , false, +# , false, +# , false, +# , false, +# , false ] +# gap> SMALLSEMI_CONVERT_ARG_NC(5, IsCommutative, true); +# [ 5, , true ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("SMALLSEMI_CONVERT_ARG_NC"); -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_CREATE_ENUM"> -## -## -## -## -## source should be a positive integer between 1 and 8, a list of -## positive integers between 1 and 8, an enumerator of small semigroups, or -## an iterator of small semigroups; -## positions should be the list -## such that positions[i] is the list of second components of id numbers ## of small semigroups in the enumerator we are creating -## names is the list of functions and values being used to create -## the enumerator. It is not checked if it is possible to create an enumerator ## using Concatenation([source],names) as an argument. See -## for more details. -## -## SMALLSEMI_CREATE_ENUM returns the same value as -## -## but here the attributes and -## are set according to -## the argument names.

-## -## Elements of enumerators creating using SMALLSEMI_CREATE_ENUM should have any -## operation in names set to the value specified when the enumerator was created. -## That is, it should not be necessary to recompute this information. -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="SMALLSEMI_CREATE_ENUM"> +# +# +# +# +# +# source should be a positive integer between 1 and 8, a list of +# positive integers between 1 and 8, an enumerator of small semigroups, or an +# iterator of small semigroups; +# +# +# positions should be the list such that positions[i] is the +# list of second components of id numbers of small semigroups in the +# enumerator being created; +# +# +# names is the list of functions and values being used to create the +# enumerator. It is not checked if it is possible to create an enumerator +# using Concatenation([source],names) as an argument. See for more details. +# +# +# SMALLSEMI_CREATE_ENUM returns the same value as but here the +# attributes and +# are set +# according to the argument names. +#

+# +# Elements of enumerators creating using SMALLSEMI_CREATE_ENUM should +# have any operation in names set to the value specified when the +# enumerator was created. That is, it should not be necessary to recompute this +# information. +# +# +# <#/GAPDoc> DeclareGlobalFunction("SMALLSEMI_CREATE_ENUM"); -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_ENTAB"> -## -## -## -## returns the string str with -## characters '>' and a space juxtaposed at the beginning. -## -## -## <#/GAPDoc> - -DeclareGlobalFunction("SMALLSEMI_ENTAB"); - -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_SORT_ARG_NC"> -## -## -## -## arg is assumed to satisfy -## (arg)=true but this is not checked. -## -## SMALLSEMI_SORT_ARG_NC sorts arg so that the functions -## arg[2i] where arg[2i+1] is true come at the start, and -## then the arguments arg[2i] are ordered alphabetically. -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="SMALLSEMI_SORT_ARG_NC"> +# +# +# +# arg is assumed to satisfy +# (arg)=true but this is not checked. +# +# SMALLSEMI_SORT_ARG_NC sorts arg so that the functions +# arg[2i] where arg[2i+1] is true come at the start, and +# then the arguments arg[2i] are ordered alphabetically. +# +# +# <#/GAPDoc> DeclareGlobalFunction("SMALLSEMI_SORT_ARG_NC"); -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_STRIP_ARG"> -## -## -## -## returns arg or arg[1] if arg is a list containing an -## argument in its first position. This is required as an arg is not -## input as a list but occurs as a list in the function where it is used. Hence -## passing the arg to another function passes a list rather than the -## correct argument. -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="SMALLSEMI_STRIP_ARG"> +# +# +# +# returns arg or arg[1] if arg is a list containing an +# argument in its first position. This is required as an arg is not +# input as a list but occurs as a list in the function where it is used. Hence +# passing the arg to another function passes a list rather than the +# correct argument. +# +# +# <#/GAPDoc> DeclareGlobalFunction("SMALLSEMI_STRIP_ARG"); - -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_RETURN"> -## -## -## -## -## -## -## -## <#/GAPDoc> -DeclareGlobalFunction("SMALLSEMI_RETURN"); - -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_TAB_LEVEL"> -## -## -## -## -## -## -## -## <#/GAPDoc> - -SMALLSEMI_TAB_LEVEL:=-1; - -#OLD? -################### - -#DeclareAttribute("ParentEnumOfSmallSemi", IsSmallSemigroup); diff --git a/gap/enums.gi b/gap/enums.gi index fc052b9..f67c3ee 100644 --- a/gap/enums.gi +++ b/gap/enums.gi @@ -1,1870 +1,1067 @@ ############################################################################# ## -#W enums.gi Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2012 Andreas Distler & James D. Mitchell +## enums.gi Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# ## +BindGlobal("SMALLSEMI_RS", RandomSource(IsMersenneTwister)); +BindGlobal("SMALLSEMI_FuncNameOrString", +function(x) + if IsFunction(x) then + return NAME_FUNC(x); + else + return x; + fi; +end); -################## - -InstallGlobalFunction(AllSmallSemigroups, -function(arg) -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("AllSmallSemigroups")); +InstallGlobalFunction(NamesFuncsSmallSemisInEnum, enum -> enum!.names); +InstallGlobalFunction(PositionsOfSmallSemisInEnum, enum -> enum!.pos); +InstallGlobalFunction(FuncsOfSmallSemisInEnum, enum -> enum!.funcs); +InstallGlobalFunction(SizesOfSmallSemisInEnum, enum -> enum!.sizes); -arg:=SMALLSEMI_STRIP_ARG(arg); +InstallGlobalFunction(NamesFuncsSmallSemisInIter, iter -> iter!.names); +InstallGlobalFunction(FuncsOfSmallSemisInIter, iter -> iter!.funcs); +InstallGlobalFunction(SizesOfSmallSemisInIter, iter -> iter!.sizes); -return SMALLSEMI_RETURN(ConstantTimeAccessList(EnumeratorSortedOfSmallSemigroups(arg))); +InstallGlobalFunction(AllSmallSemigroups, +function(arg...) + return ConstantTimeAccessList( + CallFuncList(EnumeratorSortedOfSmallSemigroups, arg)); end); -################## -# empty enum. over a pos. int. or list of pos. ints. - -InstallGlobalFunction(EmptyEnumeratorOfSmallSemigroups, -function(arg) -local enum, fam; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("EmptyEnumeratorOfSmallSemigroups")); - -if not arg=[] then - Error("argument should be empty"); -fi; - -fam:=CollectionsFamily(SmallSemigroupEltFamily); - -enum:=EnumeratorByFunctions(Domain(fam, []), rec( - ElementNumber:= ReturnFail, - - NumberElement:= ReturnFail, - - Length:=enum -> 0, - - PrintObj:=function(enum) - Print( ""); - return; - end, - - pos:=[[]], sizes:=[])); - - SetIsEnumeratorOfSmallSemigroups(enum, true); - #SetPositionsOfSmallSemisInEnum(enum, [[]]); - #SetSizesOfSmallSemisInEnum(enum, []); - SetIsFinite(enum, true); - - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - - return enum; -end); +InstallGlobalFunction(EmptyEnumeratorOfSmallSemigroups, +function(arg...) + local record, fam, enum; -################## - -InstallGlobalFunction(EmptyIteratorOfSmallSemigroups, -function(arg) -local iter; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("EmptyIteratorOfSmallSemigroups")); - -if not arg=[] then - Error("argument should be empty"); -fi; - -iter:=IteratorByFunctions( rec( - - IsDoneIterator := ReturnTrue, - - NextIterator := ReturnFail, - - PrintObj := function( iter ) Print( ""); end, - - ShallowCopy := SHALLOWCOPYITERATORSMALLSEMI, - - at := 0, - - max:= 0, - - enum:=[], - - user:=[], - - sizes:=[0])); - -SetIsIteratorOfSmallSemigroups(iter, true); - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; -return iter; -end); + if not IsEmpty(arg) then + Error("argument should be empty"); + fi; -################## - -InstallGlobalFunction(EnumeratorOfSmallSemigroups, -function(arg) -local fam, enum, pos, index, tot, lens, enums, i; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("EnumeratorOfSmallSemigroups")); - -arg:=SMALLSEMI_STRIP_ARG(arg); - -if not SMALLSEMI_ARG_OK(arg) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - Error("input is incorrect"); #JDM could just call SMALLSEMI_ARG_OK and have errors from there -fi; - -arg:=SMALLSEMI_SORT_ARG_NC(SMALLSEMI_CONVERT_ARG_NC(arg)); - -#comment out the following if statement to allow the creation of all -#enumerators of semigroups of size 8. BEWARE this might have unpredictable -#consequences. JDM - -if not SMALLSEMI_CAN_CREATE_ENUM_NC(arg) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - Error("it is not currently possible to find all enumerators containing \n semigroups of order 8"); -fi; - -if Length(arg)=1 and IsEnumeratorOfSmallSemigroups(arg[1]) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return arg[1]; #do nothing -elif Length(arg)=1 and IsIteratorOfSmallSemigroups(arg[1]) then - return SMALLSEMI_RETURN(SMALLSEMI_CREATE_ENUM(SizesOfSmallSemisInIter(arg[1]), - PositionsOfSmallSemigroups(arg[1]), FuncsOfSmallSemisInIter(arg[1]))); - #convert iterator to enumerator -elif Length(arg)=1 and IsPosInt(arg[1]) then #all semigroups - - fam:=CollectionsFamily(SmallSemigroupEltFamily); - - enum:=EnumeratorByFunctions(Domain(fam, []), rec( - ElementNumber:=function(enum, pos) - return SmallSemigroupNC(arg[1], pos); - end, - - NumberElement:=function(enum, elm) - return IdSmallSemigroup(elm)[2]; - end, - - Length:=enum -> NrSmallSemigroups(arg[1]), - - PrintObj:=function(enum) - Print( ""); - return; - end, - pos:= [[1..NrSmallSemigroups(arg[1])]], - funcs:=[], names:=["AllSmallSemigroups", arg[1]], - sizes:=[arg[1]])); - - SetIsEnumeratorOfSmallSemigroups(enum, true); - #SetPositionsOfSmallSemisInEnum(enum, [[1..NrSmallSemigroups(arg[1])]]); - #SetFuncsOfSmallSemisInEnum(enum, []); - #SetNamesFuncsSmallSemisInEnum(enum, ["AllSmallSemigroups", arg[1]]); - #SetSizesOfSmallSemisInEnum(enum, [arg[1]]); - SetIsFinite(enum, true); -elif Length(arg)=1 and ForAll(arg[1], IsPosInt) then - enum:=SMALLSEMI_CREATE_ENUM(arg[1], List(arg[1], x-> - [1..NrSmallSemigroups(x)]), arg{[2..Length(arg)]}); -elif IsPosInt(arg[1]) then - #enumerator by list of properties and their values - enum:=SMALLSEMI_CREATE_ENUM(arg[1], PositionsOfSmallSemigroups(arg), - arg{[2..Length(arg)]}); -elif IsEnumeratorOfSmallSemigroups(arg[1]) then - enum:=SMALLSEMI_CREATE_ENUM(SizesOfSmallSemisInEnum(arg[1]), - PositionsOfSmallSemigroups(arg), arg{[2..Length(arg)]}); -elif IsIteratorOfSmallSemigroups(arg[1]) then - enum:=SMALLSEMI_CREATE_ENUM(SizesOfSmallSemisInIter(arg[1]), - PositionsOfSmallSemigroups(arg), arg{[2..Length(arg)]}); -elif Length(arg)>1 and ForAll(arg[1], IsPosInt) then #enumerator over range - enum:=SMALLSEMI_CREATE_ENUM(arg[1], PositionsOfSmallSemigroups(arg), - arg{[2..Length(arg)]}); -fi; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; -return enum; + record := rec(); + record.ElementNumber := ReturnFail; + record.NumberElement := ReturnFail; + record.Length := enum -> 0; + record.PrintObj := function(_) + Print(""); + end; + record.pos := [[]]; + record.sizes := []; -end); + fam := CollectionsFamily(SmallSemigroupEltFamily); + enum := EnumeratorByFunctions(Domain(fam, []), record); -################## -# input ids, a list of ids, a pos. int. & list of positions, a list of pos. -# ints. and a list of positions of equal length + SetIsEnumeratorOfSmallSemigroups(enum, true); + SetIsFinite(enum, true); -InstallMethod(EnumeratorOfSmallSemigroupsByIds, -"for a set of pos. ints. and list of sets of positions", - [IsCyclotomicCollection, IsCyclotomicCollColl], 0, -function(sizes, positions) + return enum; +end); -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; +InstallGlobalFunction(EmptyIteratorOfSmallSemigroups, +function(arg...) + local record, iter; -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("EnumeratorOfSmallSemigroupsByIds 1")); + if not IsEmpty(arg) then + Error("argument should be empty"); + fi; -if not ForAll(sizes, x-> x>0 and x<9) then - Info(InfoWarning, 1, "can only create enums of semigroups of sizes 1 to 8"); - return fail; -fi; + record := rec(); + record.IsDoneIterator := ReturnTrue; + record.NextIterator := ReturnFail; + record.PrintObj := function(_) + Print(""); + end; + record.ShallowCopy := SHALLOWCOPYITERATORSMALLSEMI; + record.at := 0; + record.max := 0; + record.enum := []; + record.user := []; + record.sizes := [0]; + + iter := IteratorByFunctions(record); + + SetIsIteratorOfSmallSemigroups(iter, true); + return iter; +end); -if not IsSet(sizes) then - Info(InfoWarning, 1, - "1st argument must be a set of pos. int. in the range 1 .. 8"); - return fail; -fi; +InstallGlobalFunction(EnumeratorOfSmallSemigroups, +function(arg...) + local fam, record, enum, sizes; -if not Length(sizes)=Length(positions) then - Info(InfoWarning, 1, "1st and 2nd arg. must have equal length"); - return fail; -fi; + arg := SMALLSEMI_STRIP_ARG(arg); + SMALLSEMI_ValidateArgs(arg); -if not ForAll(positions, x-> ForAll(x, IsPosInt)) - or not ForAll(positions, IsSet) then - Info(InfoWarning, 1, "2nd arg. must be a list of sets of pos. ints."); - return fail; -fi; + arg := SMALLSEMI_SORT_ARG_NC(SMALLSEMI_CONVERT_ARG_NC(arg)); -if ForAny([1..Length(positions)], i-> Maximum(positions[i]) - > NrSmallSemigroups(sizes[i])) then - Info(InfoWarning, 1, "all sets in 2nd arg. should be in the range 1 to ", - "the number of semigroups of the appropriate size "); - return fail; -fi; + if not SMALLSEMI_CAN_CREATE_ENUM_NC(arg) then + Error("it is not currently possible to construct every enumerator", + "containing semigroups of order 8"); + fi; -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; + if Length(arg) = 1 then + if IsEnumeratorOfSmallSemigroups(arg[1]) then + # do nothing + return arg[1]; + elif IsIteratorOfSmallSemigroups(arg[1]) then + # convert iterator to enumerator + return SMALLSEMI_CREATE_ENUM(SizesOfSmallSemisInIter(arg[1]), + PositionsOfSmallSemigroups(arg[1]), + FuncsOfSmallSemisInIter(arg[1])); + elif IsPosInt(arg[1]) then + # all semigroups + fam := CollectionsFamily(SmallSemigroupEltFamily); + record := rec(); + + record.ElementNumber := {enum, pos} -> SmallSemigroupNC(arg[1], pos); + record.NumberElement := {enum, elm} -> IdSmallSemigroup(elm)[2]; + record.Length := enum -> NrSmallSemigroups(arg[1]); + + record.PrintObj := function(_) + Print(""); + end; + + record.pos := [[1 .. NrSmallSemigroups(arg[1])]]; + record.funcs := []; + record.names := ["AllSmallSemigroups", arg[1]]; + record.sizes := [arg[1]]; + + enum := EnumeratorByFunctions(Domain(fam, []), record); + SetIsEnumeratorOfSmallSemigroups(enum, true); + SetIsFinite(enum, true); + else + # arg is list of positive integers + enum := SMALLSEMI_CREATE_ENUM(arg[1], + List(arg[1], + x -> [1 .. NrSmallSemigroups(x)]), + arg{[2 .. Length(arg)]}); + fi; + return enum; + fi; -return EnumeratorOfSmallSemigroupsByIdsNC(sizes, positions); + if IsPosInt(arg[1]) or IsCyclotomicCollection(arg[1]) then + sizes := arg[1]; + elif IsEnumeratorOfSmallSemigroups(arg[1]) then + sizes := SizesOfSmallSemisInEnum(arg[1]); + elif IsIteratorOfSmallSemigroups(arg[1]) then + sizes := SizesOfSmallSemisInIter(arg[1]); + fi; + return SMALLSEMI_CREATE_ENUM(sizes, + PositionsOfSmallSemigroups(arg), + arg{[2 .. Length(arg)]}); end); -################## +# input ids, a list of ids, a pos. int. & list of positions, a list of pos. +# ints. and a list of positions of equal length -InstallMethod(EnumeratorOfSmallSemigroupsByIdsNC, +InstallMethod(EnumeratorOfSmallSemigroupsByIds, "for a set of pos. ints. and list of sets of positions", -[IsCyclotomicCollection, IsCyclotomicCollColl], 0, -function(sizes, positions) -local fam, enum, id1, id2, tot, lens, i; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("EnumeratorOfSmallSemigroupsByIdsNC 1")); - -if ForAll(positions, x-> x=[]) then - return SMALLSEMI_RETURN(EmptyEnumeratorOfSmallSemigroups()); -fi; - -fam:=CollectionsFamily(SmallSemigroupEltFamily); - -tot:=0; -lens:=[0]; -for i in positions do - tot:=tot+Length(i); - Add(lens, tot); -od; - -enum:=EnumeratorByFunctions(Domain(fam, []), rec( -ElementNumber:=function(enum, pos) -local i; -if pos>Length(enum) then - return fail; -fi; -i:=PositionProperty(lens, x-> pos<=x)-1; -return SmallSemigroupNC(sizes[i], positions[i][pos-lens[i]]); -end, - -NumberElement:=function(enum, elm) -local id; -id:=IdSmallSemigroup(elm); -return PositionSorted(positions[id[1]], id[2]); -end, - -Length:=enum -> tot, - -PrintObj:=function(enum) -if Length(sizes)>1 then - Print( ""); -else - Print( ""); -fi; -return; -end, pos:=positions, sizes:=sizes, names:=["enumerator by ids", sizes], -funcs:=[])); - -SetIsEnumeratorOfSmallSemigroups(enum, true); -#SetPositionsOfSmallSemisInEnum(enum, positions); -#SetFuncsOfSmallSemisInEnum(enum, []); -#SetNamesFuncsSmallSemisInEnum(enum, ["enumerator by ids", sizes]); -#SetSizesOfSmallSemisInEnum(enum, sizes); -SetIsFinite(enum, true); -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - -return enum; -end); - -################## - -InstallOtherMethod(EnumeratorOfSmallSemigroupsByIds, -"for a pos. int. and set of positions", -[IsPosInt, IsCyclotomicCollection], 0, +[IsCyclotomicCollection, IsCyclotomicCollColl], function(sizes, positions) -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("EnumeratorOfSmallSemigroupsByIds 2")); + if not IsSet(sizes) then + Info(InfoWarning, + 1, + "the 1st argument (a cyclotomic coll.) must be a set!"); + return fail; + elif not ForAll(sizes, x -> x > 0 and x < 9) then + Info(InfoWarning, + 1, + "the 1st argument (a set of integers) must be in the range [0, 9)!"); + return fail; + elif Length(sizes) <> Length(positions) then + Info(InfoWarning, 1, "the 1st and 2nd arguments must have equal length"); + return fail; + elif not ForAll(positions, x -> ForAll(x, IsPosInt)) + or not ForAll(positions, IsSet) then + Info(InfoWarning, + 1, + "the 2nd argument must be a list of sets of positive integers"); + return fail; + elif ForAny([1 .. Length(positions)], + i -> Maximum(positions[i]) > NrSmallSemigroups(sizes[i])) then + Info(InfoWarning, + 1, + "all sets in 2nd argument must be in the range 1 to the number ", + "of semigroups"); + return fail; + fi; -return SMALLSEMI_RETURN(EnumeratorOfSmallSemigroupsByIds([sizes], [positions])); + return EnumeratorOfSmallSemigroupsByIdsNC(sizes, positions); end); -################## - -InstallOtherMethod(EnumeratorOfSmallSemigroupsByIdsNC, -"for a pos. int. and set of positions", -[IsPosInt, IsCyclotomicCollection], 0, +InstallMethod(EnumeratorOfSmallSemigroupsByIdsNC, +"for a set of pos. ints. and list of sets of positions", +[IsCyclotomicCollection, IsCyclotomicCollColl], 0, function(sizes, positions) + local fam, tot, lens, record, enum, i; -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("EnumeratorOfSmallSemigroupsByIdsNC 2")); - -return SMALLSEMI_RETURN(EnumeratorOfSmallSemigroupsByIdsNC([sizes], - [positions])); -end); - -################## + if ForAll(positions, IsEmpty) then + return EmptyEnumeratorOfSmallSemigroups(); + fi; -InstallOtherMethod(EnumeratorOfSmallSemigroupsByIds, -"for a list of smallsemi ids", [IsList], 0, -function(ids) -local id1, id2, i, pos; -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; + fam := CollectionsFamily(SmallSemigroupEltFamily); + tot := 0; + lens := [0]; -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("EnumeratorOfSmallSemigroupsByIds 3")); + for i in positions do + tot := tot + Length(i); + Add(lens, tot); + od; -ids:=Set(ids); + record := rec(); -if not ForAll(ids, IsIdSmallSemigroup) then - Info(InfoWarning, 1, - "argument must be a list of ids of small semigroups"); - return fail; -fi; + record.ElementNumber := function(enum, pos) + local i; + if pos > Length(enum) then + return fail; + fi; + i := PositionProperty(lens, x -> pos <= x) - 1; + return SmallSemigroupNC(sizes[i], positions[i][pos - lens[i]]); + end; + + record.NumberElement := function(_, elm) + local id; + id := IdSmallSemigroup(elm); + return PositionSorted(positions[id[1]], id[2]); + end; + + record.Length := enum -> tot; + + record.PrintObj := function(_) + Print(" 1 then + Print("s ", sizes, ">"); + else + Print(" ", sizes[1], ">"); + fi; + return; + end; + + record.pos := positions; + record.sizes := sizes; + record.names := ["enumerator by ids", sizes]; + record.funcs := []; + + enum := EnumeratorByFunctions(Domain(fam, []), record); + SetIsEnumeratorOfSmallSemigroups(enum, true); + SetIsFinite(enum, true); + return enum; +end); -#JDM changes here +InstallMethod(EnumeratorOfSmallSemigroupsByIds, +"for a pos. int. and set of positions", [IsPosInt, IsCyclotomicCollection], +{sizes, positions} -> EnumeratorOfSmallSemigroupsByIds([sizes], [positions])); -#sort the ids etc +InstallMethod(EnumeratorOfSmallSemigroupsByIdsNC, +"for a pos. int. and set of positions", [IsPosInt, IsCyclotomicCollection], +{sizes, positions} -> EnumeratorOfSmallSemigroupsByIdsNC([sizes], [positions])); -#id1:=Set(List(ids, x-> x[1])); -#id2:=List(ids, x-> []); -#for i in [1..Length(ids)] do -# Add(id2[i], ids[i][2]); -#od; +InstallMethod(EnumeratorOfSmallSemigroupsByIds, +"for a list of smallsemi ids", [IsList], +function(ids) + local id1, id2, i, pos; -id1:=[]; id2:=[]; + ids := Set(ids); -for i in ids do - pos:=PositionSet(id1, i[1]); - if pos = fail then - AddSet(id1, i[1]); - id2[PositionSet(id1, i[1])]:=[i[2]]; - else - AddSet(id2[pos], i[2]); - fi; -od; + if not ForAll(ids, IsIdSmallSemigroup) then + Info(InfoWarning, 1, + "argument must be a list of ids of small semigroups"); + return fail; + fi; -#Print(id1, id2, "\n"); + id1 := []; + id2 := []; -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; + for i in ids do + pos := PositionSet(id1, i[1]); + if pos = fail then + AddSet(id1, i[1]); + id2[PositionSet(id1, i[1])] := [i[2]]; + else + AddSet(id2[pos], i[2]); + fi; + od; -return SMALLSEMI_RETURN(EnumeratorOfSmallSemigroupsByIdsNC(id1, id2)); + return EnumeratorOfSmallSemigroupsByIdsNC(id1, id2); end); -############################################################################# -InstallGlobalFunction( EnumeratorOfSmallSemigroupsByDiagonals, +InstallGlobalFunction(EnumeratorOfSmallSemigroupsByDiagonals, function(diagonals) local sizes, ranges, diag, n, sizepos, diagpos, start, ende, i, offset, id; - sizes := [ ]; - ranges := [ ]; + sizes := []; + ranges := []; for diag in diagonals do - n := Length(diag); - sizepos := Position(sizes, n); - diagpos := Position(MOREDATA2TO8[n].diags, diag); - start := MOREDATA2TO8[n].endpositions[diagpos]+1; - ende := MOREDATA2TO8[n].endpositions[diagpos+1]; - if sizepos = fail then - Add(sizes, n); - sizepos := Length(sizes); - Add(ranges, [start..ende]); - else - ranges[sizepos] := Union(ranges[sizepos], [start..ende]); - fi; - offset := 11433106; - if n = 8 then - for i in [3..8] do - diagpos := Position(MOREDATA2TO8[n].3nildiags, diag{[i..n]}); - if diagpos <> fail then - start := MOREDATA2TO8[n].3nilendpositions[diagpos]+1; - ende := MOREDATA2TO8[n].3nilendpositions[diagpos+1]; - id := start + offset; - repeat - Add(ranges[sizepos], id); - id := id+1; - until id > ende + offset; - fi; - od; - fi; + n := Length(diag); + sizepos := Position(sizes, n); + diagpos := Position(MOREDATA2TO8[n].diags, diag); + start := MOREDATA2TO8[n].endpositions[diagpos] + 1; + ende := MOREDATA2TO8[n].endpositions[diagpos + 1]; + if sizepos = fail then + Add(sizes, n); + sizepos := Length(sizes); + Add(ranges, [start .. ende]); + else + ranges[sizepos] := Union(ranges[sizepos], [start .. ende]); + fi; + offset := 11433106; + if n = 8 then + for i in [3 .. 8] do + diagpos := Position(MOREDATA2TO8[n].3nildiags, diag{[i .. n]}); + if diagpos <> fail then + start := MOREDATA2TO8[n].3nilendpositions[diagpos] + 1; + ende := MOREDATA2TO8[n].3nilendpositions[diagpos + 1]; + id := start + offset; + repeat + Add(ranges[sizepos], id); + id := id + 1; + until id > ende + offset; + fi; + od; + fi; od; - return EnumeratorOfSmallSemigroupsByIds(sizes, ranges); end); - - -################## - -#InstallOtherMethod(EnumeratorOfSmallSemigroupsByIdsNC, -#"for a list of small semi ids", [IsList], 0, -#function(ids) - -#SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -#Info(InfoSmallsemi, 3, SMALLSEMI_ENTAB("EnumeratorOfSmallSemigroupsByIdsNC")); - -#return SMALLSEMI_RETURN(EnumeratorOfSmallSemigroupsByIdsNC(ids[1], ids[2])); -#end); - - -################## - -InstallGlobalFunction(EnumeratorSortedOfSmallSemigroups, -function(arg) - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("EnumeratorSortedOfSmallSemigroups")); - -arg:=SMALLSEMI_STRIP_ARG(arg); - -return SMALLSEMI_RETURN(EnumeratorOfSmallSemigroups(arg)); +InstallGlobalFunction(EnumeratorSortedOfSmallSemigroups, +function(arg...) + return CallFuncList(EnumeratorOfSmallSemigroups, arg); end); -################## - -InstallGlobalFunction(IdsOfSmallSemigroups, -function(arg) -local enum, size, pos; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("IdsOfSmallSemigroups")); +InstallGlobalFunction(IdsOfSmallSemigroups, +function(arg...) + local enum, size, pos; -enum:=EnumeratorOfSmallSemigroups(arg); -size:=SizesOfSmallSemisInEnum(enum); -pos:=PositionsOfSmallSemisInEnum(enum); + enum := EnumeratorOfSmallSemigroups(arg); + size := SizesOfSmallSemisInEnum(enum); + pos := PositionsOfSmallSemisInEnum(enum); -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; -return Concatenation(List([1..Length(size)], x-> List(pos[x], y-> [size[x], y]))); + return Concatenation(List([1 .. Length(size)], + x -> List(pos[x], y -> [size[x], y]))); end); -############### - -InstallOtherMethod(IsEnumeratorOfSmallSemigroups, "for an object", [IsObject], 0, +InstallMethod(IsEnumeratorOfSmallSemigroups, "for an object", [IsObject], ReturnFalse); -############### - -InstallGlobalFunction(IsIdSmallSemigroup, -function(arg) -local m, n, nr; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("IsIdSmallSemigroup")); - -if Length(arg)=2 and IsPosInt(arg[1]) and IsPosInt(arg[2]) then - m:=arg[1]; - n:=arg[2]; -elif Length(arg)=1 and IsCyclotomicCollection(arg[1]) and Length(arg[1])=2 then - return SMALLSEMI_RETURN(IsIdSmallSemigroup(arg[1][1], arg[1][2])); -else - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return false; -fi; +InstallGlobalFunction(IsIdSmallSemigroup, +function(arg...) + local m, n, nr; + + if Length(arg) = 2 and IsPosInt(arg[1]) and IsPosInt(arg[2]) then + m := arg[1]; + n := arg[2]; + elif Length(arg) = 1 and IsCyclotomicCollection(arg[1]) + and Length(arg[1]) = 2 then + return IsIdSmallSemigroup(arg[1][1], arg[1][2]); + else + return false; + fi; -nr:=NrSmallSemigroups(m); -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; + nr := NrSmallSemigroups(m); -return 0 enum!.funcs); - -InstallGlobalFunction(FuncsOfSmallSemisInIter, -enum-> enum!.funcs); - -############### - -InstallOtherMethod(IsIteratorOfSmallSemigroups, "for an object", [IsObject], 0, +InstallOtherMethod(IsIteratorOfSmallSemigroups, "for an object", [IsObject], ReturnFalse); -############### - -BindGlobal( "PrintObj_IsIteratorOfSmallSemigroups", +BindGlobal("PrintObj_IsIteratorOfSmallSemigroups", function(iter) -if not iter!.sizes=[0] then - if Length(iter!.sizes)>1 then - Print( ""); - return; - else - Print( ""); - fi; -else - Print( ""); -fi; -end); - -############### - -InstallGlobalFunction(IteratorOfSmallSemigroups, -function ( arg ) -local iter, enum, user, i, max, sizes, names, funcs; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("IteratorOfSmallSemigroups")); - -arg:=SMALLSEMI_STRIP_ARG(arg); - -if not SMALLSEMI_ARG_OK( arg ) then - Error("argument is incorrect"); - #JDM could just call SMALLSEMI_ARG_OK and have errors from there -fi; - -if Length(arg)=1 and IsPosInt(arg[1]) then #all semigroups - - iter:=IteratorByFunctions( rec( - - IsDoneIterator := iter-> iter!.next(iter, false)=fail, - - NextIterator := iter-> iter!.next(iter, true), - - PrintObj := PrintObj_IsIteratorOfSmallSemigroups, - - next:=function(iter, advance) - - if iter!.at=iter!.max then - return fail; - fi; - - if advance then - iter!.at:=iter!.at+1; - return SmallSemigroupNC(arg[1], iter!.at); - fi; - - return true; - end, - - ShallowCopy := SHALLOWCOPYITERATORSMALLSEMI, - - at := 0, - - max:= NrSmallSemigroups(arg[1]), - - enum:=[], - - user:=[], - - sizes:=[arg[1]], - - funcs:=[], - - names:=["AllSmallSemigroups", arg[1]] - - )); - - SetIsIteratorOfSmallSemigroups(iter, true); - #SetSizesOfSmallSemisInIter(iter, [arg[1]]); - #SetFuncsOfSmallSemisInIter(iter, []); - #SetNamesFuncsSmallSemisInIter(iter, ["AllSmallSemigroups", arg[1]]); - return iter; - -elif IsOddInt(Length(arg)) and (IsPosInt(arg[1]) or - IsEnumeratorOfSmallSemigroups(arg[1]) or - IsIteratorOfSmallSemigroups(arg[1]) or - (IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt))) then - #for a list of functions and their values - - if IsPosInt(arg[1]) then - sizes:=[arg[1]]; - names:=[]; - funcs:=[]; - elif IsEnumeratorOfSmallSemigroups(arg[1]) then - if Length(arg[1])=0 then - return SMALLSEMI_RETURN(EmptyIteratorOfSmallSemigroups()); - fi; - sizes:=SizesOfSmallSemisInEnum(arg[1]); - names:=NamesFuncsSmallSemisInEnum(arg[1]); - funcs:=FuncsOfSmallSemisInEnum(arg[1]); - elif IsIteratorOfSmallSemigroups(arg[1]) then - sizes:=SizesOfSmallSemisInIter(arg[1]); - names:=NamesFuncsSmallSemisInIter(arg[1]); - funcs:=FuncsOfSmallSemisInIter(arg[1]); - elif IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt) then - sizes:=arg[1]; - names:=[]; - funcs:=[]; - fi; - - arg:=SMALLSEMI_SORT_ARG_NC(SMALLSEMI_CONVERT_ARG_NC(arg)); - - enum:=[arg[1]]; - user:=[]; - - for i in [2,4..Length(arg)-1] do - if NAME_FUNC(arg[i]) in SMALLSEMI_ALWAYS_FALSE and arg[i+1] then - return SMALLSEMI_RETURN(EmptyIteratorOfSmallSemigroups()); - elif ForAll(sizes, j-> NAME_FUNC(arg[i]) - in PrecomputedSmallSemisInfo[j]) then #precomputed function - enum:=Concatenation(enum, [arg[i], arg[i+1]]); - else #user function - user:=Concatenation(user, [arg[i], arg[i+1]]); - fi; - od; - - if IsEnumeratorOfSmallSemigroups(arg[1]) and enum=[arg[1]] then - enum:=enum[1]; - max:=Length(enum); - if Length(enum)=0 then - return EmptyIteratorOfSmallSemigroups(); - fi; - elif not enum=[arg[1]] and SMALLSEMI_CAN_CREATE_ENUM_NC(enum) then - enum:=EnumeratorOfSmallSemigroups(enum); - max:=Length(enum); - if Length(enum)=0 then - return EmptyIteratorOfSmallSemigroups(); - fi; - else - enum:=[]; - max:=Sum(sizes, j-> NrSmallSemigroups(j)); - user:=arg{[2..Length(arg)]}; - fi; - - iter:=IteratorByFunctions( rec( - - #JDM changes here... - - IsDoneIterator := iter-> iter!.next(iter, IsDoneIterator)=fail, - - NextIterator := iter-> iter!.next(iter, NextIterator), - - PrintObj := PrintObj_IsIteratorOfSmallSemigroups, - - next:=function(iter, called_by) #JDM new! - local enum, user, s; - - if iter!.last_called = IsDoneIterator then - iter!.last_called := called_by; - return iter!.last_value; - fi; - - if iter!.last_called = NextIterator then - iter!.last_called := called_by; - if iter!.at=iter!.max or iter!.last_value=fail then - iter!.last_value:=fail; - return fail; - fi; - - enum:=iter!.enum; user:=iter!.user; - - if not enum=[] and Length(enum)<=iter!.at then - #JDM shouldn't this be IdSmallSemigroup(enum[Length[enum]])[2]<= - iter!.last_value:=fail; - return fail; - fi; - - repeat - iter!.at:=iter!.at+1; - if not enum=[] then - s:=enum[iter!.at]; - else - s:=SmallSemigroupNC(iter!.at_size, iter!.at- - Sum(Filtered(iter!.sizes, x-> x< iter!.at_size), - NrSmallSemigroups)); - fi; - - if not enum=[] then - iter!.at_size:=Size(s); - elif Length(iter!.sizes)>1 and iter!.at x< iter!.at_size), - NrSmallSemigroups)>=NrSmallSemigroups(iter!.at_size) then - iter!.at_size:= - iter!.sizes[Position(iter!.sizes, iter!.at_size)+1]; - fi; - - if Length(user)=0 then - iter!.last_value:=s; - return s; - elif ForAll([1,3..Length(user)-1], i-> user[i](s)=user[i+1]) - then - iter!.last_value:=s; - return s; - else - iter!.last_value:=fail; - fi; - until iter!.at=iter!.max; - - iter!.last_value:=fail; - return fail; - fi; - end, - - last_called := NextIterator, - - last_value := 0, - - #JDM ...changes end. - - ShallowCopy:= SHALLOWCOPYITERATORSMALLSEMI, - - at := 0, - - max:= max, - - enum:=enum, - - user:=user, - - sizes:=sizes, #JDM changed from n - - at_size:=sizes[1], - - funcs:=Concatenation(funcs, arg{[2.. - Length(arg)]}), - - names:= Concatenation(names, List(arg{[2.. - Length(arg)]}, - function(x) - if IsFunction(x) then return - NAME_FUNC(x); else return x; fi; - end)) - )); - - - SetIsIteratorOfSmallSemigroups(iter, true); - #SetNamesFuncsSmallSemisInIter(iter, Concatenation(names, List(arg{[2..Length(arg)]}, - #function(x) - #if IsFunction(x) then return NAME_FUNC(x); else return x; fi; end))); - #SetFuncsOfSmallSemisInIter(iter, Concatenation(funcs, arg{[2..Length(arg)]})); - #SetSizesOfSmallSemisInIter(iter, sizes); - - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return iter; - -fi; - + if iter!.sizes = [0] then + Print(""); + fi; + Print(" 1 then + Print("s ", iter!.sizes, ">"); + else + Print(" ", iter!.sizes[1], ">"); + fi; end); -################## - -InstallGlobalFunction(NamesFuncsSmallSemisInEnum, -enum-> enum!.names); - -InstallGlobalFunction(NamesFuncsSmallSemisInIter, -enum-> enum!.names); - -################## - -InstallGlobalFunction(Nr3NilpotentSemigroups, function( arg ) - - local size, # input, order of semigroups - type, # optional input, type of semigroups - types, # list of valid second (optional) arguments - i, # loop counter - - nr3NilIso, - # takes a positive integer as input and returns the number of - # 3-nilpotent semigroups with elements up to isomorphism - - nr3NilSelfDual, - # takes a positive integer as input and returns the number of - # self-dual 3-nilpotent semigroups with elements - - nr3NilComm, - # takes a positive integer as input and returns the number of - # commutative 3-nilpotent semigroups with elements up to iso - - nr3NilAll, - # takes a positive integer as input and returns the number of - # all different 3-nilpotent semigroups on a set with elements - - nr3NilAllComm, - # takes a positive integer as input and returns the number of - # all different, commutative 3-nilpotent semigroups on a set with - # elements - - sizeConjugacyClass, - # returns for a partition of the number of permutations - # in the symmetric group on elements with disjoint cycle - # notation given by (corresponds to a conjugacy class) - - transformPart; - # takes a partition as a list of summands and returns a vector with - # the number of summands with value i in the i-th position - - ################################################################## - ### local functions - - - sizeConjugacyClass := function( partition ) - return Factorial( Sum( partition ) ) / - Product( Collected(partition), pair -> Factorial(pair[2])* - pair[1]^pair[2] ); - end; - - - transformPart := function( part ) - - local n, coll, i, jvec; - - n := Sum( part ); - jvec := [ ]; - coll := Collected(part); - for i in [1..n] do - if IsBound( coll[1] ) and coll[1][1] = i then - Add( jvec, coll[1][2] ); - Remove( coll , 1 ); - else - Add( jvec, 0 ); - fi; - od; - - return jvec; +InstallGlobalFunction(IteratorOfSmallSemigroups, +function(arg...) + local record, iter, sizes, names, funcs, enum, user, max, i; + + arg := SMALLSEMI_STRIP_ARG(arg); + SMALLSEMI_ValidateArgs(arg); + + if Length(arg) = 1 and IsPosInt(arg[1]) then + # all semigroups + record := rec(); + + record.IsDoneIterator := iter -> iter!.next(iter, false) = fail; + record.NextIterator := iter -> iter!.next(iter, true); + record.PrintObj := PrintObj_IsIteratorOfSmallSemigroups; + + record.next := function(iter, advance) + if iter!.at = iter!.max then + return fail; + elif advance then + iter!.at := iter!.at + 1; + return SmallSemigroupNC(arg[1], iter!.at); + fi; + return true; end; + record.ShallowCopy := SHALLOWCOPYITERATORSMALLSEMI; + record.at := 0; + record.max := NrSmallSemigroups(arg[1]); + record.enum := []; + record.user := []; + record.sizes := [arg[1]]; + record.funcs := []; + record.names := ["AllSmallSemigroups", arg[1]]; + + iter := IteratorByFunctions(record); + SetIsIteratorOfSmallSemigroups(iter, true); + return iter; + fi; - nr3NilIso := function( n ) + if IsPosInt(arg[1]) then + sizes := [arg[1]]; + names := []; + funcs := []; + elif IsEnumeratorOfSmallSemigroups(arg[1]) then + if IsEmpty(arg[1]) then + return EmptyIteratorOfSmallSemigroups(); + fi; + sizes := SizesOfSmallSemisInEnum(arg[1]); + names := NamesFuncsSmallSemisInEnum(arg[1]); + funcs := FuncsOfSmallSemisInEnum(arg[1]); + elif IsIteratorOfSmallSemigroups(arg[1]) then + sizes := SizesOfSmallSemisInIter(arg[1]); + names := NamesFuncsSmallSemisInIter(arg[1]); + funcs := FuncsOfSmallSemisInIter(arg[1]); + else + # list of positive integers + sizes := arg[1]; + names := []; + funcs := []; + fi; - local NrIsomorphismClasses; + arg := SMALLSEMI_SORT_ARG_NC(SMALLSEMI_CONVERT_ARG_NC(arg)); - NrIsomorphismClasses := function( n, m ) - local parts, sum, nrs, Produkt; + enum := [arg[1]]; + user := []; - Produkt := function( p1, p2 ) - local prod, i, j; + for i in [2, 4 .. Length(arg) - 1] do + if NAME_FUNC(arg[i]) in SMALLSEMI_ALWAYS_FALSE and arg[i + 1] then + return EmptyIteratorOfSmallSemigroups(); + elif ForAll(sizes, + j -> NAME_FUNC(arg[i]) in PrecomputedSmallSemisInfo[j]) then + # precomputed function + enum := Concatenation(enum, [arg[i], arg[i + 1]]); + else + # user function + user := Concatenation(user, [arg[i], arg[i + 1]]); + fi; + od; - prod := 1; + if IsEnumeratorOfSmallSemigroups(arg[1]) and enum = [arg[1]] then + enum := enum[1]; + max := Length(enum); + if IsEmpty(enum) then + return EmptyIteratorOfSmallSemigroups(); + fi; + elif enum <> [arg[1]] and SMALLSEMI_CAN_CREATE_ENUM_NC(enum) then + enum := EnumeratorOfSmallSemigroups(enum); + max := Length(enum); + if IsEmpty(enum) then + return EmptyIteratorOfSmallSemigroups(); + fi; + else + enum := []; + max := Sum(sizes, NrSmallSemigroups); + user := arg{[2 .. Length(arg)]}; + fi; - for i in [ 1.. Length(p1) ] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[i] <> 0 then - for j in [ 1..Length(p1) ] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[j] <> 0 then - prod := prod * - (1+Sum(Filtered(DivisorsInt(Lcm(i, j)), - x -> x <= Length(p2)), - d->d*p2[d])) - ^(p1[i]*p1[j]*Gcd(i,j)); - fi; - od; - fi; - od; + record := rec(); - return prod; - end; + record.IsDoneIterator := iter -> iter!.next(iter, IsDoneIterator) = fail; + record.NextIterator := iter -> iter!.next(iter, NextIterator); + record.PrintObj := PrintObj_IsIteratorOfSmallSemigroups; - # only the zero semigroup in the case |B|=1 - if m = 1 then - return 1; - fi; + record.next := function(iter, called_by) + local enum, user, s; - # the elements in the Cartesian product are pairs of partitions - # they stand for elements in a conjugacy class of S_{n-m} x S_{m-1} - parts := Cartesian( Partitions( n-m ), Partitions( m-1 )); + if iter!.last_called = IsDoneIterator then + iter!.last_called := called_by; + return iter!.last_value; + fi; - # pp is a partition pair - nrs := List(parts, - pp -> Produkt(transformPart(pp[1]), - Concatenation(transformPart(pp[2]),[0]))* - sizeConjugacyClass(pp[1]) * sizeConjugacyClass(pp[2])); + if iter!.last_called = NextIterator then + iter!.last_called := called_by; + if iter!.at = iter!.max or iter!.last_value = fail then + iter!.last_value := fail; + return fail; + fi; + + enum := iter!.enum; + user := iter!.user; + + if not IsEmpty(enum) and Length(enum) <= iter!.at then + iter!.last_value := fail; + return fail; + fi; + + repeat + iter!.at := iter!.at + 1; + if not IsEmpty(enum) then + s := enum[iter!.at]; + else + s := SmallSemigroupNC(iter!.at_size, + iter!.at - + Sum(Filtered(iter!.sizes, + x -> x < iter!.at_size), + NrSmallSemigroups)); + fi; - return Sum( nrs ) / (Factorial( n-m ) * Factorial( m-1 )); - end; + if not IsEmpty(enum) then + iter!.at_size := Size(s); + elif Length(iter!.sizes) > 1 + and iter!.at < iter!.max + and iter!.at - Sum(Filtered(iter!.sizes, x -> x < iter!.at_size), + NrSmallSemigroups) >= + NrSmallSemigroups(iter!.at_size) then + iter!.at_size := iter!.sizes[Position(iter!.sizes, iter!.at_size) + 1]; + fi; - return Sum([2..n-1], - m -> NrIsomorphismClasses(n,m) - NrIsomorphismClasses(n-1,m-1)); + if IsEmpty(user) then + iter!.last_value := s; + return s; + elif ForAll([1, 3 .. Length(user) - 1], + i -> user[i](s) = user[i + 1]) then + iter!.last_value := s; + return s; + else + iter!.last_value := fail; + fi; + until iter!.at = iter!.max; + + iter!.last_value := fail; + return fail; + fi; end; + record.last_called := NextIterator; + record.last_value := 0; + record.ShallowCopy := SHALLOWCOPYITERATORSMALLSEMI; + record.at := 0; + record.max := max; + record.enum := enum; + record.user := user; + record.sizes := sizes; + record.at_size := sizes[1]; + record.funcs := Concatenation(funcs, arg{[2 .. Length(arg)]}); + + record.names := Concatenation(names, + List(arg{[2 .. Length(arg)]}, + SMALLSEMI_FuncNameOrString)); + + iter := IteratorByFunctions(record); + SetIsIteratorOfSmallSemigroups(iter, true); + return iter; +end); - nr3NilSelfDual := function( n ) - - local NrEquivalenceClasses; - - NrEquivalenceClasses := function( n, m ) - local parts, sum, nrs, Produkt, Prod1, Prod2, Prod3, Prod4, smallc; - - smallc := function( int, part ) - return 1 + Sum( Filtered( DivisorsInt( int ), - x -> x <= Length(part)), - d -> d * part[d] ); - end; - - Prod1 := function( p1, p2 ) - local prod, i; - - prod := 1; - - for i in [1..Minimum( Int((Length(p1)+1)/2), Int((n+1)/2) )] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[2*i-1] <> 0 then - prod := prod * - (smallc(2*i-1,p2)*smallc(4*i-2,p2)^(i-1)) - ^(p1[2*i-1]); - fi; - od; +InstallGlobalFunction(NrSmallSemigroups, +function(arg...) + local numb; - return prod; - end; + if Length(arg) = 1 and IsPosInt(arg[1]) then + numb := [1, 4, 18, 126, 1160, 15973, 836021, 1843120128]; + if arg[1] > 0 and arg[1] <= 8 then + return numb[arg[1]]; + else + Error("only semigroups of sizes from 1 to 8 are in the library"); + fi; + fi; + return Sum(List(PositionsOfSmallSemigroups(arg), Length)); +end); - Prod2 := function( p1, p2 ) - local prod, i; +InstallGlobalFunction(OneSmallSemigroup, +function(arg...) + local iter; - prod := 1; + if Length(arg) = 1 then + if IsEnumeratorOfSmallSemigroups(arg[1]) and IsEmpty(arg[1]) then + return arg[1][1]; + elif IsIteratorOfSmallSemigroups(arg[1]) then + iter := arg[1]; + else + iter := IteratorOfSmallSemigroups(arg); + fi; + else + iter := IteratorOfSmallSemigroups(arg); + fi; - for i in [ 1..Minimum( Int(Length(p1)/4), Int(n/4) ) ] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[4*i] <> 0 then - prod := prod * smallc(4*i,p2)^(4*i*p1[4*i]); - fi; - od; + if not IsDoneIterator(iter) then + return NextIterator(IteratorOfSmallSemigroups(arg)); + fi; + return fail; +end); - return prod; - end; +InstallGlobalFunction(PositionsOfSmallSemigroups, +function(arg...) + local stored, sizes, enum, user, i, j, positions, out, enum2, s; - Prod3 := function( p1, p2 ) - local prod, i; + arg := SMALLSEMI_STRIP_ARG(arg); + SMALLSEMI_ValidateArgs(arg); - prod := 1; + arg := SMALLSEMI_CONVERT_ARG_NC(arg); + arg := SMALLSEMI_SORT_ARG_NC(arg); - for i in [ 1..Minimum( Int((Length(p1)+2)/4), Int(n+2/4) ) ] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[4*i-2] <> 0 then - prod := prod * - (smallc(2*i-1,p2)^2*smallc(4*i-2,p2)^(4*i-3)) - ^p1[4*i-2]; - fi; - od; + if not SMALLSEMI_CAN_CREATE_ENUM_NC(arg) then + Error("cannot create an enumerator or list of positions with input"); + fi; - return prod; - end; + # a single stored value + if IsPosInt(arg[1]) and Length(arg) = 3 and arg[3] = true then + stored := STORED_INFO(arg[1], NAME_FUNC(arg[2])); + if stored <> fail then + return [stored]; + fi; + fi; - Prod4 := function( p1, p2 ) - local prod, i, j; + # all semigroups not of order 8 + if Length(arg) = 1 and IsPosInt(arg[1]) then + return [[1 .. NrSmallSemigroups(arg[1])]]; + elif IsOddInt(Length(arg)) and (IsPosInt(arg[1]) + or IsEnumeratorOfSmallSemigroups(arg[1]) + or IsIteratorOfSmallSemigroups(arg[1]) + or (IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt))) then + # for a list of functions and their values + + # find sizes of semigroups + if IsPosInt(arg[1]) then + sizes := [arg[1]]; + elif IsEnumeratorOfSmallSemigroups(arg[1]) then + sizes := SizesOfSmallSemisInEnum(arg[1]); + elif IsIteratorOfSmallSemigroups(arg[1]) then + sizes := SizesOfSmallSemisInIter(arg[1]); + elif IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt) then + sizes := arg[1]; + fi; - prod := 1; + enum := [arg[1]]; + user := []; - for i in [ 1.. Length(p1) ] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[i] <> 0 then - prod := prod * smallc(Lcm(2,i),p2) - ^(i*Gcd(2,i)*(p1[i]^2-p1[i])/2); - for j in [ 1..Minimum( Length(p1), i-1 ) ] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[j] <> 0 then - prod := prod * smallc(Lcm(2,i,j),p2) - ^(p1[i]*p1[j]*2*i*j/Lcm(2,i,j)); - fi; - od; - fi; - od; + if IsIteratorOfSmallSemigroups(arg[1]) then + arg := Concatenation([SizesOfSmallSemisInIter(arg[1])], + arg{[2 .. Length(arg)]}, + FuncsOfSmallSemisInIter(arg[1])); + arg := SMALLSEMI_SORT_ARG_NC(SMALLSEMI_CONVERT_ARG_NC(arg)); + fi; - return prod; - end; + # split input into precomputed and user + for i in [2, 4 .. Length(arg) - 1] do + if NAME_FUNC(arg[i]) in SMALLSEMI_ALWAYS_FALSE and arg[i + 1] then + return []; + elif ForAll(sizes, + j -> NAME_FUNC(arg[i]) in PrecomputedSmallSemisInfo[j]) then + enum := Concatenation(enum, [arg[i], arg[i + 1]]); + else # user function + user := Concatenation(user, [arg[i], arg[i + 1]]); + fi; + od; - Produkt := function( p1, p2 ); - return Prod1(p1, p2)*Prod2(p1, p2)*Prod3(p1, p2)*Prod4(p1, p2); - end; + # initialize positions + if IsEnumeratorOfSmallSemigroups(arg[1]) then + positions := List(PositionsOfSmallSemisInEnum(arg[1]), ShallowCopy); + elif ForAny([3, 5 .. Length(enum)], i -> enum[i] = true) then + i := First([3, 5 .. Length(enum)], i -> enum[i] = true); + positions := List(sizes, j -> ShallowCopy(STORED_INFO(j, + NAME_FUNC(enum[i - 1])))); + else + positions := List(sizes, i -> [1 .. NrSmallSemigroups(i)]); + fi; - # only the zero semigroup in the case |B|=1, counted half - if m = 1 then - return 1; + # find what function values are stored already + for j in [1 .. Length(sizes)] do + if Length(enum) > 1 then # not just arg[1] + i := 0; + repeat + i := i + 2; + stored := STORED_INFO(sizes[j], NAME_FUNC(enum[i])); + if stored <> fail then + if enum[i + 1] = true then + IntersectSet(positions[j], stored); + elif enum[i + 1] = false then + SubtractSet(positions[j], stored); fi; - - # the elements in the Cartesian product are pairs of partitions - # they stand for elements in a conjugacy class of S_{n-m} x S_{m-1} - parts := Cartesian( Partitions( n-m ), Partitions( m-1 )); - - # pp is a partition pair - nrs := List(parts, - pp -> Produkt(transformPart(pp[1]), - Concatenation(transformPart(pp[2]),[0]))* - sizeConjugacyClass(pp[1])* sizeConjugacyClass(pp[2])); - - return Sum( nrs ) / (Factorial( n-m ) * Factorial( m-1 )); - end; - - return Sum([2..n-1], - m -> NrEquivalenceClasses(n,m) - NrEquivalenceClasses(n-1,m-1)); - end; - - - nr3NilComm := function( n ) - - local NrIsomorphismClasses; - - NrIsomorphismClasses := function( n, m ) - local parts,sum,nrs, Produkt, Produkt1, Produkt2, Produkt3, smallc; - - smallc := function( int, part ) - return 1 + Sum( Filtered( DivisorsInt( int ), - x -> x <= Length(part)), - d -> d * part[d] ); - end; - - Produkt1 := function( p1, p2 ) - local prod, i; - - prod := 1; - - for i in [ 1..Minimum( Int(Length(p1)/2), Int(n/2) ) ] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[2*i] <> 0 then - prod := prod * - (smallc(i,p2)*smallc(2*i,p2)^i)^p1[2*i]; - fi; - od; - - return prod; - end; - - Produkt2 := function( p1, p2 ) - local prod, i; - - prod := 1; - - for i in [1..Minimum( Int((Length(p1)+1)/2), Int((n+1)/2) )] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[2*i-1] <> 0 then - prod := prod * - (smallc(2*i-1,p2))^(i*p1[2*i-1]); - fi; - od; - - return prod; - end; - - Produkt3 := function( p1, p2 ) - local prod, i, j; - - prod := 1; - - for i in [ 1.. Length(p1) ] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[i] <> 0 then - prod := prod * smallc(i,p2)^(i*(p1[i]^2-p1[i])/2); - for j in [ 1..Minimum( Length(p1), i-1 ) ] do - # if exponent is 0, prod is multiplied by 1 => omit - if p1[j] <> 0 then - prod := prod * smallc(Lcm(i,j),p2) - ^(p1[i]*p1[j]*Gcd(i,j)); - fi; - od; - fi; - od; - - return prod; - end; - - Produkt := function( p1,p2 ); - return Produkt1( p1,p2 )*Produkt2( p1,p2 )*Produkt3( p1,p2 ); - end; - - # only the zero semigroup in the case |B|=1 - if m = 1 then - return 1; + fi; + until i = Length(enum) - 1 or IsEmpty(positions[j]); + fi; + + # compute the values of any remaining functions + if not IsEmpty(user) and not IsEmpty(positions[j]) then + i := -1; + + repeat + enum2 := EnumeratorOfSmallSemigroupsByIds(sizes[j], positions[j]); + i := i + 2; + out := []; + for s in [1 .. Length(enum2)] do + if InfoLevel(InfoSmallsemiEnums) = 4 then + Print(" #I at ", s, " of ", Length(enum2), "\r"); fi; + s := enum2[s]; + if user[i](s) = user[i + 1] then + Add(out, IdSmallSemigroup(s)[2]); + fi; + od; + IntersectSet(positions[j], out); + until i = Length(user) - 1 or IsEmpty(positions[j]); + fi; + od; + fi; - # the elements in the Cartesian product are pairs of partitions - # they stand for elements in a conjugacy class of S_{n-m} x S_{m-1} - parts := Cartesian( Partitions( n-m ), Partitions( m-1 )); - - # pp is a partition pair - nrs := List(parts, - pp -> Produkt(transformPart(pp[1]), - Concatenation(transformPart(pp[2]),[0]))* - sizeConjugacyClass(pp[1])* sizeConjugacyClass(pp[2])); - - return Sum( nrs ) / (Factorial( n-m ) * Factorial( m-1 )); - end; - - return Sum([2..n-1], - m -> NrIsomorphismClasses(n,m) - NrIsomorphismClasses(n-1,m-1)); - end; - + if InfoLevel(InfoSmallsemiEnums) = 4 then + Print("\n"); + fi; - nr3NilAll := function( n ) - return Sum([2..Int(n + 1/2 - RootInt(n-1))], - k -> Binomial(n,k) * k - * Sum([0..k-1], - i -> (-1)^i * Binomial(k-1,i) - *(k-i)^((n-k)^2))); - end; + return positions; +end); +InstallGlobalFunction(RandomSmallSemigroup, +function(arg...) + local iter, i, j, s, t, enum; - nr3NilAllComm := function( n ) - return Sum([1..Int(n + 3/2 - RootInt(2*n))], - k -> Binomial(n,k) * k - * Sum([0..k-1], - i -> (-1)^i * Binomial(k-1,i) - * (k-i)^((n-k)*(n-k+1)/2))); - end; + arg := SMALLSEMI_STRIP_ARG(arg); - ################################################################## - ### MAIN FUNCTION - - types := ["UpToEquivalence", "UpToIsomorphism", "SelfDual", "Commutative", - "Labelled", "Labelled-Commutative" ]; - - # check input - if Length( arg ) > 2 then - Error( "number of arguments must be two" ); - elif not IsPosInt( arg[1] ) then - Error( "first argument must be a positive integer" ); - elif Length( arg ) = 2 and not IsString( arg[2] ) then - Error( "second argument must be a string" ); - elif Length( arg ) = 2 and not arg[2] in types then - Error( "invalid second argument, string must be in ", types ); + if Length(arg) = 1 and IsPosInt(arg[1]) then + i := Random(SMALLSEMI_RS, 1, NrSmallSemigroups(arg[1])); + return SmallSemigroupNC(arg[1], i); + elif SMALLSEMI_CAN_CREATE_ENUM_NC(arg) then + enum := EnumeratorOfSmallSemigroups(arg); + if not IsEmpty(enum) then + i := Random([1 .. Length(enum)]); + return enum[i]; fi; - - # get input - size := arg[1]; - if Length( arg ) = 2 then - type := arg[2]; - else - type := types[1]; + return fail; + fi; + iter := IteratorOfSmallSemigroups(arg); + i := 0; + j := Random(SMALLSEMI_RS, 1, 500); + t := Runtime(); + + if not IsDoneIterator(iter) then # in case of the empty iterator + repeat + i := i + 1; + s := NextIterator(iter); + until IsDoneIterator(iter) or Runtime() - t > j; + + if IsDoneIterator(iter) and i > 1 then + iter := IteratorOfSmallSemigroups(arg); + for j in [1 .. RandomList([1 .. i - 1])] do + s := NextIterator(iter); + od; + elif IsDoneIterator(iter) and i = 1 then # iterators of length 1 + iter := IteratorOfSmallSemigroups(arg); + s := NextIterator(iter); fi; - - # up to equivalence - if type = types[1] then - return ( nr3NilSelfDual( size ) + nr3NilIso( size ) ) / 2; - - # up to isomorphism - elif type = types[2] then - return nr3NilIso( size ); - - # self dual semigroups - elif type = types[3] then - return nr3NilSelfDual( size ); - - # commutative semigroups - elif type = types[4] then - return nr3NilComm( size ); - - # labelled semigroups - elif type = types[5] then - return nr3NilAll( size ); - - # labelled commutative semigroups - else - return nr3NilAllComm( size ); - fi; + return s; + fi; + return fail; end); +InstallMethod(UpToIsomorphism, "for a list of non-equivalent semigroups", +[IsList], +function(list) + local out, dual, equi, S; -################## - -InstallGlobalFunction(NrSmallSemigroups, -function(arg) -local numb; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 4, SMALLSEMI_ENTAB("NrSmallSemigroups")); -#this has info level 4 as it is called every time a small semigroup -#is created - -if Length(arg)=1 and IsPosInt(arg[1]) then - numb:=[ 1, 4, 18, 126, 1160, 15973, 836021, 1843120128 ]; - if arg[1]>0 and arg[1]<=8 then - - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return numb[arg[1]]; - else - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - Error("only the semigroups of sizes from 1 to 8 are in the library"); - fi; -else - - return SMALLSEMI_RETURN(Sum(List(PositionsOfSmallSemigroups(arg), Length))); -fi; -end); + if not ForAll(list, IsSmallSemigroup) then + Error("the argument must be a list of semigroups obtained from ", + "the smallsemi library"); + fi; -################## - -InstallGlobalFunction(OneSmallSemigroup, -function(arg) -local iter; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("OneSmallSemigroup")); - -if Length(arg)=1 then - if IsEnumeratorOfSmallSemigroups(arg[1]) and not Length(arg[1])=0 then - return arg[1][1]; - elif IsIteratorOfSmallSemigroups(arg[1]) then - iter:=arg[1]; - else - iter:=IteratorOfSmallSemigroups(arg); - fi; -else - iter:=IteratorOfSmallSemigroups(arg); -fi; - -if not IsDoneIterator(iter) then - return SMALLSEMI_RETURN(NextIterator(IteratorOfSmallSemigroups(arg))); -fi; -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; -return fail; + out := []; + + for S in list do + Add(out, S); + if not IsSelfDualSemigroup(S) then + # creator for small semigroups cannot be used here as this would + # result in an object with 'IsSmallSemi' being true but not in + # the library + dual := SemigroupByMultiplicationTableNC( + TransposedMat(MultiplicationTable(S))); + equi := MappingByFunction(dual, S, x -> AsSSortedList(S)[x![1]]); + SetRespectsMultiplication(equi, false); + SetIsBijective(equi, true); + SetEquivalenceSmallSemigroup(dual, equi); + SetIdSmallSemigroup(dual, IdSmallSemigroup(S)); + Add(out, dual); + fi; + od; + return out; end); -################## - -InstallGlobalFunction(PositionsOfSmallSemigroups, -function(arg) -local stored, sizes, enum, user, i, j, positions, out, enum2, s, id; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("PositionsOfSmallSemigroups")); - -arg:=SMALLSEMI_STRIP_ARG(arg); - -if not SMALLSEMI_ARG_OK(arg) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - Error("input is incorrect."); -fi; - -arg:=SMALLSEMI_CONVERT_ARG_NC(arg); -arg:=SMALLSEMI_SORT_ARG_NC(arg); - -if not SMALLSEMI_CAN_CREATE_ENUM_NC(arg) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - Error("cannot create an enumerator or list of positions with input"); -fi; - -if IsPosInt(arg[1]) and Length(arg)=3 and arg[3]=true then #a single stored value - stored:=STORED_INFO(arg[1], NAME_FUNC(arg[2])); - if not stored=fail then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return [stored]; - fi; -fi; - -if Length(arg)=1 and IsPosInt(arg[1]) then #all semigroups not of order 8 - return SMALLSEMI_RETURN([[1..NrSmallSemigroups(arg[1])]]); -elif IsOddInt(Length(arg)) and (IsPosInt(arg[1]) or - IsEnumeratorOfSmallSemigroups(arg[1]) or IsIteratorOfSmallSemigroups(arg[1]) - or (IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt))) then - #for a list of functions and their values - - #find sizes of semigroups - if IsPosInt(arg[1]) then - sizes:=[arg[1]]; - elif IsEnumeratorOfSmallSemigroups(arg[1]) then - sizes:=SizesOfSmallSemisInEnum(arg[1]); - elif IsIteratorOfSmallSemigroups(arg[1]) then - sizes:=SizesOfSmallSemisInIter(arg[1]); - elif IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt) then - sizes:=arg[1]; - fi; - - enum:=[arg[1]]; - user:=[]; - - if IsIteratorOfSmallSemigroups(arg[1]) then - arg:=Concatenation([SizesOfSmallSemisInIter(arg[1])], arg{[2..Length(arg)]}, - FuncsOfSmallSemisInIter(arg[1])); - arg:=SMALLSEMI_SORT_ARG_NC(SMALLSEMI_CONVERT_ARG_NC(arg)); - fi; - - #split input into precomputed and user - for i in [2,4..Length(arg)-1] do - if NAME_FUNC(arg[i]) in SMALLSEMI_ALWAYS_FALSE and arg[i+1] then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return []; - elif ForAll(sizes, j-> NAME_FUNC(arg[i]) in - PrecomputedSmallSemisInfo[j]) then - #precomputed function - enum:=Concatenation(enum, [arg[i], arg[i+1]]); - else #user function - user:=Concatenation(user, [arg[i], arg[i+1]]); - fi; - od; - - #initialize positions - if IsEnumeratorOfSmallSemigroups(arg[1]) then - positions:=List(PositionsOfSmallSemisInEnum(arg[1]), ShallowCopy); - elif ForAny([3,5..Length(enum)], i-> enum[i]=true) then - i:=First([3,5..Length(enum)], i-> enum[i]=true); - positions:=List(sizes, j-> ShallowCopy(STORED_INFO(j, - NAME_FUNC(enum[i-1])))); - else - positions:=List(sizes, i-> [1..NrSmallSemigroups(i)]); - fi; - - #elif Maximum(sizes)<8 or GAPInfo.BytesPerVariable=8 then JDM - # positions:=List(sizes, i-> [1..NrSmallSemigroups(i)]); - #else #length enum > 1 and one argument is true - # i:=First([3,5..Length(enum)], i-> enum[i]=true); - # positions:=List(sizes, j-> ShallowCopy(STORED_INFO(j, - # NAME_FUNC(enum[i-1])))); - #fi; - - # find what function values are stored already - for j in [1..Length(sizes)] do - - if Length(enum)>1 then #not just arg[1] - - i:=0; - repeat - i:=i+2; - stored:=STORED_INFO(sizes[j], NAME_FUNC(enum[i])); - if not stored=fail then - if enum[i+1]=true then - IntersectSet(positions[j], stored); - elif enum[i+1]=false then - SubtractSet(positions[j], stored); - fi; - fi; - until i=Length(enum)-1 or positions[j]=[]; - fi; - - # compute the values of any remaining functions - if not user=[] and not positions[j]=[] then - i:=-1; - - repeat - enum2:=EnumeratorOfSmallSemigroupsByIds(sizes[j], positions[j]); - i:=i+2; - out:=[]; - #Info(InfoSmallsemi, 4, "testing for ", NAME_FUNC(arg[i])); - for s in [1..Length(enum2)] do - if InfoLevel(InfoSmallsemiEnums)=4 then - Print("#I at ", s, " of ", Length(enum2), "\r"); - fi; - s:=enum2[s]; - if user[i](s)=user[i+1] then - Add(out, IdSmallSemigroup(s)[2]); #JDM was AddSet, ok? - fi; - od; - IntersectSet(positions[j], out); - until i=Length(user)-1 or positions[j]=[]; - fi; - od; -fi; - -if InfoLevel(InfoSmallsemiEnums)=4 then - Print("\n"); -fi; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; -return positions; -end); +InstallMethod(UpToIsomorphism, "for a small semigroup", [IsSmallSemigroup], +S -> UpToIsomorphism([S])); -################## - -InstallGlobalFunction(PositionsOfSmallSemisInEnum, enum-> enum!.pos); - -################### - -BindGlobal( "SMALLSEMI_RS", RandomSource(IsMersenneTwister)); - -################## - -InstallGlobalFunction(RandomSmallSemigroup, -function(arg) -local iter, i, j, s, t, enum; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("RandomSmallSemigroup")); - -arg:=SMALLSEMI_STRIP_ARG(arg); - -if Length(arg)=1 and IsPosInt(arg[1]) then - i:=Random(SMALLSEMI_RS, 1, NrSmallSemigroups(arg[1])); - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return SmallSemigroupNC(arg[1], i); -elif SMALLSEMI_CAN_CREATE_ENUM_NC(arg) then - enum:=EnumeratorOfSmallSemigroups(arg); - if not IsEmpty(enum) then - i:=Random([1..Length(enum)]); - return enum[i]; - fi; - return fail; -else - iter:=IteratorOfSmallSemigroups(arg); - i:=0; - j:=Random(SMALLSEMI_RS, 1, 500); - t:=Runtime(); - - if not IsDoneIterator(iter) then #in case of the empty iterator - repeat - i:=i+1; - s:=NextIterator(iter); - until IsDoneIterator(iter) or Runtime()-t>j; - - if IsDoneIterator(iter) and i>1 then - iter:=IteratorOfSmallSemigroups(arg); - for j in [1..RandomList([1..i-1])] do - s:=NextIterator(iter); - od; - elif IsDoneIterator(iter) and i=1 then #iterators of length 1 - iter:=IteratorOfSmallSemigroups(arg); - s:=NextIterator(iter); - fi; - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return s; - fi; -fi; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; -return fail; +######################################################################## +# Internal Functions +######################################################################## +InstallGlobalFunction(SHALLOWCOPYITERATORSMALLSEMI, +function(it) + return rec(at := 0, + max := it!.max, + enum := it!.enum, + user := it!.user, + n := it!.n); end); -################### - -InstallGlobalFunction(SizesOfSmallSemisInEnum, -enum-> enum!.sizes); +InstallGlobalFunction(SMALLSEMI_ValidateArgs, +function(arg...) + local x, i; -InstallGlobalFunction(SizesOfSmallSemisInIter, -enum-> enum!.sizes); + arg := SMALLSEMI_STRIP_ARG(arg); + if not IsOddInt(Length(arg)) then + Error("there must be an odd number arguments"); + elif not ForAny([IsPosInt, + IsCyclotomicCollection, + IsEnumeratorOfSmallSemigroups, + IsIteratorOfSmallSemigroups], f -> f(arg[1])) then + Error("the 1st argument must be a positive integer, cyclotomic collection, ", + "enumerator, or iterator of small semigroups"); + fi; -################### + if IsPosInt(arg[1]) and arg[1] > 8 then + Error("the 1st argument (a positive integer) must be at most 8, found ", + arg[1]); + elif IsCyclotomicCollection(arg[1]) then + for i in [1 .. Length(arg[1])] do + x := arg[1][i]; + if not IsPosInt(x) then + Error("the 1st argument (a list) must consist of positive integers", + ", found ", TNAM_OBJ(x), " in position ", i); + elif x = 0 or x > 8 then + Error("the 1st argument (a list) must consist of positive integers", + " in the range [1, 8), found ", x); + fi; + od; + fi; -InstallMethod( UpToIsomorphism, "for a list of non-equivalent semigroups", - [ IsList ], function(semis) - local out, s, dual, equi; - - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - - Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("UpToIsomorphism")); - - if not ForAll( semis, IsSmallSemigroup ) then - Error( "input has to be a list of semigroups obtained from ", - "the smallsemi library"); + for i in [2, 4 .. Length(arg) - 1] do + if not IsFunction(arg[i]) then + Error("the argument in even positions must be functions, found ", + TNAM_OBJ(arg[i]), " in position ", i); fi; - - out:=[]; - - for s in semis do - Add(out, s); - if not IsSelfDualSemigroup( s ) then - # creator for small semigroups cannot be used here as this would - # result in an object with 'IsSmallSemi' being true but not in - # the library - dual := SemigroupByMultiplicationTableNC( - TransposedMat(MultiplicationTable(s))); - equi := MappingByFunction(dual, s, - function(x) - return AsSSortedList(s)[x![1]]; - end); - SetRespectsMultiplication( equi, false ); - SetIsBijective( equi, true ); - SetEquivalenceSmallSemigroup( dual, equi ); - SetIdSmallSemigroup( dual, IdSmallSemigroup(s)); - Add(out, dual); - fi; - od; - - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return out; + od; + return true; # TODO remove end); -InstallMethod( UpToIsomorphism, "for a small semigroup", - [ IsSmallSemigroup ], s -> UpToIsomorphism( [s] ) ); - -#Internal Functions -################### - -InstallGlobalFunction(SHALLOWCOPYITERATORSMALLSEMI, -function(iter) - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("SHALLOWCOPYITERATORSMALLSEMI")); - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; -return rec(at := 0, max:=iter!.max, enum:=iter!.enum, user:=iter!.user, n:=iter!.n); +# only allow precomputed, sorted, and converted functions as input + +InstallGlobalFunction(SMALLSEMI_CAN_CREATE_ENUM_NC, +function(arg...) + local max; + + arg := SMALLSEMI_STRIP_ARG(arg); + + if IsPosInt(arg[1]) then + max := arg[1]; + elif IsEnumeratorOfSmallSemigroups(arg[1]) then + return true; + elif IsIteratorOfSmallSemigroups(arg[1]) then + max := Maximum(SizesOfSmallSemisInIter(arg[1])); + arg := Concatenation([SizesOfSmallSemisInIter(arg[1])], + arg{[2 .. Length(arg)]}, + FuncsOfSmallSemisInIter(arg[1])); + arg := SMALLSEMI_SORT_ARG_NC(SMALLSEMI_CONVERT_ARG_NC(arg)); + elif IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt) then + max := Maximum(arg[1]); + fi; + # precomputed must contain at least 1 true + + if Length(arg) > 1 then + return max < 8 + or ForAny([2, 4 .. Length(arg) - 1], + i -> NAME_FUNC(arg[i]) + in PrecomputedSmallSemisInfo[8] and arg[i + 1]); + # JDM should be replaced with: + # return max < 8 or GAPInfo.BytesPerVariable = 8 as we should never call this + # function unless arg[1] is a list of integers or an integer. I.e. we should + # have passed SMALLSEMI_ValidateArgs before calling this function. + fi; + return max < 8 + or (GAPInfo.BytesPerVariable = 8 and IsPosInt(arg[1])) + or (GAPInfo.BytesPerVariable = 8 and ForAll(arg[1], IsPosInt)); end); -################### - -InstallGlobalFunction(SMALLSEMI_ARG_OK, -function(arg) - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("SMALLSEMI_ARG_OK")); - -arg:=SMALLSEMI_STRIP_ARG(arg); +InstallGlobalFunction(SMALLSEMI_CONVERT_ARG_NC, +function(arg...) + local out, pos1, i; -if not IsOddInt(Length(arg)) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return false; - #Error("there must be an odd number arguments"); -fi; + arg := SMALLSEMI_STRIP_ARG(arg); -if not (IsPosInt(arg[1]) or IsEnumeratorOfSmallSemigroups(arg[1]) or - (IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt)) or - IsIteratorOfSmallSemigroups(arg[1])) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return false; - #Error("the first argument must be a pos. int., list of pos. ints., enumerator of small semigps, or - #an iterator of small semigroups"); -fi; + out := [arg[1]]; -if IsPosInt(arg[1]) and arg[1]>8 then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return false; -elif IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt) and - not ForAll(arg[1], x-> x>0 and x<9) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return false; -fi; - -if not ForAll([2,4..Length(arg)-1], i-> IsFunction(arg[i])) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return false; -fi; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - -return true; - -end); - -################### -#only allow precomputed, sorted, and converted functions as input - -InstallGlobalFunction(SMALLSEMI_CAN_CREATE_ENUM_NC, -function(arg) -local max; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("SMALLSEMI_CAN_CREATE_ENUM_NC")); - -arg:=SMALLSEMI_STRIP_ARG(arg); - -if IsPosInt(arg[1]) then - max:=arg[1]; -elif IsEnumeratorOfSmallSemigroups(arg[1]) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return true; -elif IsIteratorOfSmallSemigroups(arg[1]) then - max:=Maximum(SizesOfSmallSemisInIter(arg[1])); - arg:=Concatenation([SizesOfSmallSemisInIter(arg[1])], arg{[2..Length(arg)]}, - FuncsOfSmallSemisInIter(arg[1])); - arg:=SMALLSEMI_SORT_ARG_NC(SMALLSEMI_CONVERT_ARG_NC(arg)); -elif IsCyclotomicCollection(arg[1]) and ForAll(arg[1], IsPosInt) then - max:=Maximum(arg[1]); -fi; - -#precomputed must contain at least 1 true - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - -if Length(arg)>1 then - #return max < 8 or GAPInfo.BytesPerVariable=8 or ForAny([2,4..Length(arg)-1], - # i-> NAME_FUNC(arg[i]) in - # PrecomputedSmallSemisInfo[8] and arg[i+1]); - return max < 8 or ForAny([2,4..Length(arg)-1], - i-> NAME_FUNC(arg[i]) in - PrecomputedSmallSemisInfo[8] and arg[i+1]); -else - return max < 8 or (GAPInfo.BytesPerVariable=8 and IsPosInt(arg[1])) or (GAPInfo.BytesPerVariable=8 and ForAll(arg[1], IsPosInt)); - #JDM should be replaced with: - # return max < 8 or GAPInfo.BytesPerVariable=8 as we should never call this - # function unless arg[1] is a list of integers or an integer. I.e. we should - # have passed SMALLSEMI_ARG_OK before calling this function. -fi; -end); - -################### - -InstallGlobalFunction(SMALLSEMI_CONVERT_ARG_NC, -function(arg) -local out, i, j, pos1, pos2; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("SMALLSEMI_CONVERT_ARG_NC")); - -arg:=SMALLSEMI_STRIP_ARG(arg); - -out:=[arg[1]]; - -for i in [2,4..Length(arg)-1] do - - pos1:=PositionProperty(SMALLSEMI_EQUIV, x-> [arg[i], arg[i+1]]=x[1]); - - if not pos1=fail then - out:=Concatenation(out, SMALLSEMI_EQUIV[pos1][2]); - elif not (arg[i] in SMALLSEMI_ALWAYS_FALSE and not arg[i+1]) then - out:=Concatenation(out, [arg[i], arg[i+1]]); - fi; -od; -# pos2:=PositionProperty(SMALLSEMI_CONVERSE, x-> NAME_FUNC(arg[i])=x[1]); - -# if not pos2=fail then -# if arg[i+1] then -# out:=Concatenation(out, SMALLSEMI_CONVERSE[pos2][2]); -# else -# out:=Concatenation(out, SMALLSEMI_CONVERSE[pos2][2]); -# for j in [3, 5..Length(out)] do -# if out[j] then -# out[j]:=false; -# else -# out[j]:=true; -# fi; -# od; -# -# fi; -# fi; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; -return out; + for i in [2, 4 .. Length(arg) - 1] do + pos1 := PositionProperty(SMALLSEMI_EQUIV, x -> [arg[i], arg[i + 1]] = x[1]); + if pos1 <> fail then + out := Concatenation(out, SMALLSEMI_EQUIV[pos1][2]); + elif not (arg[i] in SMALLSEMI_ALWAYS_FALSE and not arg[i + 1]) then + out := Concatenation(out, [arg[i], arg[i + 1]]); + fi; + od; + return out; end); -################ - -InstallGlobalFunction(SMALLSEMI_CREATE_ENUM, +InstallGlobalFunction(SMALLSEMI_CREATE_ENUM, function(source, position, names) -local fam, enum, i, j, enums, tot, positions, lens, sizes; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; - -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("SMALLSEMI_CREATE_ENUM")); - -if ForAll(position, x-> x=[]) then - return SMALLSEMI_RETURN(EmptyEnumeratorOfSmallSemigroups()); -fi; - -if IsPosInt(source) then - sizes:=[source]; -elif IsEnumeratorOfSmallSemigroups(source) then - sizes:=SizesOfSmallSemisInEnum(source); - names:=Concatenation(FuncsOfSmallSemisInEnum(source), names); -elif IsIteratorOfSmallSemigroups(source) then - sizes:=SizesOfSmallSemisInIter(source); - names:=Concatenation(FuncsOfSmallSemisInIter(source), names); -elif IsCyclotomicCollection(source) and ForAll(source, IsPosInt) then - sizes:=source; -fi; - -# some inherited sizes may now not occur -j:=[]; - -for i in [1..Length(sizes)] do - if not position[i]=[] then - AddSet(j, i); - fi; -od; - -sizes:=sizes{j}; -position:=position{j}; - -if Length(sizes)=1 then #one size - fam:=CollectionsFamily(SmallSemigroupEltFamily); - - enum:=EnumeratorByFunctions(Domain(fam, []), rec( - - ElementNumber:=function(enum, pos) - local s; - s:=SmallSemigroupNC(sizes[1], position[1][pos]); - for i in [1,3..Length(names)-1] do - if IsOperation(names[i]) then #JDM ok? - Setter(names[i])(s, names[i+1]); - fi; - od; - return s; - end, - - NumberElement:=function(enum, elm) - return PositionSorted(position[1], IdSmallSemigroup(elm)[2]); - end, - - Length:=enum -> Length(position[1]), - - PrintObj:=function(enum) - Print( ""); - #JDM is this optimal? - return; - end, - - pos:=position, sizes:=sizes, funcs:=names, names:= List(names, - function(x) if IsFunction(x) then return NAME_FUNC(x); else return x; - fi; end))); - - SetIsEnumeratorOfSmallSemigroups(enum, true); - #SetPositionsOfSmallSemisInEnum(enum, position); - #SetSizesOfSmallSemisInEnum(enum, sizes); - SetIsFinite(enum, true); - #SetFuncsOfSmallSemisInEnum(enum, names); - #SetNamesFuncsSmallSemisInEnum(enum, List(names, - #function(x) - #if IsFunction(x) then return NAME_FUNC(x); - # else return x; fi; end)); - - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return enum; - -else #range of sizes - - enums:=[]; - for i in [1..Length(sizes)] do - enum:=SMALLSEMI_CREATE_ENUM(sizes[i], [position[i]], names); - Add(enums, enum); - od; - - if ForAll(enums, x-> Length(x)=0) then - return SMALLSEMI_RETURN(EmptyEnumeratorOfSmallSemigroups()); - fi; - - tot:=0; - lens:=[0]; - for i in enums do - tot:=tot+Length(i); - Add(lens, tot); - od; - - enum:=First(enums, x-> not Length(x)=0); - fam:=CollectionsFamily(FamilyObj(enum[1])); - - enum:=EnumeratorByFunctions(Domain(fam, []), rec( - ElementNumber:=function(enum, pos) - local i; - i:=PositionProperty(lens, x-> pos<=x)-1; - - return enums[i][pos-lens[i]]; - end, - - NumberElement:=function(enum, elm) - local id, i; - - id:=IdSmallSemigroup(elm); - i:=Position(sizes, id[2]); - - return Position(enums[i], elm)+tot[i-1]; - end, - - Length:=enum -> tot, - - PrintObj:=function(enum) - Print( ""); - #JDM is this optimal? - return; - end, - - pos:=List(enums, x->PositionsOfSmallSemisInEnum(x)[1]), - sizes:=sizes, funcs:=names, names:=List(names, function(x) - if IsFunction(x) then return NAME_FUNC(x); else return x; fi; end))); - - SetIsEnumeratorOfSmallSemigroups(enum, true); - #SetPositionsOfSmallSemisInEnum(enum, List(enums, - # x->PositionsOfSmallSemisInEnum(x)[1])); - #SetFuncsOfSmallSemisInEnum(enum, names); - #SetNamesFuncsSmallSemisInEnum(enum, List(names, - #function(x) - #if IsFunction(x) then return NAME_FUNC(x); - # else return x; fi; end)); - #SetSizesOfSmallSemisInEnum(enum, sizes); - SetIsFinite(enum, true); - - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return enum; -fi; + local sizes, j, fam, record, enum, enums, tot, lens, i; -end); + if ForAll(position, IsEmpty) then + return EmptyEnumeratorOfSmallSemigroups(); + fi; -################### + if IsPosInt(source) then + sizes := [source]; + elif IsEnumeratorOfSmallSemigroups(source) then + sizes := SizesOfSmallSemisInEnum(source); + names := Concatenation(FuncsOfSmallSemisInEnum(source), names); + elif IsIteratorOfSmallSemigroups(source) then + sizes := SizesOfSmallSemisInIter(source); + names := Concatenation(FuncsOfSmallSemisInIter(source), names); + elif IsCyclotomicCollection(source) and ForAll(source, IsPosInt) then + sizes := source; + fi; -InstallGlobalFunction(SMALLSEMI_ENTAB, -function(str) -local sp; + # some inherited sizes may now not occur + j := []; -sp:=""; + for i in [1 .. Length(sizes)] do + if not IsEmpty(position[i]) then + AddSet(j, i); + fi; + od; -if SMALLSEMI_TAB_LEVEL>0 then - sp:=" "; -fi; + sizes := sizes{j}; + position := position{j}; -return Concatenation(Concatenation(List([1..SMALLSEMI_TAB_LEVEL], x-> ">")), sp, str); -end); + if Length(sizes) = 1 then # one size + fam := CollectionsFamily(SmallSemigroupEltFamily); -################### + record := rec(); + record.ElementNumber := function(_, pos) + local s; + s := SmallSemigroupNC(sizes[1], position[1][pos]); + for i in [1, 3 .. Length(names) - 1] do + if IsOperation(names[i]) then # JDM ok? + Setter(names[i])(s, names[i + 1]); + fi; + od; + return s; + end; -InstallGlobalFunction(SMALLSEMI_SORT_ARG_NC, -function(arg) -local input; + record.NumberElement := + {enum, elm} -> PositionSorted(position[1], IdSmallSemigroup(elm)[2]); + record.Length := enum -> Length(position[1]); -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; + record.PrintObj := function(enum) + Print(""); + end; -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("SMALLSEMI_SORT_ARG_NC")); + record.pos := position; + record.sizes := sizes; + record.funcs := names; + record.names := List(names, SMALLSEMI_FuncNameOrString); -arg:=SMALLSEMI_STRIP_ARG(arg); + enum := EnumeratorByFunctions(Domain(fam, []), record); -input:=List([2,4..Length(arg)-1], i-> [arg[i], arg[i+1]]); -Sort(input, function(x,y) -if x[2] not IsEmpty(x)); + fam := CollectionsFamily(FamilyObj(enum[1])); + + record := rec(); + record.ElementNumber := function(_, pos) + local i; + i := PositionProperty(lens, x -> pos <= x) - 1; + return enums[i][pos - lens[i]]; + end; + + record.NumberElement := function(_, elm) + local id, i; + id := IdSmallSemigroup(elm); + i := Position(enum!.sizes, id[2]); + return Position(enums[i], elm) + tot[i - 1]; + end; + + record.Length := enum -> tot; + + record.PrintObj := function(enum) + Print(""); + return; + end; + + record.pos := List(enums, x -> PositionsOfSmallSemisInEnum(x)[1]); + + record.sizes := sizes; + record.funcs := names; + record.names := List(names, SMALLSEMI_FuncNameOrString); + enum := EnumeratorByFunctions(Domain(fam, []), record); + SetIsEnumeratorOfSmallSemigroups(enum, true); + SetIsFinite(enum, true); + return enum; end); -################### - -InstallGlobalFunction(SMALLSEMI_STRIP_ARG, -function(input) +InstallGlobalFunction(SMALLSEMI_SORT_ARG_NC, +function(arg...) + local input, cmp; -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL+1; + arg := SMALLSEMI_STRIP_ARG(arg); -Info(InfoSmallsemiEnums, 3, SMALLSEMI_ENTAB("SMALLSEMI_STRIP_ARG")); - -if IsList(input) and Length(input)=1 and not IsPosInt(input[1]) and - not IsEnumeratorOfSmallSemigroups(input[1]) - and not IsIteratorOfSmallSemigroups(input[1]) and not (IsCyclotomicCollection(input[1]) and - ForAll(input[1], IsPosInt)) then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - return input[1]; -fi; - -SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; - -return input; + input := List([2, 4 .. Length(arg) - 1], i -> [arg[i], arg[i + 1]]); + cmp := function(x, y) + if x[2] < y[2] then + return true; + elif x[2] = y[2] then + return NAME_FUNC(x[1]) < NAME_FUNC(y[1]); + fi; + end; + Sort(input, cmp); + return Concatenation([arg[1]], Concatenation(input)); end); +InstallGlobalFunction(SMALLSEMI_STRIP_ARG, +function(input) + if IsList(input) + and Length(input) = 1 + and not IsPosInt(input[1]) + and not IsEnumeratorOfSmallSemigroups(input[1]) + and not IsIteratorOfSmallSemigroups(input[1]) + and not (IsCyclotomicCollection(input[1]) + and ForAll(input[1], IsPosInt)) then + return input[1]; + fi; -################### - -InstallGlobalFunction(SMALLSEMI_RETURN, -function(out) -if SMALLSEMI_TAB_LEVEL>-1 then - SMALLSEMI_TAB_LEVEL:=SMALLSEMI_TAB_LEVEL-1; -fi; -return out; + return input; end); diff --git a/gap/greensstar.gd b/gap/greensstar.gd index ad2c769..8074443 100644 --- a/gap/greensstar.gd +++ b/gap/greensstar.gd @@ -1,43 +1,30 @@ ############################################################################# ## -#W greensstar.gd Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2013 Andreas Distler & James D. Mitchell +## greensstar.gd Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# ## -## -## This file contains the declaration for Green's star relations of -## semigroups -## - -############################################################################# -## -#P IsStarRelation() -#P IsRStarRelation() -#P IsLStarRelation() -#P IsJStarRelation() -#P IsHStarRelation() -#P IsDStarRelation() -## -## <#GAPDoc Label="IsStarRelation"> -## -## -## -## -## -## -## -## -## -## These functions return true if the argument is the respective -## type of relation and false otherwise. -## -## -## <#/GAPDoc> -## +# This file contains the declaration for Green's star relations of semigroups + +# <#GAPDoc Label="IsStarRelation"> +# +# +# +# +# +# +# +# +# +# These functions return true if the argument is the respective +# type of relation and false otherwise. +# +# +# <#/GAPDoc> DeclareCategory("IsStarRelation", IsBinaryRelation); DeclareCategory("IsRStarRelation", IsStarRelation); DeclareCategory("IsLStarRelation", IsStarRelation); @@ -47,63 +34,42 @@ DeclareCategory("IsDStarRelation", IsStarRelation); DeclareProperty("IsFiniteSemigroupStarRelation", IsStarRelation); -############################################################################# -## -#A RStarRelation() -#A LStarRelation() -#A JStarRelation() -#A DStarRelation() -#A HStarRelation() -## -## <#GAPDoc Label="RStarRelation"> -## -## -## -## -## -## -## -## -## The starred Green's relations (which are equivalence relations) -## are attributes of the semigroup semigroup. -## -## -## <#/GAPDoc> -## - +# <#GAPDoc Label="RStarRelation"> +# +# +# +# +# +# +# +# +# The starred Green's relations (which are equivalence relations) +# are attributes of the semigroup semigroup. +# +# +# <#/GAPDoc> DeclareAttribute("RStarRelation", IsSemigroup); DeclareAttribute("LStarRelation", IsSemigroup); DeclareAttribute("JStarRelation", IsSemigroup); DeclareAttribute("DStarRelation", IsSemigroup); DeclareAttribute("HStarRelation", IsSemigroup); -############################################################################# -## -#P IsStarClass() -#P IsRStarClass() -#P IsLStarClass() -#P IsJStarClass() -#P IsHStarClass() -#P IsDStarClass() -## -## <#GAPDoc Label="IsStarClass"> -## -## -## -## -## -## -## -## -## -## return true if the equivalence class equiv-class is -## a starred Green's class of any type, or of R, L, J, -## H, D type, respectively, or false otherwise. -## -## -## <#/GAPDoc> -## - +# <#GAPDoc Label="IsStarClass"> +# +# +# +# +# +# +# +# +# +# return true if the equivalence class equiv-class is +# a starred Green's class of any type, or of R, L, J, +# H, D type, respectively, or false otherwise. +# +# +# <#/GAPDoc> DeclareProperty("IsStarClass", IsEquivalenceClass); DeclareProperty("IsRStarClass", IsEquivalenceClass); DeclareProperty("IsLStarClass", IsEquivalenceClass); @@ -117,38 +83,28 @@ InstallTrueMethod(IsStarClass, IsJStarClass); InstallTrueMethod(IsStarClass, IsHStarClass); InstallTrueMethod(IsStarClass, IsDStarClass); - -############################################################################# -## -#A RStarClasses() -#A LStarClasses() -#A JStarClasses() -#A DStarClasses() -#A HStarClasses() -## -## <#GAPDoc Label="RStarClasses"> -## -## -## -## -## -## -## -## -## return the R, L, J, H, or D -## starred Green's classes, respectively for semigroup semigroup. -## EquivalenceClasses for a Green's relation -## lead to one of these functions. -## s := SmallSemigroup(6, 54); -## -## gap> JStarClasses(s); -## [ {s1}, {s2}, {s4}, {s5}, {s6} ] -## ]]> -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="RStarClasses"> +# +# +# +# +# +# +# +# +# return the R, L, J, H, or D starred +# Green's classes, respectively for semigroup semigroup. +# EquivalenceClasses for a Green's relation lead to one of these +# functions. +# s := SmallSemigroup(6, 54); +# +# gap> JStarClasses(s); +# [ {s1}, {s2}, {s4}, {s5}, {s6} ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("LStarPartitionByMT"); @@ -162,93 +118,69 @@ DeclareAttribute("HStarClasses", IsStarClass); DeclareAttribute("RStarClasses", IsDStarClass); DeclareAttribute("LStarClasses", IsDStarClass); -############################################################################# -## -#A RStarClass() -#A LStarClass() -#A DStarClass() -#A JStarClass() -## -## <#GAPDoc Label="RStarClassAttribute"> -## -## -## -## -## -## -## -## are attributes reflecting the natural ordering over the various starred -## Green's classes. They return the respective class in which the given -## class C is contained, where C must be a class from a -## strictly finer relation. -## s := SmallSemigroup(7, 280142); -## -## gap> elm := AsList(s)[5];; -## gap> hclass := HStarClass(s, elm); -## {s5} -## gap> AsList(LStarClass(hclass)); -## [ s5 ] -## gap> AsList(RStarClass(hclass)); -## [ s2, s5 ] -## gap> AsList(DStarClass(hclass)); -## [ s2, s3, s4, s5 ] -## ]]> -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="RStarClassAttribute"> +# +# +# +# +# +# +# +# are attributes reflecting the natural ordering over the various starred +# Green's classes. They return the respective class in which the given +# class C is contained, where C must be a class from a +# strictly finer relation. +# s := SmallSemigroup(7, 280142); +# +# gap> elm := AsList(s)[5];; +# gap> hclass := HStarClass(s, elm); +# {s5} +# gap> AsList(LStarClass(hclass)); +# [ s5 ] +# gap> AsList(RStarClass(hclass)); +# [ s2, s5 ] +# gap> AsList(DStarClass(hclass)); +# [ s2, s3, s4, s5 ] +# ]]> +# +# +# <#/GAPDoc> DeclareAttribute("RStarClass", IsStarClass); DeclareAttribute("LStarClass", IsStarClass); DeclareAttribute("DStarClass", IsStarClass); DeclareAttribute("JStarClass", IsStarClass); -############################################################################# -## -#O RStarClass(, ) -#O LStarClass(, ) -#O DStarClass(, ) -#O JStarClass(, ) -#O HStarClass(, ) -## -## <#GAPDoc Label="RStarClassOperation"> -## -## -## -## -## -## -## -## -## Creates the X*-class of the element a -## in the semigroup S where X is one of -## L, R, D, J, or H. -## s := SmallSemigroup(7, 280142); -## -## gap> elm := AsList(s)[5];; -## gap> jclass := JStarClass(s, elm); -## {s5} -## gap> AsList(jclass); -## [ s2, s3, s4, s5 ] -## ]]> -## -## -## <#/GAPDoc> -## - +# <#GAPDoc Label="RStarClassOperation"> +# +# +# +# +# +# +# +# +# Creates the X*-class of the element a +# in the semigroup S where X is one of +# L, R, D, J, or H. +# s := SmallSemigroup(7, 280142); +# +# gap> elm := AsList(s)[5];; +# gap> jclass := JStarClass(s, elm); +# {s5} +# gap> AsList(jclass); +# [ s2, s3, s4, s5 ] +# ]]> +# +# +# <#/GAPDoc> DeclareOperation("HStarClass", [IsSemigroup, IsObject]); DeclareOperation("RStarClass", [IsSemigroup, IsObject]); DeclareOperation("LStarClass", [IsSemigroup, IsObject]); DeclareOperation("DStarClass", [IsSemigroup, IsObject]); DeclareOperation("JStarClass", [IsSemigroup, IsObject]); -############################################################################# -## -## misc -## - DeclareAttribute("InternalRepStarRelation", IsStarRelation); DeclareAttribute("CanonicalStarClass", IsStarClass); - diff --git a/gap/greensstar.gi b/gap/greensstar.gi index 4a16d9f..b05ff69 100644 --- a/gap/greensstar.gi +++ b/gap/greensstar.gi @@ -1,119 +1,100 @@ ############################################################################# ## -#W greensstar.gi Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2013 Andreas Distler & James D. Mitchell +## greensstar.gi Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# ## -## -## This file contains the implementations for starred Green's relations of -## semigroups -# - -####################### -####################### -## -#M RStarRelation() -#M LStarRelation() -#M HStarRelation() -#M DStarRelation() -#M JStarRelation() -## -## returns the appropriate equivalence relation which is stored as an attribute. -## The relation knows nothing about itself except its source, range, and what -## type of congruence it is. +# This file contains the implementations for starred Green's relations of +# semigroups. +# Returns the appropriate equivalence relation which is stored as an attribute. +# The relation knows nothing about itself except its source, range, and what +# type of congruence it is. InstallMethod(RStarRelation, "for a small semigroup", [IsSmallSemigroup], function(X) - local fam, rel, sc; - - fam := GeneralMappingsFamily( ElementsFamily(FamilyObj(X)), - ElementsFamily(FamilyObj(X)) ); - - # Create the default type for the elements. - rel := Objectify(NewType(fam, - IsEquivalenceRelation and IsEquivalenceRelationDefaultRep - and IsRStarRelation), rec()); - - SetSource(rel, X); - SetRange(rel, X); - # AD The following causes weird viewing of the relation on the command line - SetIsLeftSemigroupCongruence(rel,true); - if HasIsFinite(X) and IsFinite(X) then - SetIsFiniteSemigroupStarRelation(rel, true); - fi; + local fam, rel; + + fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)), + ElementsFamily(FamilyObj(X))); + + # Create the default type for the elements. + rel := Objectify(NewType(fam, IsEquivalenceRelation + and IsEquivalenceRelationDefaultRep + and IsRStarRelation), rec()); + SetSource(rel, X); + SetRange(rel, X); + # AD The following causes weird viewing of the relation on the command line + SetIsLeftSemigroupCongruence(rel, true); + if HasIsFinite(X) and IsFinite(X) then + SetIsFiniteSemigroupStarRelation(rel, true); + fi; -# AD rel is objectified using IsRStarRelation, so other Green's relations -# should not be set to the same object; classes might be set at the point -# where they are actually computed, i.e. RStarClasses -# -# if HasIsCommutative(X) and IsCommutative(X) then -# SetLStarRelation(X, rel); -# SetDStarRelation(X, rel); -# SetHStarRelation(X, rel); -# fi; + # AD rel is objectified using IsRStarRelation, so other Green's relations + # should not be set to the same object; classes might be set at the point + # where they are actually computed, i.e. RStarClasses - return rel; + return rel; end); InstallMethod(LStarRelation, "for a small semigroup", [IsSmallSemigroup], function(X) - local fam, rel; - - fam := GeneralMappingsFamily( ElementsFamily(FamilyObj(X)), - ElementsFamily(FamilyObj(X)) ); - - # Create the default type for the elements. - rel := Objectify(NewType(fam, - IsEquivalenceRelation and IsEquivalenceRelationDefaultRep - and IsLStarRelation), rec()); - - SetSource(rel, X); - SetRange(rel, X); - # AD The following causes weird viewing of the relation on the command line - SetIsRightSemigroupCongruence(rel,true); - if HasIsFinite(X) and IsFinite(X) then - SetIsFiniteSemigroupStarRelation(rel, true); - fi; + local fam, rel; + + fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)), + ElementsFamily(FamilyObj(X))); + + # Create the default type for the elements. + rel := Objectify(NewType(fam, IsEquivalenceRelation + and IsEquivalenceRelationDefaultRep + and IsLStarRelation), rec()); + + SetSource(rel, X); + SetRange(rel, X); + # AD The following causes weird viewing of the relation on the command line + SetIsRightSemigroupCongruence(rel, true); + if HasIsFinite(X) and IsFinite(X) then + SetIsFiniteSemigroupStarRelation(rel, true); + fi; - return rel; + return rel; end); InstallMethod(JStarRelation, "for a small semigroup", [IsSmallSemigroup], function(X) - local fam, rel; + local fam, rel; - fam := GeneralMappingsFamily( ElementsFamily(FamilyObj(X)), - ElementsFamily(FamilyObj(X)) ); + fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)), + ElementsFamily(FamilyObj(X))); - # Create the default type for the elements. - rel := Objectify(NewType(fam, - IsEquivalenceRelation and IsEquivalenceRelationDefaultRep - and IsJStarRelation), rec()); + # Create the default type for the elements. + rel := Objectify(NewType(fam, IsEquivalenceRelation + and IsEquivalenceRelationDefaultRep + and IsJStarRelation), rec()); - SetSource(rel, X); - SetRange(rel, X); - if HasIsFinite(X) and IsFinite(X) then - SetIsFiniteSemigroupStarRelation(rel, true); - fi; + SetSource(rel, X); + SetRange(rel, X); + if HasIsFinite(X) and IsFinite(X) then + SetIsFiniteSemigroupStarRelation(rel, true); + fi; - return rel; + return rel; end); InstallMethod(DStarRelation, "for a small semigroup", [IsSmallSemigroup], function(X) local fam, rel; - fam := GeneralMappingsFamily( ElementsFamily(FamilyObj(X)), - ElementsFamily(FamilyObj(X)) ); + fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)), + ElementsFamily(FamilyObj(X))); # Create the default type for the elements. - rel := Objectify(NewType(fam, - IsEquivalenceRelation and IsEquivalenceRelationDefaultRep - and IsDStarRelation), rec()); + rel := Objectify(NewType(fam, IsEquivalenceRelation + and IsEquivalenceRelationDefaultRep + and IsDStarRelation), rec()); SetSource(rel, X); SetRange(rel, X); @@ -127,278 +108,191 @@ end); InstallMethod(HStarRelation, "for a small semigroup", [IsSmallSemigroup], function(X) - local fam, rel; + local fam, rel; - fam := GeneralMappingsFamily( ElementsFamily(FamilyObj(X)), - ElementsFamily(FamilyObj(X)) ); + fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)), + ElementsFamily(FamilyObj(X))); - # Create the default type for the elements. - rel := Objectify(NewType(fam, - IsEquivalenceRelation and IsEquivalenceRelationDefaultRep - and IsHStarRelation), rec()); + # Create the default type for the elements. + rel := Objectify(NewType(fam, IsEquivalenceRelation + and IsEquivalenceRelationDefaultRep + and IsHStarRelation), rec()); - SetSource(rel, X); - SetRange(rel, X); + SetSource(rel, X); + SetRange(rel, X); - if HasIsFinite(X) and IsFinite(X) then - SetIsFiniteSemigroupStarRelation(rel, true); - fi; + if HasIsFinite(X) and IsFinite(X) then + SetIsFiniteSemigroupStarRelation(rel, true); + fi; - return rel; + return rel; end); - ### AD The following methods should probably be installed for ViewString -# AD This is overwritten by the method for LeftSemigroupCongruence -InstallMethod( ViewObj, "for RStarRelation", [IsRStarRelation], - function( obj ) - Print( "< R*-relation on "); - ViewObj(Source(obj)); - Print(" >"); -end ); - -# AD This is overwritten by the method for RightSemigroupCongruence -InstallMethod( ViewObj, "for LStarRelation", [IsLStarRelation], - function( obj ) - Print( "< L*-relation on "); - ViewObj(Source(obj)); - Print(" >"); -end ); - -InstallMethod( ViewObj, "for JStarRelation", [IsJStarRelation], - function( obj ) - Print( "< J*-relation on "); - ViewObj(Source(obj)); - Print(" >"); -end ); - -InstallMethod( ViewObj, "for DStarRelation", [IsDStarRelation], - function( obj ) - Print( "< D*-relation on "); - ViewObj(Source(obj)); - Print(" >"); -end ); - -InstallMethod( ViewObj, "for HStarRelation", [IsHStarRelation], - function( obj ) - Print( "< H*-relation on "); - ViewObj(Source(obj)); - Print(" >"); -end ); - -InstallMethod(\=, "for starred Green's relations", IsIdenticalObj, -[IsStarRelation and IsEquivalenceRelation, -IsStarRelation and IsEquivalenceRelation], function(rel1, rel2) - if not Source(rel1) = Source(rel2) then - return false; - else - # make sure the internal representation is known - EquivalenceClasses(rel1); EquivalenceClasses(rel2); - return InternalRepStarRelation(rel1) = InternalRepStarRelation(rel2); - fi; +BindGlobal("SMALLSEMI_ViewStarRelation", +function(obj, type) + Print("<", type, "*-relation on "); + ViewObj(Source(obj)); + Print(">"); end); -############################################################################# -## -## The following operations are constructors for starred Green's class with -## a given element as a representative. The call is for semigroups -## and an element in the semigroup. This function doesn't check that -## the element is actually a member of the semigroup. -## -#O RStarClass(, ) -#O LStarClass(, ) -#O JStarClass(, ) -#O DStarClass(, ) -#O HStarClass(, ) -## +# AD This is overwritten by the method for LeftSemigroupCongruence +InstallMethod(ViewObj, "for Green's R*-relation", [IsRStarRelation], +16, # to beat IsLeftSemigroupCongruence +obj -> SMALLSEMI_ViewStarRelation(obj, "R")); -InstallMethod(RStarClass, "for a small semigroup ", IsCollsElms, -[IsSmallSemigroup, IsSmallSemigroupElt], function(s,e) - return EquivalenceClassOfElement( RStarRelation(s), e ); +# AD This is overwritten by the method for RightSemigroupCongruence +InstallMethod(ViewObj, "for Green's L*-relation", [IsLStarRelation], +16, # to beat IsRightSemigroupCongruence +obj -> SMALLSEMI_ViewStarRelation(obj, "L")); + +InstallMethod(ViewObj, "for Green's J*-relation", [IsJStarRelation], +obj -> SMALLSEMI_ViewStarRelation(obj, "J")); + +InstallMethod(ViewObj, "for Green's D*-relation", [IsDStarRelation], +obj -> SMALLSEMI_ViewStarRelation(obj, "D")); + +InstallMethod(ViewObj, "for Green's H*-relation", [IsHStarRelation], +obj -> SMALLSEMI_ViewStarRelation(obj, "H")); + +InstallMethod(\=, "for starred Green's relations", IsIdenticalObj, +[IsStarRelation and IsEquivalenceRelation, + IsStarRelation and IsEquivalenceRelation], +function(rel1, rel2) + if Source(rel1) <> Source(rel2) then + return false; + fi; + # make sure the internal representation is known + EquivalenceClasses(rel1); + EquivalenceClasses(rel2); + return InternalRepStarRelation(rel1) = InternalRepStarRelation(rel2); end); +# The following operations are constructors for starred Green's class with +# a given element as a representative. The call is for semigroups +# and an element in the semigroup. This function doesn't check that +# the element is actually a member of the semigroup. + +InstallMethod(RStarClass, "for a small semigroup ", IsCollsElms, +[IsSmallSemigroup, IsSmallSemigroupElt], +{s, e} -> EquivalenceClassOfElement(RStarRelation(s), e)); + InstallMethod(LStarClass, "for a small semigroup", IsCollsElms, -[IsSmallSemigroup, IsSmallSemigroupElt], function(s,e) - return EquivalenceClassOfElement( LStarRelation(s), e ); -end); +[IsSmallSemigroup, IsSmallSemigroupElt], +{s, e} -> EquivalenceClassOfElement(LStarRelation(s), e)); InstallMethod(HStarClass, "for a small semigroup", IsCollsElms, -[IsSmallSemigroup, IsSmallSemigroupElt], function(s,e) - return EquivalenceClassOfElement( HStarRelation(s), e ); -end); +[IsSmallSemigroup, IsSmallSemigroupElt], +{s, e} -> EquivalenceClassOfElement(HStarRelation(s), e)); InstallMethod(DStarClass, "for a small semigroup", IsCollsElms, -[IsSmallSemigroup, IsSmallSemigroupElt], function(s,e) - return EquivalenceClassOfElement( DStarRelation(s), e ); -end); +[IsSmallSemigroup, IsSmallSemigroupElt], +{s, e} -> EquivalenceClassOfElement(DStarRelation(s), e)); InstallMethod(JStarClass, "for a small semigroup", IsCollsElms, -[IsSmallSemigroup, IsSmallSemigroupElt], function(s,e) - return EquivalenceClassOfElement( JStarRelation(s), e ); -end); - +[IsSmallSemigroup, IsSmallSemigroupElt], +{s, e} -> EquivalenceClassOfElement(JStarRelation(s), e)); -################# -################# -## -#M CanonicalStarClass() -## -## methods to get any starred Green's class in its canonical form -## +# Methods to get any starred Green's class in its canonical form -InstallMethod(CanonicalStarClass, "for a H*-class", [IsHStarClass], -cl-> First(HStarClasses(ParentAttr(cl)), y-> Representative(cl) in y)); +InstallMethod(CanonicalStarClass, "for a H*-class", [IsHStarClass], +cl -> First(HStarClasses(ParentAttr(cl)), y -> Representative(cl) in y)); -InstallMethod(CanonicalStarClass, "for a R*-class", [IsRStarClass], -cl-> First(RStarClasses(ParentAttr(cl)), y-> Representative(cl) in y)); +InstallMethod(CanonicalStarClass, "for a R * - class", [IsRStarClass], +cl -> First(RStarClasses(ParentAttr(cl)), y -> Representative(cl) in y)); -InstallMethod(CanonicalStarClass, "for a L*-class", [IsLStarClass], -cl-> First(LStarClasses(ParentAttr(cl)), y-> Representative(cl) in y)); +InstallMethod(CanonicalStarClass, "for a L*-class", [IsLStarClass], +cl -> First(LStarClasses(ParentAttr(cl)), y -> Representative(cl) in y)); -InstallMethod(CanonicalStarClass, "for a D*-class", [IsDStarClass], -cl-> First(DStarClasses(ParentAttr(cl)), y-> Representative(cl) in y)); +InstallMethod(CanonicalStarClass, "for a D*-class", [IsDStarClass], +cl -> First(DStarClasses(ParentAttr(cl)), y -> Representative(cl) in y)); -InstallMethod(CanonicalStarClass, "for a J*-class", [IsJStarClass], -cl-> First(JStarClasses(ParentAttr(cl)), y-> Representative(cl) in y)); +InstallMethod(CanonicalStarClass, "for a J*-class", [IsJStarClass], +cl -> First(JStarClasses(ParentAttr(cl)), y -> Representative(cl) in y)); -################# -################# -## -#M ImagesElm(, ) -## -## method to find the images under a starred Green's relation of an -## element of a semigroup. -## +# method to find the images under a starred Green's relation of an +# element of a semigroup. InstallMethod(ImagesElm, "for a starred Green's relation", -[IsStarRelation, IsObject], 0, - function(rel, elm) - local exp, semi; - - semi:=Source(rel); - - if IsRStarRelation(rel) then - exp:=RStarClass(semi, elm); - elif IsLStarRelation(rel) then - exp:=LStarClass(semi, elm); - elif IsHStarRelation(rel) then - exp:=HStarClass(semi, elm); - elif IsDStarRelation(rel) then - exp:=DStarClass(semi, elm); - elif IsJStarRelation(rel) then - exp:=JStarClass(semi, elm); - fi; +[IsStarRelation, IsObject], +function(rel, elm) + local exp, semi; - return AsSSortedList(exp); - end); + semi := Source(rel); -################# -################# -## -#M Successors() -## -## returns ImagesElm for one element in each class of -## + if IsRStarRelation(rel) then + exp := RStarClass(semi, elm); + elif IsLStarRelation(rel) then + exp := LStarClass(semi, elm); + elif IsHStarRelation(rel) then + exp := HStarClass(semi, elm); + elif IsDStarRelation(rel) then + exp := DStarClass(semi, elm); + elif IsJStarRelation(rel) then + exp := JStarClass(semi, elm); + fi; -InstallMethod(Successors, "for a starred Green's relation", -[IsStarRelation], 0, - function( rel ) - return List(EquivalenceClasses(rel), AsSSortedList); + return AsSSortedList(exp); end); -################# -################# -## -#M AsSSortedList() -## -## returns the elements of the Star class -## +# Returns ImagesElm for one element in each class of -InstallMethod(AsSSortedList, "for a starred Green's class", [IsStarClass], - x-> AsSSortedList(CanonicalStarClass(x))); +InstallMethod(Successors, "for a starred Green's relation", +[IsStarRelation], +rel -> List(EquivalenceClasses(rel), AsSSortedList)); -################# -################# -## -#M \= (,) -## +# Returns the elements of the *-class + +InstallMethod(AsSSortedList, "for a starred Green's class", [IsStarClass], +x -> AsSSortedList(CanonicalStarClass(x))); -InstallMethod(\=, "for starred Green's classes", +# Equality of *-classes +InstallMethod(\=, "for starred Green's classes", [IsStarClass, IsStarClass], -function(class1,class2) - if not ParentAttr(class1)=ParentAttr(class2) then - return false; - else - return Representative(class1) in class2; - fi; +function(class1, class2) + if ParentAttr(class1) <> ParentAttr(class2) then + return false; + fi; + return Representative(class1) in class2; end); -################# -################# -## -#M Size() -## -## size of a starred Green's class -## - +# Size of a starred Green's class InstallMethod(Size, "for a starred Green's class", [IsStarClass], -function(class) - return Size(Elements(class)); -end); +class -> Size(Elements(class))); -################# -################# -## -#M in -## -## membership test for a starred Green's class -## - -InstallMethod(\in, "membership test of starred Green's class", -[IsObject, IsStarClass], 0, +# Membership test for a starred Green's class +InstallMethod(\in, "membership test of starred Green's class", +[IsObject, IsStarClass], function(elm, class) - if elm=Representative(class) then + if elm = Representative(class) then return true; fi; return elm in Elements(class); end); -################# -################# -## -#M EquivalenceRelationPartition() -## -## - InstallMethod(EquivalenceRelationPartition, "for a starred Green's equivalence", [IsEquivalenceRelation and IsStarRelation], -function(rel) - return Filtered(Successors(rel), x-> not Length(x)=1); -end); +rel -> Filtered(Successors(rel), x -> not Length(x) <> 1)); -################# -################# -## -#M EquivalenceClassOfElementNC(, ) -## -## new methods required so that what is returned by this function -## is the appropriate type of starred Green's class +# New methods required so that what is returned by this function +# is the appropriate type of starred Green's class. -InstallOtherMethod(EquivalenceClassOfElementNC, -"for a starred Green's relation", true, - [IsEquivalenceRelation and IsStarRelation, IsObject], 0, +InstallOtherMethod(EquivalenceClassOfElementNC, +"for a starred Green's relation", +[IsEquivalenceRelation and IsStarRelation, IsObject], function(rel, rep) - local new; - new:= Objectify(NewType(CollectionsFamily(FamilyObj(rep)), - IsEquivalenceClass and IsEquivalenceClassDefaultRep), rec()); + new := Objectify(NewType(CollectionsFamily(FamilyObj(rep)), + IsEquivalenceClass and IsEquivalenceClassDefaultRep), + rec()); SetEquivalenceClassRelation(new, rel); SetRepresentative(new, rep); SetParent(new, UnderlyingDomainOfBinaryRelation(rel)); SetIsStarClass(new, true); + if IsRStarRelation(rel) then SetIsRStarClass(new, true); elif IsLStarRelation(rel) then @@ -414,405 +308,340 @@ function(rel, rep) return new; end); -################# -################# -## -#M EquivalenceClasses() -## - -InstallMethod(EquivalenceClasses, "for a starred Green's R-relation", -[IsEquivalenceRelation and IsRStarRelation], x-> RStarClasses(Source(x))); +InstallMethod(EquivalenceClasses, "for a starred Green's R - relation", +[IsEquivalenceRelation and IsRStarRelation], x -> RStarClasses(Source(x))); InstallMethod(EquivalenceClasses, "for a starred Green's L-relation", -[IsEquivalenceRelation and IsLStarRelation], x-> LStarClasses(Source(x))); +[IsEquivalenceRelation and IsLStarRelation], x -> LStarClasses(Source(x))); -InstallMethod(EquivalenceClasses, "for a starred Green's H-relation", -[IsEquivalenceRelation and IsHStarRelation], x-> HStarClasses(Source(x))); +InstallMethod(EquivalenceClasses, "for a starred Green's H - relation", +[IsEquivalenceRelation and IsHStarRelation], x -> HStarClasses(Source(x))); -InstallMethod(EquivalenceClasses, "for a starred Green's D-relation", -[IsEquivalenceRelation and IsDStarRelation], x-> DStarClasses(Source(x))); +InstallMethod(EquivalenceClasses, "for a starred Green's D - relation", +[IsEquivalenceRelation and IsDStarRelation], x -> DStarClasses(Source(x))); InstallMethod(EquivalenceClasses, "for a starred Green's J-relation", -[IsEquivalenceRelation and IsJStarRelation], x-> JStarClasses(Source(x))); +[IsEquivalenceRelation and IsJStarRelation], x -> JStarClasses(Source(x))); - -################# -################# -## -#M RStarClass() -#M LStarClass() -#M DStarClass() -#M JStarClass() -## -## return the XStarClass containing the smaller class -## +# Return the XStarClass containing the smaller class InstallOtherMethod(RStarClass, "for a starred Green's H-class", -[IsHStarClass], cl-> RStarClass(ParentAttr(cl), Representative(cl))); +[IsHStarClass], cl -> RStarClass(ParentAttr(cl), Representative(cl))); InstallOtherMethod(LStarClass, "for a starred Green's H-class", -[IsHStarClass], cl-> LStarClass(ParentAttr(cl), Representative(cl))); +[IsHStarClass], cl -> LStarClass(ParentAttr(cl), Representative(cl))); InstallOtherMethod(DStarClass, "for a starred Green's H-class", -[IsHStarClass], cl-> DStarClass(ParentAttr(cl), Representative(cl))); +[IsHStarClass], cl -> DStarClass(ParentAttr(cl), Representative(cl))); InstallOtherMethod(JStarClass, "for a starred Green's H-class", -[IsHStarClass], cl-> JStarClass(ParentAttr(cl), Representative(cl))); +[IsHStarClass], cl -> JStarClass(ParentAttr(cl), Representative(cl))); InstallOtherMethod(DStarClass, "for a starred Green's R-class", -[IsRStarClass], cl-> DStarClass(ParentAttr(cl), Representative(cl))); +[IsRStarClass], cl -> DStarClass(ParentAttr(cl), Representative(cl))); InstallOtherMethod(JStarClass, "for a starred Green's R-class", -[IsRStarClass], cl-> JStarClass(ParentAttr(cl), Representative(cl))); +[IsRStarClass], cl -> JStarClass(ParentAttr(cl), Representative(cl))); InstallOtherMethod(DStarClass, "for a starred Green's L-class", -[IsLStarClass], cl-> DStarClass(ParentAttr(cl), Representative(cl))); +[IsLStarClass], cl -> DStarClass(ParentAttr(cl), Representative(cl))); InstallOtherMethod(JStarClass, "for a starred Green's L-class", -[IsLStarClass], cl-> JStarClass(ParentAttr(cl), Representative(cl))); +[IsLStarClass], cl -> JStarClass(ParentAttr(cl), Representative(cl))); InstallOtherMethod(JStarClass, "for a starred Green's D-class", -[IsDStarClass], cl-> JStarClass(ParentAttr(cl), Representative(cl))); +[IsDStarClass], cl -> JStarClass(ParentAttr(cl), Representative(cl))); - -################# -################# -## -#F LStarPartitionByMT() -#M RStarClasses() -#M LStarClasses() -#M JStarClasses() -#M DStarClasses() -#M HStarClasses() -## -## find all the classes of a particular type +# Find all the classes of a particular type InstallGlobalFunction(LStarPartitionByMT, function(table) + local mt, # mutable copy of multiplication table + n, # size of + profiles, # types of rows, sorted + partition, # partition of indices into R*-classes + k, # element counter + pro, # profile of current elements row + pos; # position of current profile + + # get a mutable copy of the multiplication table + mt := MutableCopyMat(table); + n := Length(mt); + mt{[1 .. n]}[n + 1] := [1 .. n]; + + # initialise sorted list of profiles ... + profiles := EmptyPlist(n); + # ... and partition into R*-classes + partition := EmptyPlist(n); + + # loop over elements + for k in [1 .. n] do + pro := KernelOfTransformation(TransformationNC(mt[k])); + pos := PositionSorted(profiles, pro); + + # either ... + if IsBound(profiles[pos]) and profiles[pos] = pro then + # add element to part with same profile ... + Add(partition[pos], k); + else + # ... or start a new part + Add(profiles, pro, pos); + Add(partition, [k], pos); + fi; + od; - local mt, # mutable copy of multiplication table - n, # size of - profiles, # types of rows, sorted - partition, # partition of indices into R*-classes - k, # element counter - pro, # profile of current elements row - pos; # position of current profile - - ### main function body ### - - # get a mutable copy of the multiplication table - mt := MutableCopyMat(table); - n := Length(mt); - mt{[1..n]}[n+1] := [1..n]; - - # initialise sorted list of profiles ... - profiles := EmptyPlist(n); - # ... and partition into R*-classes - partition := EmptyPlist(n); - - # loop over elements - for k in [1..n] do - - # get profile of element - #pro := FLAT_KERNEL_TRANS(TransformationNC(mt[k])); - pro := KernelOfTransformation(TransformationNC(mt[k])); - pos := PositionSorted(profiles, pro); - - # either ... - if IsBound(profiles[pos]) and profiles[pos] = pro then - # add element to part with same profile ... - Add(partition[pos], k); - else - # ... or start a new part - Add(profiles, pro, pos); - Add(partition, [k], pos); - fi; - od; - - return AsSSortedList(partition); + return AsSSortedList(partition); end); InstallMethod(RStarClasses, "for a small semigroup", [IsSmallSemigroup], function(semi) + local partition, # partition of indices into R*-classes + classes, # the actual classes + part, # one part of , used as loop counter + rc; # one R*-class - local partition, # partition of indices into R*-classes - classes, # the actual classes - part, # one part of , used as loop counter - rc; # one R*-class + # get partition of index set into R*-classes ... + partition := LStarPartitionByMT(TransposedMat(MultiplicationTable(semi))); - ### main function body ### + # ... and use as internal representation + SetInternalRepStarRelation(RStarRelation(semi), partition); - # get partition of index set into R*-classes ... - partition := LStarPartitionByMT(TransposedMat(MultiplicationTable(semi))); + # create acutal classes as GAP objects + classes := EmptyPlist(Length(partition)); - # ... and use as internal representation - SetInternalRepStarRelation(RStarRelation(semi), partition); - - # create acutal classes as GAP objects - classes := EmptyPlist(Length(partition)); - - for part in partition do - rc := RStarClass(semi, Elements(semi)[part[1]]); - Add(classes, rc); - SetAsSSortedList(rc, Elements(semi){part}); - SetSize(rc, Size(part)); - SetCanonicalStarClass(rc, rc); - od; + for part in partition do + rc := RStarClass(semi, Elements(semi)[part[1]]); + Add(classes, rc); + SetAsSSortedList(rc, Elements(semi){part}); + SetSize(rc, Size(part)); + SetCanonicalStarClass(rc, rc); + od; - return classes; + return classes; end); InstallOtherMethod(RStarClasses, "for a starred Green's D-class", -[IsDStarClass], cl-> Filtered(RStarClasses(ParentAttr(cl)), - c-> Representative(c) in cl)); +[IsDStarClass], cl -> Filtered(RStarClasses(ParentAttr(cl)), + c -> Representative(c) in cl)); InstallOtherMethod(RStarClasses, "for a starred Green's J-class", -[IsJStarClass], cl-> Filtered(RStarClasses(ParentAttr(cl)), - c-> Representative(c) in cl)); +[IsJStarClass], cl -> Filtered(RStarClasses(ParentAttr(cl)), + c -> Representative(c) in cl)); InstallMethod(LStarClasses, "for a small semigroup", [IsSmallSemigroup], function(semi) + local partition, # partition of indices into L*-classes + classes, # the actual classes + part, # one part of , used as loop counter + lc; # one L*-class - local partition, # partition of indices into L*-classes - classes, # the actual classes - part, # one part of , used as loop counter - lc; # one L*-class - - ### main function body ### - - # get partition of index set into L*-classes ... - partition := LStarPartitionByMT(MultiplicationTable(semi)); + # get partition of index set into L*-classes ... + partition := LStarPartitionByMT(MultiplicationTable(semi)); - # ... and use as internal representation - SetInternalRepStarRelation(LStarRelation(semi), partition); + # ... and use as internal representation + SetInternalRepStarRelation(LStarRelation(semi), partition); - # create acutal classes as GAP objects - classes := EmptyPlist(Length(partition)); + # create acutal classes as GAP objects + classes := EmptyPlist(Length(partition)); - for part in partition do - lc := LStarClass(semi, Elements(semi)[part[1]]); - Add(classes, lc); - SetAsSSortedList(lc, Elements(semi){part}); - SetSize(lc, Size(part)); - SetCanonicalStarClass(lc, lc); - od; + for part in partition do + lc := LStarClass(semi, Elements(semi)[part[1]]); + Add(classes, lc); + SetAsSSortedList(lc, Elements(semi){part}); + SetSize(lc, Size(part)); + SetCanonicalStarClass(lc, lc); + od; - return classes; + return classes; end); InstallOtherMethod(LStarClasses, "for a starred Green's D-class", -[IsDStarClass], cl-> Filtered(LStarClasses(ParentAttr(cl)), - c-> Representative(c) in cl)); +[IsDStarClass], cl -> Filtered(LStarClasses(ParentAttr(cl)), + c -> Representative(c) in cl)); InstallOtherMethod(LStarClasses, "for a starred Green's J-class", -[IsJStarClass], cl-> Filtered(LStarClasses(ParentAttr(cl)), - c-> Representative(c) in cl)); +[IsJStarClass], cl -> Filtered(LStarClasses(ParentAttr(cl)), + c -> Representative(c) in cl)); # AD would it be better to use JoinEquivalenceRelations? InstallMethod(DStarClasses, "for a small semigroup", [IsSmallSemigroup], function(semi) - - local mt, # multiplication table of - left, # partition of indices into L*-classes - right, # partition of indices into R*-classes - lookupL, # positions of parts in containing each index - lookupR, # positions of parts in containing each index - partition, # partition of indices into D*-classes - classes, # the actual classes - part, # one part of , used as loop counter - dc; # one D*-class - - ### function body ### - - mt := MultiplicationTable(semi); - - # get R- and L-classes - LStarClasses(semi); RStarClasses(semi); - left := InternalRepStarRelation(LStarRelation(semi)); - right := InternalRepStarRelation(RStarRelation(semi)); - - lookupL := List([1..Size(mt)], k-> First(left, part-> k in part)); - lookupR := List([1..Size(mt)], k-> First(right, part-> k in part)); - - while left <> right do - left := Unique(List(right, part-> Union(List(part, k-> lookupL[k])))); - right := Unique(List(left, part-> Union(List(part, k-> lookupR[k])))); - od; - - partition := AsSSortedList(left); - - SetInternalRepStarRelation(DStarRelation(semi), partition); - classes := EmptyPlist(Length(partition)); - - for part in partition do - dc := DStarClass(semi, Elements(semi)[part[1]]); - Add(classes, dc); - SetAsSSortedList(dc, Elements(semi){part}); - SetSize(dc, Size(part)); - SetCanonicalStarClass(dc, dc); - od; - - return classes; + local mt, # multiplication table of + left, # partition of indices into L*-classes + right, # partition of indices into R*-classes + lookupL, # positions of parts in containing each index + lookupR, # positions of parts in containing each index + partition, # partition of indices into D*-classes + classes, # the actual classes + part, # one part of , used as loop counter + dc; # one D*-class + + mt := MultiplicationTable(semi); + + # get R- and L-classes + LStarClasses(semi); + RStarClasses(semi); + left := InternalRepStarRelation(LStarRelation(semi)); + right := InternalRepStarRelation(RStarRelation(semi)); + + lookupL := List([1 .. Size(mt)], k -> First(left, part -> k in part)); + lookupR := List([1 .. Size(mt)], k -> First(right, part -> k in part)); + + while left <> right do + left := Unique(List(right, part -> Union(List(part, k -> lookupL[k])))); + right := Unique(List(left, part -> Union(List(part, k -> lookupR[k])))); + od; + + partition := AsSSortedList(left); + + SetInternalRepStarRelation(DStarRelation(semi), partition); + classes := EmptyPlist(Length(partition)); + + for part in partition do + dc := DStarClass(semi, Elements(semi)[part[1]]); + Add(classes, dc); + SetAsSSortedList(dc, Elements(semi){part}); + SetSize(dc, Size(part)); + SetCanonicalStarClass(dc, dc); + od; + + return classes; end); InstallOtherMethod(DStarClasses, "for a starred Green's J-class", -[IsJStarClass], cl-> Filtered(DStarClasses(ParentAttr(cl)), - c-> Representative(c) in cl)); - +[IsJStarClass], cl -> Filtered(DStarClasses(ParentAttr(cl)), + c -> Representative(c) in cl)); InstallMethod(JStarClasses, "for a small semigroup", [IsSmallSemigroup], function(semi) - - local mt, # multiplication table of - n, # size of - jideals, # Green's J*-ideals of all elements - partition, # partition of indices into J*-classes - set, # a subset of the indices to become a part of - classes, # list of Green's J*-classes - rest, # elements not yet sorted into classes - elm, # element for building next class - part, # one part of , used as loop counter - jc, # one J*-class - - # AD the ideal computation should certainly become a user function - # AD but the necessary technicalities are unclear to me - greensStarJIdealRaw; - - greensStarJIdealRaw := function(elm) - local ideal, # the Green's J*-ideal of - new, # auxiliary variable for construction of - trans, # transposed of - dclasses, # internal representation of Green's D*-classes - - greensJIdeal; - - ### local local function body ### - - # AD this step is rather inefficient in its current form - # AD it should be replaced by a call to an attribute - greensJIdeal := function(a) - local regid; # the regular Greens J-ideal of - - # {a} \cup aS - regid := Union(mt[a], [a]); - - # {a} \cup aS \cup aS \cup SaS - regid := Union(regid, Union(List(regid, x-> trans[x]))); - - return regid; - end; - - ### local function body ### - - trans := TransposedMat(mt); - DStarClasses(semi); - dclasses := InternalRepStarRelation(DStarRelation(semi)); - dclasses := List([1..n], x-> First(dclasses, cl-> x in cl)); - - new := [elm]; - - repeat - ideal := new; - new := Union(List(ideal, greensJIdeal)); - new := Union(List(new, x-> dclasses[x])); - until new = ideal; - - return ideal; + local mt, # multiplication table of + n, # size of + jideals, # Green's J*-ideals of all elements + partition, # partition of indices into J*-classes + set, # a subset of the indices to become a part of + classes, # list of Green's J*-classes + rest, # elements not yet sorted into classes + elm, # element for building next class + part, # one part of , used as loop counter + jc, # one J*-class + # AD the ideal computation should certainly become a user function + # AD but the necessary technicalities are unclear to me + greensStarJIdealRaw; + + greensStarJIdealRaw := function(elm) + local ideal, # the Green's J*-ideal of + new, # auxiliary variable for construction of + trans, # transposed of + dclasses, # internal representation of Green's D*-classes + greensJIdeal; + + # AD this step is rather inefficient in its current form + # AD it should be replaced by a call to an attribute + greensJIdeal := function(a) + local regid; # the regular Greens J-ideal of + # {a} \cup aS + regid := Union(mt[a], [a]); + # {a} \cup aS \cup aS \cup SaS + return Union(regid, Union(List(regid, x -> trans[x]))); end; - ### main function body ### + trans := TransposedMat(mt); + DStarClasses(semi); + dclasses := InternalRepStarRelation(DStarRelation(semi)); + dclasses := List([1 .. n], x -> First(dclasses, cl -> x in cl)); - mt := MultiplicationTable(semi); - n := Size(mt); + new := [elm]; - jideals := List([1..n], i-> greensStarJIdealRaw(i)); + repeat + ideal := new; + new := Union(List(ideal, greensJIdeal)); + new := Union(List(new, x -> dclasses[x])); + until new = ideal; - partition := EmptyPlist(Size(mt)); - rest := [1..Size(mt)]; + return ideal; + end; - repeat + mt := MultiplicationTable(semi); + n := Size(mt); - # take one of the remaining elements - elm := rest[1]; + jideals := List([1 .. n], greensStarJIdealRaw); - # get remaining elements in the same class - set := Filtered(Intersection(rest, jideals[elm]), - x-> elm in jideals[x]); + partition := EmptyPlist(Size(mt)); + rest := [1 .. Size(mt)]; - # remember new class and prepare for next step - Add(partition, set); - rest := Difference(rest, set); + repeat + # take one of the remaining elements + elm := rest[1]; - until IsEmpty(rest); + # get remaining elements in the same class + set := Filtered(Intersection(rest, jideals[elm]), + x -> elm in jideals[x]); - MakeImmutable(partition); - SetIsSSortedList(partition, true); + # remember new class and prepare for next step + Add(partition, set); + rest := Difference(rest, set); + until IsEmpty(rest); - SetInternalRepStarRelation(JStarRelation(semi), partition); - classes := EmptyPlist(Length(partition)); + MakeImmutable(partition); + SetIsSSortedList(partition, true); - for part in partition do - jc := JStarClass(semi, Elements(semi)[part[1]]); - Add(classes, jc); - SetAsSSortedList(jc, Elements(semi){part}); - SetSize(jc, Size(part)); - SetCanonicalStarClass(jc, jc); - od; + SetInternalRepStarRelation(JStarRelation(semi), partition); + classes := EmptyPlist(Length(partition)); - SetJStarClasses(semi, classes); + for part in partition do + jc := JStarClass(semi, Elements(semi)[part[1]]); + Add(classes, jc); + SetAsSSortedList(jc, Elements(semi){part}); + SetSize(jc, Size(part)); + SetCanonicalStarClass(jc, jc); + od; - return classes; + SetJStarClasses(semi, classes); + + return classes; end); InstallMethod(HStarClasses, "for a small semigroup", [IsSmallSemigroup], function(semi) - - local mt, # multiplication table of - left, # partition of indices into L*-classes - lpart, # one part of - right, # partition of indices into R*-classes - rpart, # one part of - partition, # partition of indices into D*-classes - classes, # the actual classes - part, # one part of , used as loop counter - hc; # one H*-class - - ### function body ### - - mt := MultiplicationTable(semi); + local left, # partition of indices into L*-classes + lpart, # one part of + right, # partition of indices into R*-classes + rpart, # one part of + partition, # partition of indices into D*-classes + classes, # the actual classes + part, # one part of , used as loop counter + hc; # one H*-class # get R- and L-classes - LStarClasses(semi); RStarClasses(semi); + LStarClasses(semi); + RStarClasses(semi); + left := InternalRepStarRelation(LStarRelation(semi)); right := InternalRepStarRelation(RStarRelation(semi)); - partition := [ ]; + partition := []; for lpart in left do - for rpart in right do - Add(partition, Intersection(lpart, rpart)); - od; + for rpart in right do + Add(partition, Intersection(lpart, rpart)); + od; od; - partition := AsSSortedList(Filtered(partition, p-> not IsEmpty(p))); + partition := AsSSortedList(Filtered(partition, p -> not IsEmpty(p))); - SetInternalRepStarRelation(HStarRelation(semi), partition); + SetInternalRepStarRelation(HStarRelation(semi), partition); classes := EmptyPlist(Length(partition)); for part in partition do - hc := HStarClass(semi, Elements(semi)[part[1]]); - Add(classes, hc); - SetAsSSortedList(hc, Elements(semi){part}); - SetSize(hc, Size(part)); - SetCanonicalStarClass(hc, hc); + hc := HStarClass(semi, Elements(semi)[part[1]]); + Add(classes, hc); + SetAsSSortedList(hc, Elements(semi){part}); + SetSize(hc, Size(part)); + SetCanonicalStarClass(hc, hc); od; - SetHStarClasses(semi, classes); - return classes; end); -InstallOtherMethod(HStarClasses, "for a starred Green's class", -[IsStarClass], cl-> Filtered(HStarClasses(ParentAttr(cl)), - c-> Representative(c) in cl)); - - +InstallOtherMethod(HStarClasses, "for a starred Green's class", +[IsStarClass], cl -> Filtered(HStarClasses(ParentAttr(cl)), + c -> Representative(c) in cl)); diff --git a/gap/properties.gd b/gap/properties.gd index 5abfe9c..9b4b735 100644 --- a/gap/properties.gd +++ b/gap/properties.gd @@ -1,546 +1,495 @@ ############################################################################# ## -#W properties.gd Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2014 Andreas Distler & James D. Mitchell +## properties.gd Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# -########################################################################### -## -## <#GAPDoc Label="Annihilators"> -## -## -## -## returns the set of annihilators of sgrp if sgrp contains a -## zero element and fail otherwise.

-## -## An element x in a semigroup with zero z is an -## annihilator if xy=yx=z for every element y in the -## semigroup. -## s := SmallSemigroup(5,6); -## -## gap> Annihilators(s); -## [ s1, s2 ] -## ]]> -## -## -## <#/GAPDoc> - -DeclareAttribute( "Annihilators", IsSemigroup ); - -########################################################################### -## -## <#GAPDoc Label="DiagonalOfMultiplicationTable"> -## -## -## -## returns the diagonal of the multiplication table of the semigroup -## sgrp. -## s:=SmallSemigroup(8,10101);; -## gap> DiagonalOfMultiplicationTable(s); -## [ 1, 1, 1, 1, 1, 1, 1, 1 ] -## gap> s:=SmallSemigroup(7,10101);; -## gap> DiagonalOfMultiplicationTable(s); -## [ 1, 1, 1, 1, 1, 1, 1 ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="Annihilators"> +# +# +# +# returns the set of annihilators of sgrp if sgrp contains a +# zero element and fail otherwise.

+# +# An element x in a semigroup with zero z is an +# annihilator if xy=yx=z for every element y in the +# semigroup. +# s := SmallSemigroup(5,6); +# +# gap> Annihilators(s); +# [ s1, s2 ] +# ]]> +# +# +# <#/GAPDoc> +DeclareAttribute("Annihilators", IsSemigroup); + +# <#GAPDoc Label="DiagonalOfMultiplicationTable"> +# +# +# +# returns the diagonal of the multiplication table of the semigroup +# sgrp. +# s:=SmallSemigroup(8,10101);; +# gap> DiagonalOfMultiplicationTable(s); +# [ 1, 1, 1, 1, 1, 1, 1, 1 ] +# gap> s:=SmallSemigroup(7,10101);; +# gap> DiagonalOfMultiplicationTable(s); +# [ 1, 1, 1, 1, 1, 1, 1 ] +# ]]> +# +# +# <#/GAPDoc> DeclareAttribute("DiagonalOfMultiplicationTable", IsSemigroup); -########################################################################### -## -## <#GAPDoc Label="DisplaySmallSemigroup"> -## -## -## -## displays all the information about the small semigroup sgrp that -## is stored in the library and its Green's classes and -## idempotents. -## s:=SmallSemigroup(6, 3838);; -## gap> DisplaySmallSemigroup(s); -## IsBand: false -## IsBrandtSemigroup: false -## IsCommutative: false -## IsCompletelyRegularSemigroup: false -## IsFullTransformationSemigroupCopy: false -## IsGroupAsSemigroup: false -## IsIdempotentGenerated: false -## IsInverseSemigroup: false -## IsMonogenicSemigroup: false -## IsMonoidAsSemigroup: false -## IsMultSemigroupOfNearRing: false -## IsOrthodoxSemigroup: false -## IsRectangularBand: false -## IsRegularSemigroup: false -## IsSelfDualSemigroup: false -## IsSemigroupWithClosedIdempotents: true -## IsSimpleSemigroup: false -## IsSingularSemigroupCopy: false -## IsZeroSemigroup: false -## IsZeroSimpleSemigroup: false -## MinimalGeneratingSet: [ s3, s4, s5, s6 ] -## Idempotents: [ s1, s5, s6 ] -## GreensRClasses: [ {s1}, {s2}, {s3}, {s4}, {s5}, {s6} ] -## GreensLClasses: [ {s1}, {s2}, {s3}, {s4}, {s6} ] -## GreensHClasses: [ {s1}, {s2}, {s3}, {s4}, {s5}, {s6} ] -## GreensDClasses: [ {s1}, {s2}, {s3}, {s4}, {s6} ] -## ]]> -## -## -## <#/GAPDoc> -## - +# <#GAPDoc Label="DisplaySmallSemigroup"> +# +# +# +# displays all the information about the small semigroup sgrp that +# is stored in the library and its Green's classes and +# idempotents. +# s:=SmallSemigroup(6, 3838);; +# gap> DisplaySmallSemigroup(s); +# IsBand: false +# IsBrandtSemigroup: false +# IsCommutative: false +# IsCompletelyRegularSemigroup: false +# IsFullTransformationSemigroupCopy: false +# IsGroupAsSemigroup: false +# IsIdempotentGenerated: false +# IsInverseSemigroup: false +# IsMonogenicSemigroup: false +# IsMonoidAsSemigroup: false +# IsMultSemigroupOfNearRing: false +# IsOrthodoxSemigroup: false +# IsRectangularBand: false +# IsRegularSemigroup: false +# IsSelfDualSemigroup: false +# IsSemigroupWithClosedIdempotents: true +# IsSimpleSemigroup: false +# IsSingularSemigroupCopy: false +# IsZeroSemigroup: false +# IsZeroSimpleSemigroup: false +# MinimalGeneratingSet: [ s3, s4, s5, s6 ] +# Idempotents: [ s1, s5, s6 ] +# GreensRClasses: [ {s1}, {s2}, {s3}, {s4}, {s5}, {s6} ] +# GreensLClasses: [ {s1}, {s2}, {s3}, {s4}, {s6} ] +# GreensHClasses: [ {s1}, {s2}, {s3}, {s4}, {s5}, {s6} ] +# GreensDClasses: [ {s1}, {s2}, {s3}, {s4}, {s6} ] +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("DisplaySmallSemigroup"); -############################################################################# -## -## <#GAPDoc Label="IndexPeriod"> -## -## -## -## returns the minimum numbers m, r such that x^{m+r}=x^m; known -## as the index and period of the small semigroup element x. -## s:=SmallSemigroup(5,116); -## -## gap> x:=Elements(s)[3]; -## s3 -## gap> IndexPeriod(x); -## [ 2, 1 ] -## gap> x^3=x^2; -## true -## gap> x^2=x^1; -## false -## gap> x^3=x^1; -## false -## ]]> -## -## -## <#/GAPDoc> -## -## - +# <#GAPDoc Label="IndexPeriod"> +# +# +# +# returns the minimum numbers m, r such that x^{m+r}=x^m; known +# as the index and period of the small semigroup element x. +# s:=SmallSemigroup(5,116); +# +# gap> x:=Elements(s)[3]; +# s3 +# gap> IndexPeriod(x); +# [ 2, 1 ] +# gap> x^3=x^2; +# true +# gap> x^2=x^1; +# false +# gap> x^3=x^1; +# false +# ]]> +# +# +# <#/GAPDoc> +# DeclareAttribute("IndexPeriod", IsSmallSemigroupElt); -########################################################################### -## -## <#GAPDoc Label="IsBand"> -## -## -## -## returns true if the small semigroup sgrp is a band and -## false otherwise.

-## -## A semigroup sgrp is a band if every element is an -## idempotent, that is, x^2=x for all x in sgrp. -## s:=SmallSemigroup(5,519);; -## gap> IsBand(s); -## false -## gap> s:=OneSmallSemigroup(5, IsBand, true); -## -## gap> IsBand(s); -## true -## gap> IdSmallSemigroup(s); -## [ 5, 1010 ] -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="IsBrandtSemigroup"> -## -## -## -## returns true if the small semigroup sgrp is a Brandt semigroup -## and false otherwise.

-## -## A finite semigroup sgrp is a Brandt semigroup if it is inverse -## and zero simple. -## s:=SmallSemigroup(5,519);; -## gap> IsBrandtSemigroup(s); -## false -## gap> s:=OneSmallSemigroup(5, IsBrandtSemigroup, true); -## -## gap> IsBrandtSemigroup(s); -## true -## gap> IdSmallSemigroup(s); -## [ 5, 149 ] -## ]]> -## -## -## <#/GAPDoc> - - - -########################################################################### -## -## <#GAPDoc Label="IsCliffordSemigroup"> -## -## -## -## returns true if the small semigroup sgrp is a Clifford -## semigroup and false otherwise.

-## -## A semigroup sgrp is a Clifford semigroup if it is a -## regular semigroup whose idempotents are central, that is, for all -## e,x in sgrp where e^2=e -## we have that ex=xe. -## s:=SmallSemigroup(5,519);; -## gap> IsBand(s); -## false -## gap> s:=OneSmallSemigroup(5, IsBand, true); -## -## gap> IsBand(s); -## true -## gap> IdSmallSemigroup(s); -## [ 5, 1010 ] -## gap> s:=SmallSemigroup(5,519);; -## gap> IsCliffordSemigroup(s); -## false -## gap> s:=OneSmallSemigroup(5, IsCliffordSemigroup, true); -## -## gap> IsCliffordSemigroup(s); -## true -## gap> IdSmallSemigroup(s); -## [ 5, 148 ] -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="IsCommutativeSemigroup"> -## -## -## -## -## return true if the small semigroup sgrp is commutative -## and false otherwise.

-## -## A semigroup sgrp is commutative if -## xy=yx for all x,y in sgrp. -## s:=SmallSemigroup(6,871);; -## gap> IsCommutativeSemigroup(s); -## false -## gap> s:=OneSmallSemigroup(5, IsCommutative, true); -## -## gap> IsCommutativeSemigroup(s); -## true -## gap> IsCommutative(s); -## true -## gap> IdSmallSemigroup(s); -## [ 5, 1 ] -## gap> s:=OneSmallSemigroup(5, IsCommutativeSemigroup, true); -## -## gap> IsCommutativeSemigroup(s); -## true -## gap> IsCommutative(s); -## true -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="IsCompletelyRegularSemigroup"> -## -## -## -## returns true if the semigroup sgrp is completely -## regular and false otherwise.

-## A semigroup is completely regular -## if every element is contained in a subgroup. -## s:=SmallSemigroup(6,13131); -## -## gap> IsCompletelyRegularSemigroup(s); -## false -## gap> s:=OneSmallSemigroup(6, IsCompletelyRegularSemigroup, true); -## -## gap> IsCompletelyRegularSemigroup(s); -## true -## gap> IdSmallSemigroup(s); -## [ 6, 3164 ] -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="IsFullTransformationSemigroupCopy"> -## -## -## -## returns true if the semigroup sgrp is isomorphic to a full -## transformation -## semigroup and false otherwise.

-## -## The size of the full transformation semigroup on an n element set is -## n^n and so there are only two semigroup in the library that have this property. -## s:=SmallSemigroup(1,1); -## -## gap> IsFullTransformationSemigroupCopy(s); -## true -## gap> s:=OneSmallSemigroup(4, IsFullTransformationSemigroupCopy, true); -## -## gap> IsFullTransformationSemigroupCopy(s); -## true -## gap> IdSmallSemigroup(s); -## [ 4, 96 ] -## gap> s:=OneSmallSemigroup(6, IsFullTransformationSemigroupCopy, true); -## fail -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="IsBand"> +# +# +# +# returns true if the small semigroup sgrp is a band and +# false otherwise.

+# +# A semigroup sgrp is a band if every element is an idempotent, +# that is, x^2=x for all x in sgrp. +# s:=SmallSemigroup(5,519);; +# gap> IsBand(s); +# false +# gap> s:=OneSmallSemigroup(5, IsBand, true); +# +# gap> IsBand(s); +# true +# gap> IdSmallSemigroup(s); +# [ 5, 1010 ] +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsBrandtSemigroup"> +# +# +# +# returns true if the small semigroup sgrp is a Brandt semigroup +# and false otherwise.

+# +# A finite semigroup sgrp is a Brandt semigroup if it is inverse +# and zero simple. +# s:=SmallSemigroup(5,519);; +# gap> IsBrandtSemigroup(s); +# false +# gap> s:=OneSmallSemigroup(5, IsBrandtSemigroup, true); +# +# gap> IsBrandtSemigroup(s); +# true +# gap> IdSmallSemigroup(s); +# [ 5, 149 ] +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsCliffordSemigroup"> +# +# +# +# returns true if the small semigroup sgrp is a Clifford +# semigroup and false otherwise.

+# +# A semigroup sgrp is a Clifford semigroup if it is a +# regular semigroup whose idempotents are central, that is, for all +# e,x in sgrp where e^2=e +# we have that ex=xe. +# s:=SmallSemigroup(5,519);; +# gap> IsBand(s); +# false +# gap> s:=OneSmallSemigroup(5, IsBand, true); +# +# gap> IsBand(s); +# true +# gap> IdSmallSemigroup(s); +# [ 5, 1010 ] +# gap> s:=SmallSemigroup(5,519);; +# gap> IsCliffordSemigroup(s); +# false +# gap> s:=OneSmallSemigroup(5, IsCliffordSemigroup, true); +# +# gap> IsCliffordSemigroup(s); +# true +# gap> IdSmallSemigroup(s); +# [ 5, 148 ] +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsCommutativeSemigroup"> +# +# +# +# +# return true if the small semigroup sgrp is commutative and +# false otherwise.

+# +# A semigroup sgrp is commutative if xy=yx for all +# x,y in sgrp. +# s:=SmallSemigroup(6,871);; +# gap> IsCommutativeSemigroup(s); +# false +# gap> s:=OneSmallSemigroup(5, IsCommutative, true); +# +# gap> IsCommutativeSemigroup(s); +# true +# gap> IsCommutative(s); +# true +# gap> IdSmallSemigroup(s); +# [ 5, 1 ] +# gap> s:=OneSmallSemigroup(5, IsCommutativeSemigroup, true); +# +# gap> IsCommutativeSemigroup(s); +# true +# gap> IsCommutative(s); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsCompletelyRegularSemigroup"> +# +# +# +# returns true if the semigroup sgrp is completely +# regular and false otherwise.

+# A semigroup is completely regular +# if every element is contained in a subgroup. +# s:=SmallSemigroup(6,13131); +# +# gap> IsCompletelyRegularSemigroup(s); +# false +# gap> s:=OneSmallSemigroup(6, IsCompletelyRegularSemigroup, true); +# +# gap> IsCompletelyRegularSemigroup(s); +# true +# gap> IdSmallSemigroup(s); +# [ 6, 3164 ] +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsFullTransformationSemigroupCopy"> +# +# +# +# returns true if the semigroup sgrp is isomorphic to a full +# transformation +# semigroup and false otherwise.

+# +# The size of the full transformation semigroup on an n element set is +# n^n and so there are only two semigroup in the library that have this +# property. +# s:=SmallSemigroup(1,1); +# +# gap> IsFullTransformationSemigroupCopy(s); +# true +# gap> s:=OneSmallSemigroup(4, IsFullTransformationSemigroupCopy, true); +# +# gap> IsFullTransformationSemigroupCopy(s); +# true +# gap> IdSmallSemigroup(s); +# [ 4, 96 ] +# gap> s:=OneSmallSemigroup(6, IsFullTransformationSemigroupCopy, true); +# fail +# ]]> +# +# +# <#/GAPDoc> DeclareProperty("IsFullTransformationSemigroupCopy", IsSmallSemigroup); - -########################################################################### -## -## <#GAPDoc Label="IsGroupAsSemigroup"> -## -## -## -## returns true if the small semigroup sgrp -## is mathematically a group, and returns false otherwise. -## Note that no small semigroup can lie in the category -## . -## s:=SmallSemigroup(7,7); -## -## gap> IsGroupAsSemigroup(s); -## false -## gap> s:=SmallSemigroup(4,37);; -## gap> IsGroupAsSemigroup(s); -## true -## ]]> -## -## -## <#/GAPDoc> - -########################################################################### -## -## <#GAPDoc Label="IsIdempotentGenerated"> -## IsIdempotentGenerated -## -## -## -## returns true if the semigroup sgrp is a -## semiband and false otherwise.

-## -## A semigroup sgrp is idempotent generated or equivalently a -## semiband if it is generated by its idempotent elements, i.e elements -## satisfying x^2=x. -## s:=SmallSemigroup(3, 13); -## -## gap> IsIdempotentGenerated(s); -## true -## gap> s:=OneSmallSemigroup(3, IsIdempotentGenerated, false); -## -## gap> IsIdempotentGenerated(s); -## false -## gap> IdSmallSemigroup(s); -## [ 3, 1 ] -## gap> s:=OneSmallSemigroup(4, IsIdempotentGenerated, true, -## > IsSingularSemigroupCopy, true); -## fail -## gap> s:=OneSmallSemigroup(2, IsIdempotentGenerated, true, -## > IsSingularSemigroupCopy, true); -## -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="IsInverseSemigroup"> -## -## -## -## returns true if the semigroup sgrp is an inverse -## semigroup and false otherwise.

-## -## A semigroup sgrp is an inverse semigroup if every element -## x in sgrp has a unique semigroup inverse, that is, a unique -## element y such that xyx=x and yxy=y. -## s:=OneSmallSemigroup(7, IsInverseSemigroup, true); -## -## gap> IsInverseSemigroup(s); -## true -## gap> s:=SmallSemigroup(7, 101324); -## -## gap> IsInverseSemigroup(s); -## false -## ]]> -## -## -## <#/GAPDoc> - -########################################################################### -## -## <#GAPDoc Label="IsLeftZeroSemigroup"> -## -## -## -## returns true if the semigroup sgrp is -## a left zero semigroup and false otherwise.

-## -## A semigroup sgrp is a left zero semigroup if xy=x -## for all x,y in sgrp. -## s:=SmallSemigroup(5, 438); -## -## gap> IsLeftZeroSemigroup(s); -## false -## gap> s:=SmallSemigroup(5, 1141); -## -## gap> IsLeftZeroSemigroup(s); -## true -## ]]> -## -## -## <#/GAPDoc> - -########################################################################### -## -## <#GAPDoc Label="IsMonogenicSemigroup"> -## -## -## -## returns true if the small semigroup sgrp is generated by a -## single element and false otherwise. -## s:=RandomSmallSemigroup(7); -## -## gap> IsMonogenicSemigroup(s); -## false -## gap> s:=OneSmallSemigroup(7, IsMonogenicSemigroup, true); -## -## gap> IsMonogenicSemigroup(s); -## true -## gap> MinimalGeneratingSet(s); -## [ s7 ] -## gap> s:=SmallSemigroup( 7, 406945); -## -## gap> IsMonogenicSemigroup(s); -## false -## ]]> -## -## -## <#/GAPDoc> +# <#GAPDoc Label="IsGroupAsSemigroup"> +# +# +# +# returns true if the small semigroup sgrp +# is mathematically a group, and returns false otherwise. +# Note that no small semigroup can lie in the category +# . +# s:=SmallSemigroup(7,7); +# +# gap> IsGroupAsSemigroup(s); +# false +# gap> s:=SmallSemigroup(4,37);; +# gap> IsGroupAsSemigroup(s); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsIdempotentGenerated"> +# IsIdempotentGenerated +# +# +# +# returns true if the semigroup sgrp is a +# semiband and false otherwise.

+# +# A semigroup sgrp is idempotent generated or equivalently a +# semiband if it is generated by its idempotent elements, i.e elements +# satisfying x^2=x. +# s:=SmallSemigroup(3, 13); +# +# gap> IsIdempotentGenerated(s); +# true +# gap> s:=OneSmallSemigroup(3, IsIdempotentGenerated, false); +# +# gap> IsIdempotentGenerated(s); +# false +# gap> IdSmallSemigroup(s); +# [ 3, 1 ] +# gap> s:=OneSmallSemigroup(4, IsIdempotentGenerated, true, +# > IsSingularSemigroupCopy, true); +# fail +# gap> s:=OneSmallSemigroup(2, IsIdempotentGenerated, true, +# > IsSingularSemigroupCopy, true); +# +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsInverseSemigroup"> +# +# +# +# returns true if the semigroup sgrp is an inverse +# semigroup and false otherwise.

+# +# A semigroup sgrp is an inverse semigroup if every element +# x in sgrp has a unique semigroup inverse, that is, a unique +# element y such that xyx=x and yxy=y. +# s:=OneSmallSemigroup(7, IsInverseSemigroup, true); +# +# gap> IsInverseSemigroup(s); +# true +# gap> s:=SmallSemigroup(7, 101324); +# +# gap> IsInverseSemigroup(s); +# false +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsLeftZeroSemigroup"> +# +# +# +# returns true if the semigroup sgrp is +# a left zero semigroup and false otherwise.

+# +# A semigroup sgrp is a left zero semigroup if xy=x +# for all x,y in sgrp. +# s:=SmallSemigroup(5, 438); +# +# gap> IsLeftZeroSemigroup(s); +# false +# gap> s:=SmallSemigroup(5, 1141); +# +# gap> IsLeftZeroSemigroup(s); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsMonogenicSemigroup"> +# +# +# +# returns true if the small semigroup sgrp is generated by a +# single element and false otherwise. +# s:=RandomSmallSemigroup(7); +# +# gap> IsMonogenicSemigroup(s); +# false +# gap> s:=OneSmallSemigroup(7, IsMonogenicSemigroup, true); +# +# gap> IsMonogenicSemigroup(s); +# true +# gap> MinimalGeneratingSet(s); +# [ s7 ] +# gap> s:=SmallSemigroup( 7, 406945); +# +# gap> IsMonogenicSemigroup(s); +# false +# ]]> +# +# +# <#/GAPDoc> DeclareSynonymAttr("Is1GeneratedSemigroup", IsMonogenicSemigroup); -########################################################################### -## -## <#GAPDoc Label="IsMonoidAsSemigroup"> -## -## -## -## returns true if the semigroup sgrp is a monoid (i.e. has an -## identity element) and false otherwise. -## s:=SmallSemigroup(4, 126); -## -## gap> IsMonoidAsSemigroup(s); -## false -## gap> s:=OneSmallSemigroup(4, IsMonoidAsSemigroup, true); -## -## gap> IsMonoidAsSemigroup(s); -## true -## gap> One(s); -## s1 -## gap> IdSmallSemigroup(s); -## [ 4, 7 ] -## ]]> -## -## -## <#/GAPDoc> -## - -########################################################################### -## -## <#GAPDoc Label="IsMultSemigroupOfNearRing"> -## -## -## -## returns true if sgrp is isomorphic (or anti-isomorphic?) -## to the multiplicative semigroup of a near-ring and false otherwise. -##

-## Those semigroups in the library that have this property were identified -## using the Sonata package. -## s:=OneSmallSemigroup(7, IsMultSemigroupOfNearRing, true); -## -## gap> IdSmallSemigroup(s); -## [ 7, 1 ] -## gap> IsMultSemigroupOfNearRing(s); -## true -## gap> s:=SmallSemigroup(2,2); -## -## gap> IsMultSemigroupOfNearRing(s); -## false -## ]]> -## -## -## <#/GAPDoc> -## JDM expand the example? is it isomorphic and anti-isomorphic or only -## isomorphic? - +# <#GAPDoc Label="IsMonoidAsSemigroup"> +# +# +# +# returns true if the semigroup sgrp is a monoid (i.e. has an +# identity element) and false otherwise. +# s:=SmallSemigroup(4, 126); +# +# gap> IsMonoidAsSemigroup(s); +# false +# gap> s:=OneSmallSemigroup(4, IsMonoidAsSemigroup, true); +# +# gap> IsMonoidAsSemigroup(s); +# true +# gap> One(s); +# s1 +# gap> IdSmallSemigroup(s); +# [ 4, 7 ] +# ]]> +# +# +# <#/GAPDoc> +# + +# <#GAPDoc Label="IsMultSemigroupOfNearRing"> +# +# +# +# returns true if sgrp is isomorphic (or anti-isomorphic?) +# to the multiplicative semigroup of a near-ring and false otherwise. +#

+# Those semigroups in the library that have this property were identified +# using the Sonata package. +# s:=OneSmallSemigroup(7, IsMultSemigroupOfNearRing, true); +# +# gap> IdSmallSemigroup(s); +# [ 7, 1 ] +# gap> IsMultSemigroupOfNearRing(s); +# true +# gap> s:=SmallSemigroup(2,2); +# +# gap> IsMultSemigroupOfNearRing(s); +# false +# ]]> +# +# +# <#/GAPDoc> +# JDM expand the example? is it isomorphic and anti-isomorphic or only +# isomorphic? DeclareProperty("IsMultSemigroupOfNearRing", IsSmallSemigroup); -########################################################################### -## -## <#GAPDoc Label="IsNGeneratedSemigroup"> -## -## -## -## returns true if the least size of a generating set for the -## small semigroup sgrp is n and false otherwise. -## s:=SmallSemigroup(7, 760041); -## -## gap> IsNGeneratedSemigroup(s, 4); -## false -## gap> IsNGeneratedSemigroup(s, 3); -## true -## gap> MinimalGeneratingSet(s); -## [ s3, s5, s7 ] -## gap> s:=OneSmallSemigroup(4, x-> Length(MinimalGeneratingSet(x)), 4); -## -## gap> IsNGeneratedSemigroup(s, 4); -## true -## ]]> -## -## -## <#/GAPDoc> +# <#GAPDoc Label="IsNGeneratedSemigroup"> +# +# +# +# returns true if the least size of a generating set for the +# small semigroup sgrp is n and false otherwise. +# s:=SmallSemigroup(7, 760041); +# +# gap> IsNGeneratedSemigroup(s, 4); +# false +# gap> IsNGeneratedSemigroup(s, 3); +# true +# gap> MinimalGeneratingSet(s); +# [ s3, s5, s7 ] +# gap> s:=OneSmallSemigroup(4, x-> Length(MinimalGeneratingSet(x)), 4); +# +# gap> IsNGeneratedSemigroup(s, 4); +# true +# ]]> +# +# +# <#/GAPDoc> DeclareOperation("IsNGeneratedSemigroup", [IsSmallSemigroup, IsPosInt]); @@ -552,26 +501,24 @@ DeclareProperty("Is6GeneratedSemigroup", IsSmallSemigroup); DeclareProperty("Is7GeneratedSemigroup", IsSmallSemigroup); DeclareProperty("Is8GeneratedSemigroup", IsSmallSemigroup); -########################################################################### -## -## <#GAPDoc Label="IsNIdempotentSemigroup"> -## -## -## -## returns true if the small semigroup sgrp has n idempotents -## and false otherwise. -## s:=SmallSemigroup(4, 75);; -## gap> IsNIdempotentSemigroup(s, 1); -## false -## gap> IsNIdempotentSemigroup(s, 2); -## false -## gap> IsNIdempotentSemigroup(s, 3); -## true -## ]]> -## -## -## <#/GAPDoc> +# <#GAPDoc Label="IsNIdempotentSemigroup"> +# +# +# +# returns true if the small semigroup sgrp has n idempotents +# and false otherwise. +# s:=SmallSemigroup(4, 75);; +# gap> IsNIdempotentSemigroup(s, 1); +# false +# gap> IsNIdempotentSemigroup(s, 2); +# false +# gap> IsNIdempotentSemigroup(s, 3); +# true +# ]]> +# +# +# <#/GAPDoc> DeclareOperation("IsNIdempotentSemigroup", [IsSmallSemigroup, IsPosInt]); @@ -584,541 +531,427 @@ DeclareProperty("Is6IdempotentSemigroup", IsSmallSemigroup); DeclareProperty("Is7IdempotentSemigroup", IsSmallSemigroup); DeclareProperty("Is8IdempotentSemigroup", IsSmallSemigroup); -############################################################################# -## -## <#GAPDoc Label="IsNilpotentSemigroup"> -## IsNilpotentSemigroup -## -## -## -## returns true if the small semigroup sgrp is nilpotent and -## false otherwise. -##

-## -## A semigroup is nilpotent if it has a zero element and -## every element to some power equals this zero. -## -## s:=SmallSemigroup(5,116); -## -## gap> IsNilpotentSemigroup(s); -## false -## gap> s:=SmallSemigroup(7, 673768);; -## gap> IsNilpotentSemigroup(s); -## true -## gap> s:=SmallSemigroup(7, 657867);; -## gap> IsNilpotent(s); -## true -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="IsOrthodoxSemigroup"> -## -## -## -## returns true if the semigroup sgrp is orthodox and -## false otherwise. -##

-## -## A semigroup is orthodox if it is regular and its idempotents -## form a subsemigroup. -## s:=SmallSemigroup(6, 15858);; -## gap> IsSemigroupWithClosedIdempotents(s); -## true -## gap> IsRegularSemigroup(s); -## true -## gap> IsOrthodoxSemigroup(s); -## true -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="IsRectangularBand"> -## -## -## -## returns true if the small semigroup sgrp is a -## rectangular band and false otherwise.

-## -## A semigroup sgrp is a rectangular band if for all -## x,y,z in sgrp we have that x^2=x and xyz=xz. -## s:=SmallSemigroup(5, 216);; -## gap> IsRectangularBand(s); -## false -## gap> s:=SmallSemigroup(6, 15854);; -## gap> IsRectangularBand(s); -## true -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="IsRegularSemigroup"> -## -## -## -## returns true if the small semigroup sgrp is a regular -## semigroup and false otherwise.

-## -## A semigroup sgrp is regular if for all x in -## sgrp there exists y in sgrp such that xyx=x. -## -## s:=SmallSemigroup(3, 10);; -## gap> IsRegularSemigroup(s); -## true -## gap> s:=SmallSemigroup(3, 1);; -## gap> IsRegularSemigroup(s); -## false -## gap> s:=OneSmallSemigroup(4, IsFullTransformationSemigroupCopy, true); -## -## gap> IsRegularSemigroup(s); -## true -## ]]> -## -## -## <#/GAPDoc> - -########################################################################### -## -## <#GAPDoc Label="IsRightZeroSemigroup"> -## -## -## -## returns false for any small semigroup sgrp since -## the library contains only left zero semigroups. -##

-## A semigroup sgrp is a right zero semigroup if xy=y -## for all x,y in sgrp. -## -## s:=SmallSemigroup(5, 438); -## -## gap> IsRightZeroSemigroup(s); -## false -## ]]> -## -## -## <#/GAPDoc> - - -############################################################################ -## -## <#GAPDoc Label="IsSelfDualSemigroup"> -## -## -## -## returns true if the semigroup sgrp is self dual and -## false otherwise. -##

-## A semigroup is self dual if it is isomorphic to its dual, -## that is, the semigroup t with multiplication * defined -## by x*y=yx where yx denotes the product in sgrp. -## s:=SmallSemigroup(5,116); -## -## gap> IsSelfDualSemigroup(s); -## false -## gap> s:=RandomSmallSemigroup(5, IsSelfDualSemigroup, true); -## -## gap> IsSelfDualSemigroup(s); -## true -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="IsNilpotentSemigroup"> +# IsNilpotentSemigroup +# +# +# +# returns true if the small semigroup sgrp is nilpotent and +# false otherwise. +#

+# +# A semigroup is nilpotent if it has a zero element and +# every element to some power equals this zero. +# +# s:=SmallSemigroup(5,116); +# +# gap> IsNilpotentSemigroup(s); +# false +# gap> s:=SmallSemigroup(7, 673768);; +# gap> IsNilpotentSemigroup(s); +# true +# gap> s:=SmallSemigroup(7, 657867);; +# gap> IsNilpotent(s); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsOrthodoxSemigroup"> +# +# +# +# returns true if the semigroup sgrp is orthodox and +# false otherwise. +#

+# +# A semigroup is orthodox if it is regular and its idempotents +# form a subsemigroup. +# s:=SmallSemigroup(6, 15858);; +# gap> IsSemigroupWithClosedIdempotents(s); +# true +# gap> IsRegularSemigroup(s); +# true +# gap> IsOrthodoxSemigroup(s); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsRectangularBand"> +# +# +# +# returns true if the small semigroup sgrp is a +# rectangular band and false otherwise.

+# +# A semigroup sgrp is a rectangular band if for all +# x,y,z in sgrp we have that x^2=x and xyz=xz. +# s:=SmallSemigroup(5, 216);; +# gap> IsRectangularBand(s); +# false +# gap> s:=SmallSemigroup(6, 15854);; +# gap> IsRectangularBand(s); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsRegularSemigroup"> +# +# +# +# returns true if the small semigroup sgrp is a regular +# semigroup and false otherwise.

+# +# A semigroup sgrp is regular if for all x in +# sgrp there exists y in sgrp such that xyx=x. +# +# s:=SmallSemigroup(3, 10);; +# gap> IsRegularSemigroup(s); +# true +# gap> s:=SmallSemigroup(3, 1);; +# gap> IsRegularSemigroup(s); +# false +# gap> s:=OneSmallSemigroup(4, IsFullTransformationSemigroupCopy, true); +# +# gap> IsRegularSemigroup(s); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsRightZeroSemigroup"> +# +# +# +# returns false for any small semigroup sgrp since +# the library contains only left zero semigroups. +#

+# A semigroup sgrp is a right zero semigroup if xy=y +# for all x,y in sgrp. +# +# s:=SmallSemigroup(5, 438); +# +# gap> IsRightZeroSemigroup(s); +# false +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsSelfDualSemigroup"> +# +# +# +# returns true if the semigroup sgrp is self dual and +# false otherwise. +#

+# A semigroup is self dual if it is isomorphic to its dual, +# that is, the semigroup t with multiplication * defined +# by x*y=yx where yx denotes the product in sgrp. +# s:=SmallSemigroup(5,116); +# +# gap> IsSelfDualSemigroup(s); +# false +# gap> s:=RandomSmallSemigroup(5, IsSelfDualSemigroup, true); +# +# gap> IsSelfDualSemigroup(s); +# true +# ]]> +# +# +# <#/GAPDoc> DeclareProperty("IsSelfDualSemigroup", IsSmallSemigroup); -########################################################################### -## -## <#GAPDoc Label="IsSemigroupWithClosedIdempotents"> -## -## -## -## returns true if the idempotent elements of the semigroup -## sgrp form a subsemigroup and false otherwise. -## -## s:=SmallSemigroup(5, 677);; -## gap> IsSemigroupWithClosedIdempotents(s); -## true -## gap> s:=SmallSemigroup(5, 659);; -## gap> IsSemigroupWithClosedIdempotents(s); -## true -## gap> s:=SmallSemigroup(5, 327);; -## gap> IsSemigroupWithClosedIdempotents(s); -## false -## ]]> -## -## -## <#/GAPDoc> +# <#GAPDoc Label="IsSemigroupWithClosedIdempotents"> +# +# +# +# returns true if the idempotent elements of the semigroup sgrp +# form a subsemigroup and false otherwise. +# +# s:=SmallSemigroup(5, 677);; +# gap> IsSemigroupWithClosedIdempotents(s); +# true +# gap> s:=SmallSemigroup(5, 659);; +# gap> IsSemigroupWithClosedIdempotents(s); +# true +# gap> s:=SmallSemigroup(5, 327);; +# gap> IsSemigroupWithClosedIdempotents(s); +# false +# ]]> +# +# +# <#/GAPDoc> if not IsBoundGlobal("IsSemigroupWithClosedIdempotents") then DeclareProperty("IsSemigroupWithClosedIdempotents", IsSemigroup); fi; -############################################################################ -## <#GAPDoc Label="IsSemigroupWithZero"> -## -## -## -## returns true if the semigroup sgrp has a zero element -## and false otherwise. -##

-## -## An element z is a zero if z*x=x*z=z for all -## x in the semigroup. -## -## s:=SmallSemigroup(5,1); -## -## gap> IsSemigroupWithZero(s); -## true -## gap> s:=SmallSemigroup(4,26); -## -## gap> IsSemigroupWithZero(s); -## false -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="IsSemigroupWithZero"> +# +# +# +# returns true if the semigroup sgrp has a zero element +# and false otherwise. +#

+# +# An element z is a zero if z*x=x*z=z for all +# x in the semigroup. +# +# s:=SmallSemigroup(5,1); +# +# gap> IsSemigroupWithZero(s); +# true +# gap> s:=SmallSemigroup(4,26); +# +# gap> IsSemigroupWithZero(s); +# false +# ]]> +# +# +# <#/GAPDoc> DeclareProperty("IsSemigroupWithZero", IsSemigroup); -########################################################################### -## -## <#GAPDoc Label="IsSimpleSemigroup"> -## IsSimpleSemigroup -## -## -## -## return true if the semigroup sgrp is simple or -## completely simple and false otherwise. -##

-## A semigroup is simple if it has no proper 2-sided ideals. A -## semigroup is completely simple if it is simple and possesses -## minimal left and right ideals. -##

-## A finite semigroup is simple if and only if it is completely simple. -## s:=SmallSemigroup(7, 835080);; -## gap> IsSimpleSemigroup(s); -## true -## gap> IsCompletelySimpleSemigroup(s); -## true -## gap> s:=SmallSemigroup(7, 208242);; -## gap> IsSimpleSemigroup(s); -## false -## ]]> -## -## -## <#/GAPDoc> - -########################################################################### -## -## <#GAPDoc Label="IsSingularSemigroupCopy"> -## -## -## -## returns true if the semigroup sgrp is isomorphic to a -## semigroup of singular (i.e. non-invertible) mappings on a finite set -## and false otherwise. -##

-## The size of this semigroup on an n element set is n^n-n! -## and so there is only one semigroup in the library that has this property. -## s:=SmallSemigroup(1,1); -## -## gap> IsSingularSemigroupCopy(s); -## false -## gap> s:=OneSmallSemigroup(2, IsSingularSemigroupCopy, true); -## -## gap> IsSingularSemigroupCopy(s); -## true -## gap> IdSmallSemigroup(s); -## [ 2, 4 ] -## gap> s:=OneSmallSemigroup(4, IsSingularSemigroupCopy, true); -## fail -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="IsSimpleSemigroup"> +# IsSimpleSemigroup +# +# +# +# return true if the semigroup sgrp is simple or +# completely simple and false otherwise. +#

+# A semigroup is simple if it has no proper 2-sided ideals. A +# semigroup is completely simple if it is simple and possesses +# minimal left and right ideals. +#

+# A finite semigroup is simple if and only if it is completely simple. +# s:=SmallSemigroup(7, 835080);; +# gap> IsSimpleSemigroup(s); +# true +# gap> IsCompletelySimpleSemigroup(s); +# true +# gap> s:=SmallSemigroup(7, 208242);; +# gap> IsSimpleSemigroup(s); +# false +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsSingularSemigroupCopy"> +# +# +# +# returns true if the semigroup sgrp is isomorphic to a +# semigroup of singular (i.e. non-invertible) mappings on a finite set +# and false otherwise. +#

+# The size of this semigroup on an n element set is n^n-n! +# and so there is only one semigroup in the library that has this property. +# s:=SmallSemigroup(1,1); +# +# gap> IsSingularSemigroupCopy(s); +# false +# gap> s:=OneSmallSemigroup(2, IsSingularSemigroupCopy, true); +# +# gap> IsSingularSemigroupCopy(s); +# true +# gap> IdSmallSemigroup(s); +# [ 2, 4 ] +# gap> s:=OneSmallSemigroup(4, IsSingularSemigroupCopy, true); +# fail +# ]]> +# +# +# <#/GAPDoc> DeclareProperty("IsSingularSemigroupCopy", IsSmallSemigroup); -########################################################################### -## -## <#GAPDoc Label="IsZeroGroup"> -## -## -## -## returns true if the semigroup sgrp is a zero group -## and false otherwise. -##

-## The semigroup sgrp is a zero group if there exists -## an element z in sgrp such that sgrp without -## z is a group and for all x in sgrp we have that -## xz=zx=z. -## g:=Group((1,2),(3,4)); -## Group([ (1,2), (3,4) ]) -## gap> IdSmallSemigroup(g); -## [ 4, 7 ] -## gap> s := Range(InjectionZeroMagma(g)); -## -## gap> IdSmallSemigroup(s); -## [ 5, 149 ] -## gap> IsZeroGroup(s); -## true -## ]]> -## -## -## <#/GAPDoc> - -########################################################################### -## -## <#GAPDoc Label="IsZeroSemigroup"> -## -## -## -## returns true if the semigroup sgrp is a zero semigroup -## and false otherwise. -##

-## The semigroup sgrp is a zero semigroup if there exists an -## element z in sgrp such that xy=z for all x,y -## in sgrp. -## s:=OneSmallSemigroup(5, IsZeroSemigroup, true); -## -## gap> IsZeroSemigroup(s); -## true -## gap> IdSmallSemigroup(s); -## [ 5, 1 ] -## gap> s:=OneSmallSemigroup(5, IsZeroSemigroup, false); -## -## gap> IdSmallSemigroup(s); -## [ 5, 2 ] -## gap> IsZeroSemigroup(s); -## false -## ]]> -## Note that for each size the unique zero semigroup is always the first -## semigroup of this size in the library. -## IsZeroSemigroup(SmallSemigroup(6,1)); -## true -## gap> IsZeroSemigroup(SmallSemigroup(7,1)); -## true -## gap> IsZeroSemigroup(SmallSemigroup(8,1)); -## true -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="IsZeroSimpleSemigroup"> -## -## -## -## return true if the semigroup sgrp is zero simple -## and false otherwise.

-## -## A semigroup sgrp is zero simple if the only 2-sided ideals -## are the zero {0} and sgrp. -## s:=SmallSemigroup(7, 519799); -## -## gap> IsZeroSimpleSemigroup(s); -## false -## gap> s:=RandomSmallSemigroup(7, IsZeroSimpleSemigroup, true); -## -## gap> IsZeroSimpleSemigroup(s); -## true -## ]]> -## -## -## <#/GAPDoc> - - -########################################################################### -## -## <#GAPDoc Label="MinimalGeneratingSet"> -## -## -## -## returns a set of generators for sgrp with minimal size. -## s:=SmallSemigroup(8, 1478885610);; -## gap> MinimalGeneratingSet(s); -## [ s4, s5, s6, s7, s8 ] -## gap> s:=SmallSemigroup(7, 673768);; -## gap> MinimalGeneratingSet(s); -## [ s4, s5, s6, s7 ] -## gap> s:=SmallSemigroup(4, 4);; -## gap> MinimalGeneratingSet(s); -## [ s2, s3, s4 ] -## ]]> -## -## -## <#/GAPDoc> +# <#GAPDoc Label="IsZeroGroup"> +# +# +# +# returns true if the semigroup sgrp is a zero group +# and false otherwise. +#

+# The semigroup sgrp is a zero group if there exists +# an element z in sgrp such that sgrp without +# z is a group and for all x in sgrp we have that +# xz=zx=z. +# g:=Group((1,2),(3,4)); +# Group([ (1,2), (3,4) ]) +# gap> IdSmallSemigroup(g); +# [ 4, 7 ] +# gap> s := Range(InjectionZeroMagma(g)); +# +# gap> IdSmallSemigroup(s); +# [ 5, 149 ] +# gap> IsZeroGroup(s); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsZeroSemigroup"> +# +# +# +# returns true if the semigroup sgrp is a zero semigroup +# and false otherwise. +#

+# The semigroup sgrp is a zero semigroup if there exists an +# element z in sgrp such that xy=z for all x,y +# in sgrp. +# s:=OneSmallSemigroup(5, IsZeroSemigroup, true); +# +# gap> IsZeroSemigroup(s); +# true +# gap> IdSmallSemigroup(s); +# [ 5, 1 ] +# gap> s:=OneSmallSemigroup(5, IsZeroSemigroup, false); +# +# gap> IdSmallSemigroup(s); +# [ 5, 2 ] +# gap> IsZeroSemigroup(s); +# false +# ]]> +# Note that for each size the unique zero semigroup is always the first +# semigroup of this size in the library. +# IsZeroSemigroup(SmallSemigroup(6,1)); +# true +# gap> IsZeroSemigroup(SmallSemigroup(7,1)); +# true +# gap> IsZeroSemigroup(SmallSemigroup(8,1)); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsZeroSimpleSemigroup"> +# +# +# +# return true if the semigroup sgrp is zero simple +# and false otherwise.

+# +# A semigroup sgrp is zero simple if the only 2-sided ideals +# are the zero {0} and sgrp. +# s:=SmallSemigroup(7, 519799); +# +# gap> IsZeroSimpleSemigroup(s); +# false +# gap> s:=RandomSmallSemigroup(7, IsZeroSimpleSemigroup, true); +# +# gap> IsZeroSimpleSemigroup(s); +# true +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="MinimalGeneratingSet"> +# +# +# +# returns a set of generators for sgrp with minimal size. +# s:=SmallSemigroup(8, 1478885610);; +# gap> MinimalGeneratingSet(s); +# [ s4, s5, s6, s7, s8 ] +# gap> s:=SmallSemigroup(7, 673768);; +# gap> MinimalGeneratingSet(s); +# [ s4, s5, s6, s7 ] +# gap> s:=SmallSemigroup(4, 4);; +# gap> MinimalGeneratingSet(s); +# [ s2, s3, s4 ] +# ]]> +# +# +# <#/GAPDoc> # MinimalGeneratingSet was only declared for IsGroup in GAP < 4.12. This # declaration and comment can be removed if smallsemi ever requires GAP >= 4.12. DeclareAttribute("MinimalGeneratingSet", IsSemigroup); -########################################################################### -## -## <#GAPDoc Label="NilpotencyDegree"> -## -## -## -## returns the least n such that every product of n elements -## in the nilpotent semigroup sgrp equals the zero element and -## returns fail if the semigroup sgrp is not nilpotent. -## s := SmallSemigroup(5, 1121);; -## gap> NilpotencyDegree(s); -## fail -## gap> s := SmallSemigroup(7, 393450);; -## gap> NilpotencyDegree(s); -## 3 -## ]]> -## Note that for size 8 a semigroup in the library with ID (8,n) is -## nilpotent of degree 3 if and only if n is greater than 11433106. -## s := SmallSemigroup(8, 11433106+1231);; -## gap> NilpotencyDegree(s); -## 3 -## gap> s := SmallSemigroup(8,NrSmallSemigroups(8));; -## gap> NilpotencyDegree(s); -## 3 -## ]]> -## -## -## <#/GAPDoc> - - -#Internal Functions -########################################################################### -## <#GAPDoc Label="IsSemigroupWithoutClosedIdempotents"> -## -## -## -## returns true if the idempotent elements of the semigroup -## sgrp do not form a subsemigroup, and false otherwise. -##

-## The reason this function exists is that almost all semigroups in the -## library have the converse property and so it is more efficient to store -## the positions of those that do not in the infon.g files. -##

-## -## -## <#/GAPDoc> +# <#GAPDoc Label="NilpotencyDegree"> +# +# +# +# returns the least n such that every product of n elements +# in the nilpotent semigroup sgrp equals the zero element and +# returns fail if the semigroup sgrp is not nilpotent. +# s := SmallSemigroup(5, 1121);; +# gap> NilpotencyDegree(s); +# fail +# gap> s := SmallSemigroup(7, 393450);; +# gap> NilpotencyDegree(s); +# 3 +# ]]> +# Note that for size 8 a semigroup in the library with ID (8,n) is +# nilpotent of degree 3 if and only if n is greater than 11433106. +# s := SmallSemigroup(8, 11433106+1231);; +# gap> NilpotencyDegree(s); +# 3 +# gap> s := SmallSemigroup(8,NrSmallSemigroups(8));; +# gap> NilpotencyDegree(s); +# 3 +# ]]> +# +# +# <#/GAPDoc> + +# <#GAPDoc Label="IsSemigroupWithoutClosedIdempotents"> +# +# +# +# returns true if the idempotent elements of the semigroup +# sgrp do not form a subsemigroup, and false otherwise. +#

+# The reason this function exists is that almost all semigroups in the +# library have the converse property and so it is more efficient to store +# the positions of those that do not in the infon.g files. +#

+# +# +# <#/GAPDoc> DeclareProperty("IsSemigroupWithoutClosedIdempotents", IsSmallSemigroup); -########################################################################### -## -## <#GAPDoc Label="SMALLSEMI_ALWAYS_FALSE"> -## -## -## -## is a global variable whose value is a list of strings str of names of properties -## or attributes that are always false for a small semigroup.

-## -## For example, is always false -## for small semigroups but -## can be true. -## SMALLSEMI_ALWAYS_FALSE; -## [ "IsFullTransformationSemigroup", "IsSingularSemigroup" ] -## ]]> -## -## -## <#/GAPDoc> - -#DeclareGlobalVariable("SMALLSEMI_ALWAYS_FALSE"); - -########################################################################### -## <#GAPDoc Label="SMALLSEMI_EQUIV"> -## -## -## -## is a global variable whose value is a list of pairs P of functions -## and values where P[1] -## is a property and value which is equivalent to the properties and values -## in P[2] for small semigroups.

-## For example, -## implies -## Is1GeneratedSemigroup for all semigroups and is -## hence a synonym and the pair [[IsMonogenicSemigroup, true], [Is1GeneratedSemigroup, true]] does -## not need to be installed in SMALLSEMI_EQUIV. On the other hand, -## only holds for -## and and -## hence is not a synonym and the pairs -## [ [IsCompletelySimpleSemigroup, true], [IsSimpleSemigroup, true]] -## and [ [IsCompletelySimpleSemigroup, false], [IsSimpleSemigroup, false]] -## -## must be entered in -## SMALLSEMI_EQUIV. Note that [[IsOrthodoxSemigroup, true], -## [IsRegularSemigroup, true, IsSemigroupWithoutClosedIdempotents, false]] -## can be entered in SMALLSEMI_EQUIV but currently it is not possible to -## have any pair in SMALLSEMI_EQUIV with first entry -## [IsOrthodoxSemigroup, false].

-## -## Also note that if P is an entry in SMALLSEMI_EQUIV, then -## P[1] must have length 2.

-## -## The reason for doing all of this is so that when -## is called with argument -## IsCompletelySimpleSemigroup there is no component in the record in the info file with -## the name "IsCompletelySimpleSemigroup" and so this name is provided by -## SMALLSEMI_EQUIV. If two properties are synonymous, then NAME_FUNC has the same -## value for both and so it is only necessary to store a component with that one name and hence -## not necessary to put a pair in SMALLSEMI_EQUIV.

-## The name of the component in the info file should be in the second component of a pair in -## SMALLSEMI_EQUIV -## SMALLSEMI_EQUIV; -## [ [ "IsCompletelySimpleSemigroup", "IsSimpleSemigroup" ], -## [ "IsCommutativeSemigroup", "IsCommutative" ], -## [ "IsNilpotent", "IsNilpotentSemigroup" ] ] -## ]]> -## -## -## <#/GAPDoc> - -#DeclareGlobalVariable("SMALLSEMI_EQUIV"); - -########################################################################### -## -## <#GAPDoc Label="STORED_INFO"> -## -## -## -## returns the value of the component of the record MOREDATA2TO8[n] with -## name the string str. This is equivalent to doing the following. -## -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="STORED_INFO"> +# +# +# +# returns the value of the component of the record MOREDATA2TO8[n] with +# name the string str. This is equivalent to doing the following. +# +# +# +# <#/GAPDoc> DeclareGlobalFunction("STORED_INFO"); + +DeclareGlobalFunction("SMALLSEMI_TableToLiterals"); +DeclareGlobalFunction("SMALLSEMI_OnLiterals"); diff --git a/gap/properties.gi b/gap/properties.gi index b5fd8af..ae6e017 100644 --- a/gap/properties.gi +++ b/gap/properties.gi @@ -1,186 +1,145 @@ ############################################################################# ## -#W properties.gi Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2014 Andreas Distler & James D. Mitchell +## properties.gi Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# ## +## The functions in this file are used to test whether a given +## small semigroup has a given property. -## The functions in this file are used to test whether a given -## small semigroup has a given property. +InstallMethod(Annihilators, "for a small semigroup", [IsSmallSemigroup], +function(sg) + local n, # size of the + mt, # multiplication table of + zero, # index of the zero element in + indices; # indices of annihilators in -InstallMethod( Annihilators, "for a small semigroup", [ IsSmallSemigroup ], -function( sg ) - local n, # size of the - mt, # multiplication table of - zero, # index of the zero element in - indices; # indices of annihilators in + # AD maybe this should run into an error or return the empty list? + if not IsSemigroupWithZero(sg) then + return fail; + fi; - # AD maybe this should run into an error or return the empty list? - if not IsSemigroupWithZero( sg ) then return fail; fi; + n := Size(sg); + mt := MultiplicationTable(sg); + zero := MultiplicativeZero(sg)!.index; - n := Size( sg ); - mt := MultiplicationTable( sg ); - zero := MultiplicativeZero( sg )!.index; - - indices := Filtered( [ 1..n ], i -> Unique( mt{[ 1..n ]}[i] ) = [ zero ] - and Unique( mt[i] ) = [ zero ] ); - - return Elements( sg ){ indices }; + indices := Filtered([1 .. n], i -> Unique(mt{[1 .. n]}[i]) = [zero] + and Unique(mt[i]) = [zero]); + return Elements(sg){indices}; end); -########################################################################### - -InstallMethod(DiagonalOfMultiplicationTable, "for a semigroup", true, -[IsSemigroup and HasIsFinite and IsFinite], 0, +InstallMethod(DiagonalOfMultiplicationTable, "for a semigroup", +[IsSemigroup and HasIsFinite and IsFinite], x -> DiagonalOfMat(MultiplicationTable(x))); -########################################################################### - -InstallGlobalFunction(DisplaySmallSemigroup, -function(s) -local id, pre, out, info, max, eval, tab; -if not IsSmallSemigroup(s) then - return fail; -fi; - -id:=IdSmallSemigroup(s); -# collect function names for display -info:=Concatenation(PrecomputedSmallSemisInfo[id[1]], - ["IsSemigroupWithClosedIdempotents", - "IsMonogenicSemigroup", - "IsRectangularBand", - "IsOrthodoxSemigroup", - "IsBrandtSemigroup"]); - -# delete those that we do not want to display, sort alphabetically -info:=Difference(info,["IsSemigroupWithoutClosedIdempotents", - "Is1GeneratedSemigroup", - "Is2GeneratedSemigroup", - "Is3GeneratedSemigroup", - "Is4GeneratedSemigroup", - "Is5GeneratedSemigroup", - "Is6GeneratedSemigroup", - "Is7GeneratedSemigroup", - "Is8GeneratedSemigroup"]); - -# glue things at the end of the display -info := Concatenation( info, [ "MinimalGeneratingSet", "Idempotents", - "GreensRClasses","GreensLClasses", - "GreensHClasses","GreensDClasses"] ); - -out:=[]; -max:=Maximum(List(info, Length)); - -for pre in info do - eval:=EvalString(pre)(s); - tab:=Concatenation(List([1..(max-Length(pre))+3], x-> " ")); - Add(out, Concatenation(pre, ":", tab, String(eval), "\n")); -od; - -Print(Concatenation(out)); -end); - -############################################################################# - -InstallMethod( Idempotents, "for a small semigroup", [IsSmallSemigroup], -function(s) - local i, idems; - - idems := EmptyPlist( 1 ); - for i in [ 1..Size(s) ] do - if MultiplicationTable(s)[i][i] = i then Add(idems,i); fi; - od; - - return Elements(s){idems}; -end); - - -############################################################################# - -InstallMethod(IndexPeriod, "for a small semigroup elt", true, [IsSmallSemigroupElt], 0, +InstallGlobalFunction(DisplaySmallSemigroup, +function(S) + local id, info, out, max, eval, tab, pre; + + if not IsSmallSemigroup(S) then + return fail; + fi; + + id := IdSmallSemigroup(S); + # collect function names for display + info := Concatenation(PrecomputedSmallSemisInfo[id[1]], + ["IsSemigroupWithClosedIdempotents", + "IsMonogenicSemigroup", + "IsRectangularBand", + "IsOrthodoxSemigroup", + "IsBrandtSemigroup"]); + + # delete those that we do not want to display, sort alphabetically + info := Difference(info, ["IsSemigroupWithoutClosedIdempotents", + "Is1GeneratedSemigroup", + "Is2GeneratedSemigroup", + "Is3GeneratedSemigroup", + "Is4GeneratedSemigroup", + "Is5GeneratedSemigroup", + "Is6GeneratedSemigroup", + "Is7GeneratedSemigroup", + "Is8GeneratedSemigroup"]); + + # glue things at the end of the display + info := Concatenation(info, ["MinimalGeneratingSet", "Idempotents", + "GreensRClasses", "GreensLClasses", + "GreensHClasses", "GreensDClasses"]); + + out := []; + max := Maximum(List(info, Length)); + + for pre in info do + eval := ValueGlobal(pre)(S); + tab := Concatenation(List([1 .. (max - Length(pre)) + 3], x -> " ")); + Add(out, Concatenation(pre, ":", tab, String(eval), "\n")); + od; + + Print(Concatenation(out)); +end); + +InstallMethod(Idempotents, "for a small semigroup", [IsSmallSemigroup], +S -> Filtered(S, IsIdempotent)); + +# TODO improve this method +InstallMethod(IndexPeriod, "for a small semigroup element", +[IsSmallSemigroupElt], function(x) -local i, y, m, powers; + local i, y, m, powers; -i:=1; -y:=x; -powers:=[y]; + i := 1; + y := x; + powers := [y]; -repeat - i:=i+1; - y:=y*x; - Add(powers, y); -until not IsDuplicateFreeList(powers); + repeat + i := i + 1; + y := y * x; + Add(powers, y); + until not IsDuplicateFreeList(powers); -m:=Position(powers, powers[i]); + m := Position(powers, powers[i]); -return [m, Length(powers)-m]; + return [m, Length(powers) - m]; end); - -########################################################################### - - InstallMethod(IsBand, "for a small semigroup", -true, [IsSmallSemigroup], 0, -function(s) - -if HasIsCompletelyRegularSemigroup(s) and not IsCompletelyRegularSemigroup(s) then - return false; -else - return DiagonalOfMat(s!.table)=[1..Size(s)]; -fi; -end); - -########################################################################### - -InstallMethod(IsBrandtSemigroup, "for a small semigroup", -true, [IsSmallSemigroup], 0, +[IsSmallSemigroup], function(s) - -if HasIsInverseSemigroup(s) and not IsInverseSemigroup(s) then - return false; -elif HasIsZeroSimpleSemigroup(s) and not IsZeroSimpleSemigroup(s) then - return false; -fi; - -return IsInverseSemigroup(s) and IsZeroSimpleSemigroup(s); -end); - -########################################################################### - -InstallMethod(IsCliffordSemigroup, "for a small semigroup", true, [IsSmallSemigroup], 0, -function(M) - -if HasIsInverseSemigroup(M) and not IsInverseSemigroup(M) then - return false; -elif HasIsRegularSemigroup(M) and not IsRegularSemigroup(M) then - return false; -elif HasIsCompletelyRegularSemigroup(M) and not IsCompletelyRegularSemigroup(M) then - return false; -elif HasIsGroupAsSemigroup(M) and IsGroupAsSemigroup(M) then - return true; -else - if ForAll(Idempotents(M), x-> x in Center(M)) then - return IsRegularSemigroup(M); - fi; -fi; - -return false; - + if HasIsCompletelyRegularSemigroup(s) + and not IsCompletelyRegularSemigroup(s) then + return false; + fi; + return DiagonalOfMat(s!.table) = [1 .. Size(s)]; end); -########################################################################### +InstallMethod(IsBrandtSemigroup, "for a small semigroup", +[IsSmallSemigroup], +S -> IsInverseSemigroup(S) and IsZeroSimpleSemigroup(S)); -InstallMethod(IsCommutativeSemigroup, "for a small semigroup", true, [IsSmallSemigroup], 0, -function(M) -return IsCommutative(M); +InstallMethod(IsCliffordSemigroup, "for a small semigroup", +[IsSmallSemigroup], +function(S) + if HasIsInverseSemigroup(S) and not IsInverseSemigroup(S) then + return false; + elif HasIsRegularSemigroup(S) and not IsRegularSemigroup(S) then + return false; + elif HasIsCompletelyRegularSemigroup(S) + and not IsCompletelyRegularSemigroup(S) then + return false; + elif HasIsGroupAsSemigroup(S) and IsGroupAsSemigroup(S) then + return true; + fi; + if ForAll(Idempotents(S), x -> x in Center(S)) then + return IsRegularSemigroup(S); + fi; + return false; end); -########################################################################### +InstallMethod(IsCommutativeSemigroup, "for a small semigroup", +[IsSmallSemigroup], IsCommutative); InstallMethod(IsCompletelySimpleSemigroup, "for a small semigroup", [IsSmallSemigroup], IsSimpleSemigroup); @@ -188,337 +147,178 @@ InstallMethod(IsCompletelySimpleSemigroup, "for a small semigroup", InstallMethod(IsSemiband, "for a small semigroup", [IsSmallSemigroup], IsIdempotentGenerated); -InstallMethod(IsSemilattice, "for a small semigroup", -[IsSmallSemigroup], s-> IsCommutative(s) and IsBand(s)); - -########################################################################### - -InstallMethod( IsCompletelyRegularSemigroup, "for a small semigroup", true, [IsSmallSemigroup], 0, -function(M) - -if HasIsRegularSemigroup(M) and not IsRegularSemigroup(M) then - return false; -elif IsRegularSemigroup(M) then - return Length(GreensHClasses(M))=Length(Idempotents(M)); -fi; - -return false; -end); - -########################################################################### - -InstallMethod(IsFullTransformationSemigroupCopy, "for a small semigroup", -[IsSmallSemigroup], function(s) - return IdSmallSemigroup(s)=[4,96] or IdSmallSemigroup(s)=[1,1]; -end); - +InstallMethod(IsSemilattice, "for a small semigroup", +[IsSmallSemigroup], S -> IsCommutative(S) and IsBand(S)); -########################################################################### - -InstallMethod(IsGroupAsSemigroup, "for a small semigroup", true, [IsSmallSemigroup], 0, -function(s) -local table, id; +InstallMethod(IsCompletelyRegularSemigroup, "for a small semigroup", +[IsSmallSemigroup], +function(S) -id:=IdSmallSemigroup(s); + if HasIsRegularSemigroup(S) and not IsRegularSemigroup(S) then + return false; + elif IsRegularSemigroup(S) then + return Length(GreensHClasses(S)) = Length(Idempotents(S)); + fi; -table:=ShallowCopy(MultiplicationTable(s)); -if not (ForAll(table, x-> AsSet(x)=[1..Size(s)]) - and ForAll(TransposedMat(table), x-> AsSet(x)=[1..Size(s)])) then return false; -fi; - -SetIsRegularSemigroup(s, true); -SetIsSimpleSemigroup(s, true); -SetIsCompletelyRegularSemigroup(s, true); -SetIsCliffordSemigroup(s, true); -if Size(s)>1 then - SetIsRectangularBand(s, false); -else - SetIsRectangularBand(s, true); -fi; -return true; end); -########################################################################### +InstallMethod(IsFullTransformationSemigroupCopy, "for a small semigroup", +[IsSmallSemigroup], +S -> IdSmallSemigroup(S) = [4, 96] or IdSmallSemigroup(S) = [1, 1]); -InstallMethod(IsIdempotentGenerated, "for a small semigroup", -true, [IsSmallSemigroup], 0, function(S) +InstallMethod(IsGroupAsSemigroup, "for a small semigroup", [IsSmallSemigroup], +function(S) + local table; - # semigroup contains only idempotents - if IsBand(S) then - return true; - # in a nilpotent semigroup zero does not generate the semigroup + table := ShallowCopy(MultiplicationTable(S)); + if ForAny(table, x -> AsSet(x) <> [1 .. Size(S)]) + or ForAny(TransposedMat(table), x -> AsSet(x) <> [1 .. Size(S)]) then + return false; + fi; + + SetIsRegularSemigroup(S, true); + SetIsSimpleSemigroup(S, true); + SetIsCompletelyRegularSemigroup(S, true); + SetIsCliffordSemigroup(S, true); + if Size(S) > 1 then + SetIsRectangularBand(S, false); + else + SetIsRectangularBand(S, true); + fi; + return true; +end); + +InstallMethod(IsIdempotentGenerated, "for a small semigroup", +[IsSmallSemigroup], +function(S) + if IsBand(S) then + return true; + elif IsNilpotentSemigroup(S) then + # in a nilpotent semigroup zero does not generate the semigroup # (except if size is 1, but then it is already a band) - elif IsNilpotentSemigroup(S) then - return false; - fi; + return false; + fi; - return Size(Semigroup(Idempotents(S)))=Size(S); + return Size(Semigroup(Idempotents(S))) = Size(S); end); -########################################################################### -#JDM is the `other' required here? - -InstallMethod(IsInverseSemigroup, "for a small semigroup", -true, [IsSmallSemigroup], 0, -function(M) -local i, j, idem; - -if HasIsCliffordSemigroup(M) and IsCliffordSemigroup(M) then - return true; -elif IsRegularSemigroup(M) then -idem:=Idempotents(M); - -for i in [1..Length(idem)] do - for j in [i+1..Length(idem)] do - if not idem[i]*idem[j]=idem[j]*idem[i] then - return false; - fi; - od; -od; -return true; -fi; +InstallMethod(IsInverseSemigroup, "for a small semigroup", +[IsSmallSemigroup], +function(S) + local i, j, idem; -return false; + if HasIsCliffordSemigroup(S) and IsCliffordSemigroup(S) then + return true; + elif IsRegularSemigroup(S) then + idem := Idempotents(S); -end); + for i in [1 .. Length(idem)] do + for j in [i + 1 .. Length(idem)] do + if not idem[i] * idem[j] = idem[j] * idem[i] then + return false; + fi; + od; + od; + return true; + fi; -########################################################################### + return false; +end); -InstallMethod(IsLeftZeroSemigroup, "for a small semigroup", -true, [IsSmallSemigroup], 0, +InstallMethod(IsLeftZeroSemigroup, "for a small semigroup", +[IsSmallSemigroup], function(S) - local table, i, j; - - table := MultiplicationTable( S ); - for i in [ 1..Size(S) ] do - for j in [ 1..Size(S) ] do - # for every entry test whether it equals its row index - if table[i][j] <> i then - return false; - fi; - od; + local table, i, j; + + table := MultiplicationTable(S); + for i in [1 .. Size(S)] do + for j in [1 .. Size(S)] do + # for every entry test whether it equals its row index + if table[i][j] <> i then + return false; + fi; od; + od; - return true; + return true; end); -################### - -InstallMethod(IsMonoidAsSemigroup, "for a small semigroup", true, [IsSmallSemigroup], 0, +InstallMethod(IsMonoidAsSemigroup, "for a small semigroup", [IsSmallSemigroup], function(S) -local table, id, pos; + local table, id, pos; -table:=MultiplicationTable(S); -id:=IdSmallSemigroup(S); + table := MultiplicationTable(S); + id := IdSmallSemigroup(S); -pos:=Position(table, [1..id[1]]); + pos := Position(table, [1 .. id[1]]); -if not pos=fail then - return List(table, x-> x[pos])=[1..id[1]]; -fi; + if pos <> fail then + return List(table, x -> x[pos]) = [1 .. id[1]]; + fi; -return false; + return false; end); -################### - -InstallMethod(IsMultSemigroupOfNearRing, "for a small semigroup", true, -[IsSmallSemigroup], 0, +InstallMethod(IsMultSemigroupOfNearRing, "for a small semigroup", +[IsSmallSemigroup], function(s) - local id, vals; + local id, vals; - id := IdSmallSemigroup(s); - vals := STORED_INFO( id[1], "IsMultSemigroupOfNearRing" ); + id := IdSmallSemigroup(s); + vals := STORED_INFO(id[1], "IsMultSemigroupOfNearRing"); - if id[2] in vals then - return true; - else - return false; - fi; + return id[2] in vals; end); +InstallMethod(IsNGeneratedSemigroup, "for a small semigroup and a pos. int", +[IsSmallSemigroup, IsPosInt], +function(S, n) + local id, funcname, idlist, result, IsMGenerated, M; -######################### - -InstallMethod(IsNGeneratedSemigroup, "for a small semigroup and a pos. int", -[IsSmallSemigroup, IsPosInt], function(S, n) - local id, funcname, idlist; - - id:=IdSmallSemigroup(S); - - if n > id[1] then - return false; - fi; - - funcname := Concatenation("Is",String(n),"GeneratedSemigroup"); - - idlist := STORED_INFO( id[1], funcname ); - - if not idlist=fail then - return id[2] in idlist; - else - return Length(MinimalGeneratingSet(S))=n; - fi; -end); - -######################### - -InstallMethod(Is1GeneratedSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNGeneratedSemigroup(S, 1); -if out then - SetIs2GeneratedSemigroup(S, false); - SetIs3GeneratedSemigroup(S, false); - SetIs4GeneratedSemigroup(S, false); - SetIs5GeneratedSemigroup(S, false); - SetIs6GeneratedSemigroup(S, false); - SetIs7GeneratedSemigroup(S, false); - SetIs8GeneratedSemigroup(S, false); -fi; -return out; -end); - -######################### - -InstallMethod(Is2GeneratedSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNGeneratedSemigroup(S, 2); -if out then - SetIs1GeneratedSemigroup(S, false); - SetIs3GeneratedSemigroup(S, false); - SetIs4GeneratedSemigroup(S, false); - SetIs5GeneratedSemigroup(S, false); - SetIs6GeneratedSemigroup(S, false); - SetIs7GeneratedSemigroup(S, false); - SetIs8GeneratedSemigroup(S, false); -fi; -return out; -end); - -######################### - -InstallMethod(Is3GeneratedSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNGeneratedSemigroup(S, 3); -if out then - SetIs1GeneratedSemigroup(S, false); - SetIs2GeneratedSemigroup(S, false); - SetIs4GeneratedSemigroup(S, false); - SetIs5GeneratedSemigroup(S, false); - SetIs6GeneratedSemigroup(S, false); - SetIs7GeneratedSemigroup(S, false); - SetIs8GeneratedSemigroup(S, false); -fi; -return out; -end); + id := IdSmallSemigroup(S); -######################### - -InstallMethod(Is4GeneratedSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNGeneratedSemigroup(S, 4); -if out then - SetIs1GeneratedSemigroup(S, false); - SetIs2GeneratedSemigroup(S, false); - SetIs3GeneratedSemigroup(S, false); - SetIs5GeneratedSemigroup(S, false); - SetIs6GeneratedSemigroup(S, false); - SetIs7GeneratedSemigroup(S, false); - SetIs8GeneratedSemigroup(S, false); -fi; -return out; -end); + if n > id[1] then + return false; + fi; -######################### - -InstallMethod(Is5GeneratedSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNGeneratedSemigroup(S, 5); -if out then - SetIs1GeneratedSemigroup(S, false); - SetIs2GeneratedSemigroup(S, false); - SetIs3GeneratedSemigroup(S, false); - SetIs4GeneratedSemigroup(S, false); - SetIs6GeneratedSemigroup(S, false); - SetIs7GeneratedSemigroup(S, false); - SetIs8GeneratedSemigroup(S, false); -fi; -return out; -end); + funcname := Concatenation("Is", String(n), "GeneratedSemigroup"); + idlist := STORED_INFO(id[1], funcname); -######################### - -InstallMethod(Is6GeneratedSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNGeneratedSemigroup(S, 6); -if out then - SetIs1GeneratedSemigroup(S, false); - SetIs2GeneratedSemigroup(S, false); - SetIs3GeneratedSemigroup(S, false); - SetIs4GeneratedSemigroup(S, false); - SetIs5GeneratedSemigroup(S, false); - SetIs7GeneratedSemigroup(S, false); - SetIs8GeneratedSemigroup(S, false); -fi; -return out; -end); + if idlist <> fail then + result := id[2] in idlist; + else + result := Length(MinimalGeneratingSet(S)) = n; + fi; -######################### - -InstallMethod(Is7GeneratedSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNGeneratedSemigroup(S, 7); -if out then - SetIs1GeneratedSemigroup(S, false); - SetIs2GeneratedSemigroup(S, false); - SetIs3GeneratedSemigroup(S, false); - SetIs4GeneratedSemigroup(S, false); - SetIs5GeneratedSemigroup(S, false); - SetIs6GeneratedSemigroup(S, false); - SetIs8GeneratedSemigroup(S, false); -fi; -return out; + if result then + for M in [1 .. n - 1] do + IsMGenerated := ValueGlobal(StringFormatted("Is{}GeneratedSemigroup", M)); + Setter(IsMGenerated)(S, false); + od; + for M in [n + 1 .. 8] do + IsMGenerated := ValueGlobal(StringFormatted("Is{}GeneratedSemigroup", M)); + Setter(IsMGenerated)(S, false); + od; + fi; + return result; end); -######################### - -InstallMethod(Is8GeneratedSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNGeneratedSemigroup(S, 8); -if out then - SetIs1GeneratedSemigroup(S, false); - SetIs2GeneratedSemigroup(S, false); - SetIs3GeneratedSemigroup(S, false); - SetIs4GeneratedSemigroup(S, false); - SetIs5GeneratedSemigroup(S, false); - SetIs6GeneratedSemigroup(S, false); - SetIs7GeneratedSemigroup(S, false); -fi; -return out; +BindGlobal("InstallIsNGenerated", +function(N) + local IsNGenerated; + IsNGenerated := ValueGlobal(StringFormatted("Is{}GeneratedSemigroup", N)); + InstallMethod(IsNGenerated, "for a small semigroup", + [IsSmallSemigroup], S -> IsNGeneratedSemigroup(S, N)); end); -######################### -######################### -######################### +for N in [1 .. 8] do + InstallIsNGenerated(N); +od; +MakeReadWriteGlobal("InstallIsNGenerated"); +Unbind(InstallIsNGenerated); +Unbind(N); -########################################################################### # Is there really a point in having IsIdempotentSemigroup functions # if they don't do something more clever than calling Length(Idempotents)? # (It's not needed for enumerator etc., is it?) @@ -526,849 +326,600 @@ end); # Besides, storing of the values should probably behave in a different way. # The values for IsIdempotentSemigroup are at the moment not known after # calling IsNIdempotentSemigroup (compare maybe MovedPoints vs. NrMovedPoints -# for Permutations). -# -InstallMethod(IsNIdempotentSemigroup, "for a small semigroup and a pos. int", -true, [IsSmallSemigroup, IsPosInt], 0, +# for Permutations). +InstallMethod(IsNIdempotentSemigroup, "for a small semigroup and a pos. int", +[IsSmallSemigroup, IsPosInt], function(S, n) + local result, IsMIdempotent, M; -if n>Size(S) then - return false; -fi; - -if IsBand(S) then - if n=Size(S) then - return true; - fi; - return false; -fi; - -return Length(Idempotents(S))=n; -end); - -######################### - -InstallMethod(Is1IdempotentSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNIdempotentSemigroup(S, 1); -if out then - SetIs2IdempotentSemigroup(S, false); - SetIs3IdempotentSemigroup(S, false); - SetIs4IdempotentSemigroup(S, false); - SetIs5IdempotentSemigroup(S, false); - SetIs6IdempotentSemigroup(S, false); - SetIs7IdempotentSemigroup(S, false); - SetIs8IdempotentSemigroup(S, false); -fi; -return out; -end); - -######################### - -InstallMethod(Is2IdempotentSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNIdempotentSemigroup(S, 2); -if out then - SetIs1IdempotentSemigroup(S, false); - SetIs3IdempotentSemigroup(S, false); - SetIs4IdempotentSemigroup(S, false); - SetIs5IdempotentSemigroup(S, false); - SetIs6IdempotentSemigroup(S, false); - SetIs7IdempotentSemigroup(S, false); - SetIs8IdempotentSemigroup(S, false); -fi; -return out; -end); - -######################### - -InstallMethod(Is3IdempotentSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNIdempotentSemigroup(S, 3); -if out then - SetIs2IdempotentSemigroup(S, false); - SetIs1IdempotentSemigroup(S, false); - SetIs4IdempotentSemigroup(S, false); - SetIs5IdempotentSemigroup(S, false); - SetIs6IdempotentSemigroup(S, false); - SetIs7IdempotentSemigroup(S, false); - SetIs8IdempotentSemigroup(S, false); -fi; -return out; -end); - -######################### - -InstallMethod(Is4IdempotentSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNIdempotentSemigroup(S, 4); -if out then - SetIs2IdempotentSemigroup(S, false); - SetIs3IdempotentSemigroup(S, false); - SetIs1IdempotentSemigroup(S, false); - SetIs5IdempotentSemigroup(S, false); - SetIs6IdempotentSemigroup(S, false); - SetIs7IdempotentSemigroup(S, false); - SetIs8IdempotentSemigroup(S, false); -fi; -return out; -end); - -######################### - -InstallMethod(Is5IdempotentSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNIdempotentSemigroup(S, 5); -if out then - SetIs2IdempotentSemigroup(S, false); - SetIs3IdempotentSemigroup(S, false); - SetIs4IdempotentSemigroup(S, false); - SetIs1IdempotentSemigroup(S, false); - SetIs6IdempotentSemigroup(S, false); - SetIs7IdempotentSemigroup(S, false); - SetIs8IdempotentSemigroup(S, false); -fi; -return out; -end); - -######################### - -InstallMethod(Is6IdempotentSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNIdempotentSemigroup(S, 6); -if out then - SetIs2IdempotentSemigroup(S, false); - SetIs3IdempotentSemigroup(S, false); - SetIs4IdempotentSemigroup(S, false); - SetIs5IdempotentSemigroup(S, false); - SetIs1IdempotentSemigroup(S, false); - SetIs7IdempotentSemigroup(S, false); - SetIs8IdempotentSemigroup(S, false); -fi; -return out; -end); + if n > Size(S) then + return false; + fi; + + result := (IsBand(S) and n = Size(S)) or Length(Idempotents(S)) = n; + if result then + for M in [1 .. n - 1] do + IsMIdempotent := + ValueGlobal(StringFormatted("Is{}IdempotentSemigroup", M)); + Setter(IsMIdempotent)(S, false); + od; + for M in [n + 1 .. 8] do + IsMIdempotent := + ValueGlobal(StringFormatted("Is{}IdempotentSemigroup", M)); + Setter(IsMIdempotent)(S, false); + od; + fi; -######################### - -InstallMethod(Is7IdempotentSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNIdempotentSemigroup(S, 7); -if out then - SetIs2IdempotentSemigroup(S, false); - SetIs3IdempotentSemigroup(S, false); - SetIs4IdempotentSemigroup(S, false); - SetIs5IdempotentSemigroup(S, false); - SetIs6IdempotentSemigroup(S, false); - SetIs1IdempotentSemigroup(S, false); - SetIs8IdempotentSemigroup(S, false); -fi; -return out; + return result; end); -######################### - -InstallMethod(Is8IdempotentSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, function(S) -local out; - -out:=IsNIdempotentSemigroup(S, 8); -if out then - SetIs2IdempotentSemigroup(S, false); - SetIs3IdempotentSemigroup(S, false); - SetIs4IdempotentSemigroup(S, false); - SetIs5IdempotentSemigroup(S, false); - SetIs6IdempotentSemigroup(S, false); - SetIs7IdempotentSemigroup(S, false); - SetIs1IdempotentSemigroup(S, false); -fi; -return out; +BindGlobal("InstallIsNIdempotent", +function(N) + local IsNIdempotent; + IsNIdempotent := ValueGlobal(StringFormatted("Is{}IdempotentSemigroup", N)); + InstallMethod(IsNIdempotent, "for a small semigroup", + [IsSmallSemigroup], S -> IsNIdempotentSemigroup(S, N)); end); -######################### -######################### -######################### +for N in [1 .. 8] do + InstallIsNIdempotent(N); +od; +MakeReadWriteGlobal("InstallIsNIdempotent"); +Unbind(InstallIsNIdempotent); +Unbind(N); -InstallMethod(IsNilpotent, "for a small semigroup", true, [IsSmallSemigroup], +InstallMethod(IsNilpotent, "for a small semigroup", [IsSmallSemigroup], IsNilpotentSemigroup); -InstallMethod(IsNilpotentSemigroup,"for a small semigroup",[IsSmallSemigroup], -function( S ) - - if ForAll( [2..Size(S)], i -> MultiplicationTable( S )[i][i] <> i ) and - IsSemigroupWithZero( S ) then - return true; - else - return false; - fi; +InstallMethod(IsNilpotentSemigroup, "for a small semigroup", [IsSmallSemigroup], +function(S) + return ForAll([2 .. Size(S)], i -> MultiplicationTable(S)[i][i] <> i) + and IsSemigroupWithZero(S); end); -########################################################################### - InstallTrueMethod(IsOrthodoxSemigroup, IsSemigroupWithClosedIdempotents and IsRegularSemigroup); InstallMethod(IsOrthodoxSemigroup, "for a semigroup", [IsSemigroup], -function(s) - return IsSemigroupWithClosedIdempotents(s) and IsRegularSemigroup(s); -end); +S -> IsSemigroupWithClosedIdempotents(S) and IsRegularSemigroup(S)); -########################################################################### - -InstallMethod(IsRectangularBand, "for a small semigroup", -true, [IsSmallSemigroup], 0, -function(s) -return IsBand(s) and IsSimpleSemigroup(s); -end); - -########################################################################### - -InstallMethod(IsRegularSemigroup, "for a small semigroup", true, [IsSmallSemigroup], 0, -function ( s ) - -if HasIsCompletelyRegularSemigroup(s) and IsCompletelyRegularSemigroup(s) then - return true; -elif HasIsGroupAsSemigroup(s) and IsGroupAsSemigroup(s) then - return true; -elif IsBand(s) then - return true; -else - return ForAll(GreensRClasses(s), x-> ForAny(Idempotents(s), y-> y in x)); -fi; - -end); - -########################################################################### -# no semigroup in smallsemi is right zero, keep code for change of methods to -# be applicable to every semigroup with multiplication table -# - -InstallMethod(IsRightZeroSemigroup, "for a small semigroup", -[IsSmallSemigroup], function(s) - - Info(InfoSmallsemi, 1, "Semigroups are stored up to isomorphism ", - "and anti-isomorphism in Smallsemi"); - Info(InfoSmallsemi, 1, - "and there are only left zero semigroups in the library."); - - return false; -end); - -#true, [IsSmallSemigroup], 0, -#function(S) -# local table, i, j; -# -# table := MultiplicationTable( S ); -# for i in [ 1..Size(S) ] do -# for j in [ 1..Size(S) ] do -# # for every entry test whether it equals its column index -# if table[i][j] <> j then -# return false; -# fi; -# od; -# od; -# -# return true; -#end); - -########################################################################### - -InstallMethod(IsSemigroupWithClosedIdempotents, "for a small semigroup", -true, [IsSmallSemigroup], 0, -function(s) - local idems, i, j; - - if HasIsBand(s) and IsBand(s) then - return true; - fi; - - if HasIsNilpotentSemigroup(s) and IsNilpotentSemigroup(s) then - return true; - fi; - - # most likely one idempotent - idems := EmptyPlist(1); - for i in [ 1..Size(s) ] do - if MultiplicationTable(s)[i][i] = i then Add(idems,i); fi; - od; - - # AD the following seems natural but slows down the computation by a factor - # AD of 4. To have a separate call to 'Idempotents' if necessary seems the - # AD better solution. - #SetIdempotents( s, AsSSotedList(s){idems} ); - - for i in idems do - for j in idems do - if i <> j and not MultiplicationTable(s)[i][j] in idems then - return false; - fi; - od; - od; +InstallMethod(IsRectangularBand, "for a small semigroup", +[IsSmallSemigroup], S -> IsBand(S) and IsSimpleSemigroup(S)); +InstallMethod(IsRegularSemigroup, "for a small semigroup", [IsSmallSemigroup], +function(S) + if HasIsCompletelyRegularSemigroup(S) and IsCompletelyRegularSemigroup(S) then return true; + elif HasIsGroupAsSemigroup(S) and IsGroupAsSemigroup(S) then + return true; + elif IsBand(S) then + return true; + fi; + return ForAll(GreensRClasses(S), x -> ForAny(Idempotents(S), y -> y in x)); end); -########################################################################### - -InstallMethod(IsSemigroupWithoutClosedIdempotents, "for a small semigroup", -true, [IsSmallSemigroup], 0, -function(s) +# No semigroup in smallsemi is right zero, keep code for change of methods to +# be applicable to every semigroup with multiplication table. -return not IsSemigroupWithClosedIdempotents(s); +InstallMethod(IsRightZeroSemigroup, "for a small semigroup", +[IsSmallSemigroup], +function(_) + Info(InfoSmallsemi, 1, "Semigroups are stored up to isomorphism ", + "and anti-isomorphism in Smallsemi"); + Info(InfoSmallsemi, 1, + "and there are only left zero semigroups in the library."); + return false; end); -########################################################################### +InstallMethod(IsSemigroupWithClosedIdempotents, "for a small semigroup", +[IsSmallSemigroup], +function(S) + local table, idems, lookup, i, j; -InstallMethod(IsSemigroupWithZero, "for a small semigroup", [IsSmallSemigroup], -function(s) - local i, hasleftzero; - - hasleftzero := false; - # search for a left zero - for i in [ 1..Size(s) ] do - if ForAll([ 1..Size(s) ], j -> MultiplicationTable(s)[i][j] = i) then - hasleftzero := true; - break; + if HasIsBand(S) and IsBand(S) then + return true; + elif HasIsNilpotentSemigroup(S) and IsNilpotentSemigroup(S) then + return true; + fi; + + table := MultiplicationTable(S); + idems := Filtered([1 .. Size(S)], i -> table[i][i] = i); + lookup := BlistList([1 .. Size(S)], idems); + + # AD the following seems natural but slows down the computation by a factor + # AD of 4. To have a separate call to 'Idempotents' if necessary seems the + # AD better solution. + # SetIdempotents(S, AsSSortedList(S){idems}); + + for i in idems do + for j in idems do + if i <> j then + if not lookup[table[i][j]] then + return false; fi; + fi; od; - - if hasleftzero then - # test whether the left zero is as well a right zero - return ForAll([ 1..Size(s) ], j -> MultiplicationTable(s)[j][i] = i); - else - # there is no left zero - return false; - fi; + od; + return true; end); -# # get idempotent elements -> possible zeros -# idems := EmptyPlist(1); -# for i in [ 1..Size(s) ] do -# if MultiplicationTable(s)[i][i] = i then Add(idems,i); fi; -# od; -# -# # idempotent is zero if all entries in row and column are equal to it -# for id in idems do -# bool := true; -# for i in [ 1..Size(s) ] do -# od; -# if bool then return true; fi; -# od; -# -# return false; -#end); +InstallMethod(IsSemigroupWithoutClosedIdempotents, "for a small semigroup", +[IsSmallSemigroup], S -> not IsSemigroupWithClosedIdempotents(S)); -############################################################################# - -InstallMethod( IsSelfDualSemigroup, "for a small semigroup", - [ IsSmallSemigroup ], function( S ) - local orbit,NumLit,tbl2lits,onLiterals,n,LitNum,phi,literals,vals; - - LitNum := function(ln, n) - return [QuoInt(ln-1,n^2)+1,QuoInt((ln-1) mod n^2,n)+1,(ln-1) mod n+1]; - end; - - NumLit := function(lit,n) - local row,col, val; - row := lit[1]; - col := lit[2]; - val := lit[3]; - return val+(row-1)*n^2+(col-1)*n; - end; - - tbl2lits := function(table,n) - local i,j,literals, val; - literals := []; - for i in [1..n] do - for j in [1..n] do - val := table[i][j]; - Add(literals, NumLit([i,j,val],n)); - od; - od; - - return literals; - end; - - onLiterals := n->function(ln,pi) - local lit,imlit; - lit := LitNum(ln,n); - imlit := OnTuples(lit,pi); - if (n+1)^pi = n+2 then - imlit := Permuted(imlit,(1,2)); - fi; - return NumLit(imlit,n); - end; - - n := Size( S ); - vals := STORED_INFO( n, "IsSelfDualSemigroup" ); - if vals = fail then - if IsCommutativeSemigroup( S ) then - return true; - fi; - phi := ActionHomomorphism(SymmetricGroup(n),[1..n^3],onLiterals(n)); - literals := tbl2lits( MultiplicationTable( S ), n ); - orbit := Orbit( Image( phi, SymmetricGroup( n ) ), literals, OnSets ); - - if tbl2lits(TransposedMat(MultiplicationTable( S )), n) in orbit then - return true; - else - return false; - fi; - else - return IdSmallSemigroup(S)[2] in vals; +InstallMethod(IsSemigroupWithZero, "for a small semigroup", [IsSmallSemigroup], +function(S) + local i, hasleftzero; + + hasleftzero := false; + # search for a left zero + for i in [1 .. Size(S)] do + if ForAll([1 .. Size(S)], j -> MultiplicationTable(S)[i][j] = i) then + hasleftzero := true; + break; fi; -end); - -########################################################################### - -InstallMethod( IsSimpleSemigroup, "for a small semigroup", true, [IsSmallSemigroup], 0, -function(M) - -if IsGroupAsSemigroup(M) then - return true; -elif HasIsCompletelyRegularSemigroup(M) and not IsCompletelyRegularSemigroup(M) then - return false; -fi; - -if Length(GreensDClasses(M))=1 then - SetIsCompletelyRegularSemigroup(M,true); - SetIsRegularSemigroup(M, true); - return true; -fi; - -return false; + od; + if hasleftzero then + # test whether the left zero is as well a right zero + return ForAll([1 .. Size(S)], j -> MultiplicationTable(S)[j][i] = i); + fi; + # there is no left zero + return false; end); -########################################################################### - -InstallMethod(IsSingularSemigroupCopy, "for a small semigroup", -[IsSmallSemigroup], function(s) - return IdSmallSemigroup(s)=[2,4]; +InstallGlobalFunction(SMALLSEMI_TableToLiterals, +function(table, n, NumLit) + local i, j, literals, val; + literals := []; + for i in [1 .. n] do + for j in [1 .. n] do + val := table[i][j]; + Add(literals, NumLit([i, j, val], n)); + od; + od; + return literals; end); -########################################################################### - -#JDM the following method could surely be better - -InstallMethod(IsZeroGroup, "for a small semigroup", true, [IsSmallSemigroup], 0, -function(s) -local zero, elts; - -zero:=MultiplicativeZero(s); -if not zero=fail then - elts:=Difference(Elements(s), [zero]); - return IsGroupAsSemigroup(SmallSemigroup(IdSmallSemigroup(Semigroup(elts)))); -fi; #JDM the previous line is a good example of why IsomorphismSmallSemigroup is required - # AD shouldn't this rather be something like: - # AD return fail <> AsGroup( elts ); -return false; - +InstallGlobalFunction(SMALLSEMI_OnLiterals, +{n, LitNum, NumLit} -> function(ln, pi) + local lit, imlit; + lit := LitNum(ln, n); + imlit := OnTuples(lit, pi); + if (n + 1) ^ pi = n + 2 then + imlit := Permuted(imlit, (1, 2)); + fi; + return NumLit(imlit, n); end); -########################################################################### +InstallMethod(IsSelfDualSemigroup, "for a small semigroup", +[IsSmallSemigroup], +function(S) + local orbit, NumLit, tbl2lits, onLiterals, n, LitNum, phi, literals, vals; + + LitNum := {ln, n} -> [QuoInt(ln - 1, n ^ 2) + 1, + QuoInt((ln - 1) mod n ^ 2, n) + 1, + (ln - 1) mod n + 1]; + + NumLit := function(lit, n) + local row, col, val; + row := lit[1]; + col := lit[2]; + val := lit[3]; + return val + (row - 1) * n ^ 2 + (col - 1) * n; + end; + + tbl2lits := {table, n} -> SMALLSEMI_TableToLiterals(table, n, NumLit); + onLiterals := n -> SMALLSEMI_OnLiterals(n, LitNum, NumLit); + + n := Size(S); + vals := STORED_INFO(n, "IsSelfDualSemigroup"); + if vals <> fail then + return IdSmallSemigroup(S)[2] in vals; + fi; + + if IsCommutativeSemigroup(S) then + return true; + fi; + phi := ActionHomomorphism(SymmetricGroup(n), [1 .. n ^ 3], onLiterals(n)); + literals := tbl2lits(MultiplicationTable(S), n); + orbit := Orbit(Image(phi, SymmetricGroup(n)), literals, OnSets); -InstallMethod(IsZeroSemigroup, "for a small semigroup", -[IsSmallSemigroup], -function(s) - return Length( Unique( Flat(MultiplicationTable(s)))) = 1; + return tbl2lits(TransposedMat(MultiplicationTable(S)), n) in orbit; end); -########################################################################### +InstallMethod(IsSimpleSemigroup, "for a small semigroup", [IsSmallSemigroup], +function(S) -InstallMethod( IsZeroSimpleSemigroup, "for a small semigroup", true, -[IsSmallSemigroup], 0, -function(M) -local zero; - -if IsGroupAsSemigroup(M) then - return false; -elif HasIsCompletelyRegularSemigroup(M) and IsCompletelyRegularSemigroup(M) then - return false; -elif IsRegularSemigroup(M) then - zero:=MultiplicativeZero(M); - if not zero=fail and Length(GreensDClasses(M))=2 then - return true; - fi; -fi; + if IsGroupAsSemigroup(S) then + return true; + elif HasIsCompletelyRegularSemigroup(S) + and not IsCompletelyRegularSemigroup(S) then + return false; + fi; -return false; + if Length(GreensDClasses(S)) = 1 then + SetIsCompletelyRegularSemigroup(S, true); + SetIsRegularSemigroup(S, true); + return true; + fi; + return false; end); -########################################################################### -# -# split in two methods, second one for abitrary semigroups -# -InstallMethod(MinimalGeneratingSet,"for a small semigroup",[IsSmallSemigroup], -function(s) - local subsets, id, pos, entries, gens, subset, k, subsgrp, generatedSubSG, - mt, generated; - - generatedSubSG := function( indices ) - local new, old; +InstallMethod(IsSingularSemigroupCopy, "for a small semigroup", +[IsSmallSemigroup], S -> IdSmallSemigroup(S) = [2, 4]); - new := indices; - - repeat - old := new; - new := Union( old, Unique( Flat(mt{old}{old}) )); - until new = old; - - return new; - end; - - mt := MultiplicationTable( s ); - - # elements not in the mult. table have to be in every generating set - entries := Unique(Flat(MultiplicationTable(s))); - gens := Difference( [ 1..Size(s) ], entries ); +InstallMethod(IsZeroGroup, "for a small semigroup", [IsSmallSemigroup], +function(S) + local zero, elts; + + zero := MultiplicativeZero(S); + if zero <> fail then + elts := Difference(Elements(S), [zero]); + return IsGroupAsSemigroup(SmallSemigroup(IdSmallSemigroup(Semigroup(elts)))); + fi; + # TODO resolve the comments below + # JDM the previous line is a good example of why IsomorphismSmallSemigroup is + # required + # AD shouldn't this rather be something like: + # AD return fail <> AsGroup( elts ); + return false; +end); - # for nilpotent semigroups the non-entries are a generating set - if IsNilpotentSemigroup( s ) then - return AsSSortedList(s){gens}; - fi; +InstallMethod(IsZeroSemigroup, "for a small semigroup", +[IsSmallSemigroup], +S -> Length(Unique(Flat(MultiplicationTable(S)))) = 1); - if not IsEmpty( gens ) then - generated := generatedSubSG( gens ); - entries := Difference( entries, generated ); +InstallMethod(IsZeroSimpleSemigroup, "for a small semigroup", +[IsSmallSemigroup], +function(S) + local zero; + if IsGroupAsSemigroup(S) then + return false; + elif HasIsCompletelyRegularSemigroup(S) + and IsCompletelyRegularSemigroup(S) then + return false; + elif IsRegularSemigroup(S) then + zero := MultiplicativeZero(S); + if zero <> fail and Length(GreensDClasses(S)) = 2 then + return true; fi; + fi; + return false; +end); - # try inductively adding sets of size k to get generating set - for k in [ Maximum(0,1-Length(gens))..Length(entries) ] do - # subsets of elements not generated by - subsets := Combinations( entries, k ); - for subset in subsets do - if Length(generatedSubSG(Concatenation(gens,subset)))=Size(s) then - return AsSSortedList(s){Concatenation(gens,subset)}; - fi; - od; +# split in two methods, second one for abitrary semigroups +InstallMethod(MinimalGeneratingSet, "for a small semigroup", [IsSmallSemigroup], +function(S) + local subsets, entries, gens, subset, k, generatedSubSG, mt, generated; + + generatedSubSG := function(indices) + local new, old; + new := indices; + repeat + old := new; + new := Union(old, Unique(Flat(mt{old}{old}))); + until new = old; + return new; + end; + + mt := MultiplicationTable(S); + + # elements not in the mult. table have to be in every generating set + entries := Unique(Flat(MultiplicationTable(S))); + gens := Difference([1 .. Size(S)], entries); + + # for nilpotent semigroups the non - entries are a generating set + if IsNilpotentSemigroup(S) then + return AsSSortedList(S){gens}; + fi; + + if not IsEmpty(gens) then + generated := generatedSubSG(gens); + entries := Difference(entries, generated); + fi; + + # try inductively adding sets of size k to get generating set + for k in [Maximum(0, 1 - Length(gens)) .. Length(entries)] do + # subsets of elements not generated by < gens > + subsets := Combinations(entries, k); + for subset in subsets do + if Length(generatedSubSG(Concatenation(gens, subset))) = Size(S) then + return AsSSortedList(S){Concatenation(gens, subset)}; + fi; od; + od; end); -########################################################################### - -InstallMethod( NilpotencyDegree, "for a small semigroup", [ IsSmallSemigroup ], -function( S ) - local elms, rank, gens, gen, elm, elmslist; - - if not IsNilpotentSemigroup(S) then - Info(InfoSmallsemi,2, - "Only nilpotent semigroups have a nilpotency rank."); - return fail; - fi; +InstallMethod(NilpotencyDegree, "for a small semigroup", [IsSmallSemigroup], +function(S) + local elms, rank, gens, gen, elm, elmslist; + if not IsNilpotentSemigroup(S) then + Info(InfoSmallsemi, 2, + "Only nilpotent semigroups have a nilpotency degree."); + return fail; + elif Size(S) = 1 then # special case trivial semigroup - if Size(S) = 1 then return 1; fi; - + return 1; + elif Size(S) = 8 and IdSmallSemigroup(S)[2] > 11433106 then # special treatment for 3-nilpotent semigroups of size 8 - if Size(S) = 8 and IdSmallSemigroup(S)[2] > 11433106 then - return 3; - fi; - - # the generators of a nilpotent semigroup are precisely the elements - # which do not appear in the multplication table - gens := Difference( [1..Size(S)], Unique(Flat(MultiplicationTable(S))) ); - elms := gens; - rank := 1; - - # for a 'small semigroup' 1 is the zero - while [ 1 ] <> elms do - rank := rank+1; - # max. 6 generators (for zero semigroup of size 7) - elmslist := EmptyPlist( 36 ); - # repeatedly calculate {gens}^(rank) - for gen in gens do - for elm in elms do - Add( elmslist, MultiplicationTable(S)[gen][elm] ); - od; - od; - elms := Unique( elmslist ); + return 3; + fi; + + # the generators of a nilpotent semigroup are precisely the elements + # which do not appear in the multplication table + gens := Difference([1 .. Size(S)], Unique(Flat(MultiplicationTable(S)))); + elms := gens; + rank := 1; + + # for a 'small semigroup' 1 is the zero + while [1] <> elms do + rank := rank + 1; + # max. 6 generators (for zero semigroup of size 7) + elmslist := EmptyPlist(36); + # repeatedly calculate {gens} ^ (rank) + for gen in gens do + for elm in elms do + Add(elmslist, MultiplicationTable(S)[gen][elm]); + od; od; + elms := Unique(elmslist); + od; - return rank; + return rank; end); # the following are special methods for library functions - no doc -########################################################################### -########################################################################### -########################################################################### -InstallMethod(GreensRClasses, "for a small semigroup", [IsSmallSemigroup], +InstallMethod(GreensRClasses, "for a small semigroup", [IsSmallSemigroup], function(S) -local pos, elms, id, class, gens, graph, out, i; - -elms:=AsSSortedList(S); - -if HasMinimalGeneratingSet(S) then - gens:=List(MinimalGeneratingSet(S), x-> x!.index); -else - gens:=List(GeneratorsOfSemigroup(S), x-> x!.index); -fi; - -graph:=List(MultiplicationTable(S), x-> x{gens}); #the left Cayley graph -class:=STRONGLY_CONNECTED_COMPONENTS_DIGRAPH(graph); - -elms:=AsSet(List(class, x-> AsSet(elms{x}))); -out:=[]; -for i in [1..Length(elms)] do - out[i]:=GreensRClassOfElement(S, elms[i][1]); - SetAsSSortedList(out[i], elms[i]); -od; + local table, class, elms, out, i; + + # the left Cayley graph + table := MultiplicationTable(S); + class := STRONGLY_CONNECTED_COMPONENTS_DIGRAPH(table); + elms := Elements(S); + elms := AsSet(List(class, x -> AsSet(elms{x}))); + out := []; + for i in [1 .. Length(elms)] do + out[i] := GreensRClassOfElement(S, elms[i][1]); + SetAsSSortedList(out[i], elms[i]); + od; + return out; +end); + +InstallMethod(GreensLClasses, "for a small semigroup", [IsSmallSemigroup], +function(S) + local table, class, elms, out, i; + + # the left Cayley graph + table := TransposedMat(MultiplicationTable(S)); + class := STRONGLY_CONNECTED_COMPONENTS_DIGRAPH(table); + elms := Elements(S); + elms := AsSet(List(class, x -> AsSet(elms{x}))); + out := []; + for i in [1 .. Length(elms)] do + out[i] := GreensRClassOfElement(S, elms[i][1]); + SetAsSSortedList(out[i], elms[i]); + od; + return out; +end); + +# TODO replace this with the method in the Semigroups package +InstallMethod(GreensHClasses, "for a small semigroup", +[IsSmallSemigroup], +function(S) + local r, l, H, c, i, h; -return out; + r := GreensRClasses(S); + l := GreensLClasses(S); -end); - -########################################################################### + if Length(r) = Size(S) then + SetGreensDClasses(S, List(l, x -> + GreensDClassOfElement(S, Representative(x)))); -InstallMethod(GreensLClasses, "for a small semigroup", [IsSmallSemigroup], -function(S) -local pos, elms, id, class, gens, graph, out, i; + for i in [1 .. Length(GreensLClasses(S))] do + SetAsSSortedList(GreensDClasses(S)[i], Elements(GreensLClasses(S)[i])); + od; -elms:=AsSSortedList(S); + SetGreensHClasses(S, List(r, x -> + GreensHClassOfElement(S, Representative(x)))); -if HasMinimalGeneratingSet(S) then - gens:=List(MinimalGeneratingSet(S), x-> x!.index); -else - gens:=List(GeneratorsOfSemigroup(S), x-> x!.index); -fi; + for c in GreensHClasses(S) do + SetAsSSortedList(c, [Representative(c)]); + od; -graph:=List(TransposedMat(MultiplicationTable(S)), x-> x{gens}); -#the right Cayley graph -class:=STRONGLY_CONNECTED_COMPONENTS_DIGRAPH(graph); + return GreensHClasses(S); + elif Length(l) = Size(S) then + SetGreensDClasses(S, List(r, x -> + GreensDClassOfElement(S, Representative(x)))); -elms:=AsSet(List(class, x-> AsSet(elms{x}))); -out:=[]; -for i in [1..Length(elms)] do - out[i]:=GreensLClassOfElement(S, elms[i][1]); - SetAsSSortedList(out[i], elms[i]); -od; - -return out; + for i in [1 .. Length(GreensRClasses(S))] do + SetAsSSortedList(GreensDClasses(S)[i], Elements(GreensRClasses(S)[i])); + od; -end); + SetGreensHClasses(S, List(l, x -> + GreensHClassOfElement(S, Representative(x)))); -########################################################################### + for c in GreensHClasses(S) do + SetAsSSortedList(c, [Representative(c)]); + od; -InstallMethod(GreensHClasses, "for a small semigroup", true, -[IsSmallSemigroup], 0, -function(S) -local r, l, H, c, i, h; - -r:=GreensRClasses(S); -l:=GreensLClasses(S); - -#Info(InfoWarning, 1, "THIS FUNCTION IS CURRENTLY FAULTY"); - -if Length(r)=Size(S) then - SetGreensDClasses(S, List(l, x-> - GreensDClassOfElement(S, Representative(x)))); - - for i in [1..Length(GreensLClasses(S))] do - SetAsSSortedList(GreensDClasses(S)[i], Elements(GreensLClasses(S)[i])); - od; - - SetGreensHClasses(S, List(r, x-> - GreensHClassOfElement(S, Representative(x)))); - - for c in GreensHClasses(S) do - SetAsSSortedList(c, [Representative(c)]); - od; - - return GreensHClasses(S); -elif Length(l)=Size(S) then - SetGreensDClasses(S, List(r, x-> - GreensDClassOfElement(S, Representative(x)))); - - for i in [1..Length(GreensRClasses(S))] do - SetAsSSortedList(GreensDClasses(S)[i], Elements(GreensRClasses(S)[i])); - od; - - SetGreensHClasses(S, List(l, x-> - GreensHClassOfElement(S, Representative(x)))); - - for c in GreensHClasses(S) do - SetAsSSortedList(c, [Representative(c)]); - od; - - return GreensHClasses(S); -fi; + return GreensHClasses(S); + fi; + + r := List(r, x -> List(Elements(x), y -> y!.index)); + l := List(l, x -> List(Elements(x), y -> y!.index)); + + H := []; + + repeat + c := r[1]; + i := 0; + repeat + i := i + 1; + if not IsEmpty(l[i]) then + h := Intersection(c, l[i]); + if not IsEmpty(h) then + Add(H, h); + SubtractSet(l[i], h); + SubtractSet(c, h); + fi; + fi; + until IsEmpty(c); + SubtractSet(r, [c]); + until IsEmpty(r); -r:=List(r, x-> List(Elements(x), y->y!.index)); -l:=List(l, x-> List(Elements(x), y->y!.index)); - -H:=[]; - -repeat - c:=r[1]; - i:=0; - repeat - i:=i+1; - if not l[i]=[] then - h:=Intersection(c, l[i]); - if not h=[] then - Add(H, h); - SubtractSet(l[i], h); - SubtractSet(c, h); - fi; - fi; - until c=[]; - SubtractSet(r, [c]); -until r=[]; - -SetGreensHClasses(S, List(H, x-> GreensHClassOfElement(S, Elements(S)[x[1]]))); - -for i in [1..Length(H)] do - SetAsSSortedList(GreensHClasses(S)[i], Elements(S){H[i]}); -od; + SetGreensHClasses(S, + List(H, x -> GreensHClassOfElement(S, Elements(S)[x[1]]))); -return GreensHClasses(S); + for i in [1 .. Length(H)] do + SetAsSSortedList(GreensHClasses(S)[i], Elements(S){H[i]}); + od; + return GreensHClasses(S); end); -########################################################################### - -InstallMethod(GreensDClasses, "for a small semigroup", true, -[IsSmallSemigroup], 0, +InstallMethod(GreensDClasses, "for a small semigroup", +[IsSmallSemigroup], function(S) -local elts, gens, r, l, d, i, c; - -if HasGreensRClasses(S) and Length(GreensRClasses(S))=Size(S) then - SetGreensHClasses(S, List(GreensRClasses(S), x-> - GreensHClassOfElement(S, Representative(x)))); - - for c in GreensHClasses(S) do - SetAsSSortedList(c, [Representative(c)]); - od; - - SetGreensDClasses(S, List(GreensLClasses(S), x-> GreensDClassOfElement(S, - Representative(x)))); - - for i in [1..Length(GreensLClasses(S))] do - SetAsSSortedList(GreensDClasses(S)[i], Elements(GreensLClasses(S)[i])); - od; - - return GreensDClasses(S); - - elif HasGreensLClasses(S) and Length(GreensLClasses(S))=Size(S) then - SetGreensHClasses(S, List(GreensLClasses(S), x-> - GreensHClassOfElement(S, Representative(x)))); - for c in GreensHClasses(S) do - SetAsSSortedList(c, [Representative(c)]); - od; - - SetGreensDClasses(S, List(GreensRClasses(S), x-> - GreensDClassOfElement(S, Representative(x)))); - - for i in [1..Length(GreensRClasses(S))] do - SetAsSSortedList(GreensDClasses(S)[i], Elements(GreensRClasses(S)[i])); - od; -fi; - -if HasMinimalGeneratingSet(S) then - gens:=List(MinimalGeneratingSet(S), x-> x!.index); -else - gens:=List(GeneratorsOfSemigroup(S), x-> x!.index); -fi; - -r:=List(TransposedMat(MultiplicationTable(S)), x-> x{gens}); #right -l:=List(MultiplicationTable(S), x-> x{gens}); #left + local R, L, D, elts, C, i; -d:=List([1..Size(S)], i-> Union(r[i], l[i])); #union of the two graphs -d:=STRONGLY_CONNECTED_COMPONENTS_DIGRAPH(d); + R := TransposedMat(MultiplicationTable(S)); + L := MultiplicationTable(S); -elts:=AsSSortedList(S); -elts:=AsSet(List(d, x-> AsSet(elts{x}))); -d:=[]; -for i in [1..Length(elts)] do - d[i]:=GreensDClassOfElement(S, elts[i][1]); - SetAsSSortedList(d[i], elts[i]); -od; - -return d; -end); + # union of the two graphs + D := List([1 .. Size(S)], i -> Union(R[i], L[i])); + D := STRONGLY_CONNECTED_COMPONENTS_DIGRAPH(D); + elts := AsSSortedList(S); + elts := AsSet(List(D, x -> AsSet(elts{x}))); + C := []; + for i in [1 .. Length(elts)] do + C[i] := GreensDClassOfElement(S, elts[i][1]); + SetAsSSortedList(C[i], elts[i]); + od; -## Method for 'String' missing for Green's classes in the GAP library. AD -############################################################################# -## -#M String( ) . . . for Green's classes -## -InstallMethod(String, "for Green's classes of a semigroup", [IsGreensClass], -function(c) -return Concatenation("{", String(Representative( c )), "}"); + return C; end); +InstallMethod(String, "for Green's classes of a semigroup", [IsGreensClass], +C -> Concatenation("{", String(Representative(C)), "}")); -# Internal functions - documented in the dev manual -########################################################################### ########################################################################### +# Internal functions - documented in the dev manual ########################################################################### InstallGlobalFunction(STORED_INFO, function(n, name) - local i; - - if name in RecNames(MOREDATA2TO8[n]) then - return MOREDATA2TO8[n].(name); - elif name="IsBand" then - i := Position(MOREDATA2TO8[n].diags, [1..n]); - return [ MOREDATA2TO8[n].endpositions[i]+1 .. - MOREDATA2TO8[n].endpositions[i+1]]; - else - return fail; - fi; -end); - -#this is the same as using DeclareSynonymAttr(SMALLSEMI_EQUIV[1], -#SMALLSEMI_EQUIV[2]) but where SMALLSEMI_EQUIV[2] is not a property of -#semigroups alone or is not true for all semigroups. For example, -#IsMonogenicSemigroup implies Is1GeneratedSemigroup for all semigroups, and is -#hence a synonym. On the other hand, IsCompletelySimpleSemigroup only holds for -#IsSimpleSemigroup and IsFinite, and IsCommutativeSemigroup only holds for -#IsCommutative and IsSemigroup. - -if IsBound(IsSingularSemigroup) then - BindGlobal( "SMALLSEMI_ALWAYS_FALSE", - [IsFullTransformationSemigroup, - IsSingularSemigroup]); + local i; + + if name in RecNames(MOREDATA2TO8[n]) then + return MOREDATA2TO8[n].(name); + elif name = "IsBand" then + i := Position(MOREDATA2TO8[n].diags, [1 .. n]); + return [MOREDATA2TO8[n].endpositions[i] + 1 .. + MOREDATA2TO8[n].endpositions[i + 1]]; + fi; + return fail; +end); + +# This is the same as using DeclareSynonymAttr(SMALLSEMI_EQUIV[1], +# SMALLSEMI_EQUIV[2]) but where SMALLSEMI_EQUIV[2] is not a property of +# semigroups alone or is not true for all semigroups. For example, +# IsMonogenicSemigroup implies Is1GeneratedSemigroup for all semigroups, and is +# hence a synonym. On the other hand, IsCompletelySimpleSemigroup only holds +# for IsSimpleSemigroup and IsFinite, and IsCommutativeSemigroup only holds for +# IsCommutative and IsSemigroup. + +# <#GAPDoc Label="SMALLSEMI_ALWAYS_FALSE"> +# +# +# +# is a global variable whose value is a list of strings str of names of +# properties or attributes that are always false for a small semigroup. +#

+# +# For example, is +# always false for small semigroups but +# can be true. +# SMALLSEMI_ALWAYS_FALSE; +# [ "IsFullTransformationSemigroup", "IsSingularSemigroup" ] +# ]]> +# +# +# <#/GAPDoc> + +if IsBound(IsSingularSemigroup) then + BindGlobal("SMALLSEMI_ALWAYS_FALSE", + [IsFullTransformationSemigroup, IsSingularSemigroup]); else - BindGlobal( "SMALLSEMI_ALWAYS_FALSE", + BindGlobal("SMALLSEMI_ALWAYS_FALSE", [IsFullTransformationSemigroup]); fi; -#BindGlobal( "SMALLSEMI_EQUIV", -# [["IsCompletelySimpleSemigroup", "IsSimpleSemigroup"], -# ["IsCommutativeSemigroup", "IsCommutative"], -# ["IsNilpotent", "IsNilpotentSemigroup"]]); - -# the entries in the variable SMALLSEMI_EQUIV should be sorted according to -# SMALLSEMI_SORT_ARG_NC, i.e. the ones with true as argument come -# first and then are sorted alphabetically. Currently, the first -# component of every instance in SMALLSEMI_EQUIV should have length -# two! +# the entries in the variable SMALLSEMI_EQUIV should be sorted according to +# SMALLSEMI_SORT_ARG_NC, i.e. the ones with true as argument come first and +# then are sorted alphabetically. Currently, the first component of every +# instance in SMALLSEMI_EQUIV should have length two! -BindGlobal( "SMALLSEMI_EQUIV", [ +# <#GAPDoc Label="SMALLSEMI_EQUIV"> +# +# +# +# is a global variable whose value is a list of pairs P of functions and +# values where P[1] is a property and value which is equivalent to the +# properties and values in P[2] for small semigroups.

+# +# For example, implies +# Is1GeneratedSemigroup for all semigroups and is hence a synonym and +# the pair [[IsMonogenicSemigroup, true], [Is1GeneratedSemigroup, true]] +# does not need to be installed in SMALLSEMI_EQUIV. On the other hand, +# only holds for +# and and hence is not a synonym and the pairs [ +# [IsCompletelySimpleSemigroup, true], [IsSimpleSemigroup, true]] and [ +# [IsCompletelySimpleSemigroup, false], [IsSimpleSemigroup, false]] +# must be entered in SMALLSEMI_EQUIV. Note that +# [[IsOrthodoxSemigroup, true], [IsRegularSemigroup, true, +# IsSemigroupWithoutClosedIdempotents, false]] can be entered in +# SMALLSEMI_EQUIV but currently it is not possible to have any pair in +# SMALLSEMI_EQUIV with first entry [IsOrthodoxSemigroup, +# false].

+# +# Also note that if P is an entry in SMALLSEMI_EQUIV, then +# P[1] must have length 2.

+# +# The reason for doing all of this is so that when is called with +# argument IsCompletelySimpleSemigroup there is no component in the +# record in the info file with the name "IsCompletelySimpleSemigroup" +# and so this name is provided by SMALLSEMI_EQUIV. If two properties are +# synonymous, then NAME_FUNC has the same value for both and so it is +# only necessary to store a component with that one name and hence not +# necessary to put a pair in SMALLSEMI_EQUIV.

The name of the +# component in the info file should be in the second component of a pair in +# SMALLSEMI_EQUIV +# SMALLSEMI_EQUIV; +# [ [ "IsCompletelySimpleSemigroup", "IsSimpleSemigroup" ], +# [ "IsCommutativeSemigroup", "IsCommutative" ], +# [ "IsNilpotent", "IsNilpotentSemigroup" ] ] +# ]]> +# +# +# <#/GAPDoc> + +BindGlobal("SMALLSEMI_EQUIV", [ [[IsCliffordSemigroup, true], -[IsCompletelyRegularSemigroup, true, IsInverseSemigroup, true]], +[IsCompletelyRegularSemigroup, true, IsInverseSemigroup, true]], [[IsCompletelySimpleSemigroup, true], [IsSimpleSemigroup, true]], [[IsCompletelySimpleSemigroup, false], [IsSimpleSemigroup, false]], -[[IsCommutativeSemigroup, true], [IsCommutative, true]], +[[IsCommutativeSemigroup, true], [IsCommutative, true]], [[IsCommutativeSemigroup, false], [IsCommutative, false]], @@ -1385,33 +936,11 @@ BindGlobal( "SMALLSEMI_EQUIV", [ [[IsSemilattice, true], [IsBand, true, IsCommutative, true]], -#JDM see comment in the NV note about the four below. Waiting for -#JDM anti-position list to allow for [IsOrthodoxSemigroup, false] and similar. - -# [[Is4GeneratedSemigroup, true], -# [Is1GeneratedSemigroup, false, Is2GeneratedSemigroup, false, -# Is3GeneratedSemigroup, false, Is5GeneratedSemigroup, false, -# Is6GeneratedSemigroup, false, Is7GeneratedSemigroup, false, -# Is8GeneratedSemigroup, false ]], - [[IsRectangularBand, true], [IsBand, true, IsSimpleSemigroup, true]], -[[IsOrthodoxSemigroup, true], +[[IsOrthodoxSemigroup, true], [IsRegularSemigroup, true, IsSemigroupWithoutClosedIdempotents, false]], - -[[IsBrandtSemigroup, true], [IsInverseSemigroup, true, - IsZeroSimpleSemigroup, true]], +[[IsBrandtSemigroup, true], [IsInverseSemigroup, true, + IsZeroSimpleSemigroup, true]], ]); - -#BindGlobal( "SMALLSEMI_CONVERSE", -# [["Is4GeneratedSemigroup", -# [Is1GeneratedSemigroup, false, Is2GeneratedSemigroup, false, -# Is3GeneratedSemigroup, false, Is5GeneratedSemigroup, false, -# Is6GeneratedSemigroup, false, Is7GeneratedSemigroup, false]], -# ["IsRectangularBand", [IsBand, true, IsSimpleSemigroup, true]], -# ["IsOrthodoxSemigroup", -# [IsRegularSemigroup, true, -# IsSemigroupWithoutClosedIdempotents, false]], -# ["IsSemigroupWithClosedIdempotents", -# [IsSemigroupWithoutClosedIdempotents, false]]]); diff --git a/gap/small.gd b/gap/small.gd index 503caa5..6f7731b 100644 --- a/gap/small.gd +++ b/gap/small.gd @@ -1,573 +1,469 @@ ############################################################################# ## -#W small.gd Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2012 Andreas Distler & James D. Mitchell +## small.gd Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## -## Licensing information can be found in the README file of this package. +# Licensing information can be found in the README file of this package. ## ############################################################################# ## - -########################################################################### -## -## <#GAPDoc Label="EquivalenceSmallSemigroup"> -## -## -## -## returns a mapping map from sgrp to the semigroup in -## Smallsemi equivalent to sgrp. The mapping -## is an isomorphism if such exists and an anti-isomorphism otherwise. -## The argument sgrp has to be a semigroup of size 8 or less, -## otherwise an error is signalled. -## sgrp:=Semigroup(Transformation( [ 1, 2, 2 ] ), -## > Transformation( [ 1, 2, 3 ] ));; -## gap> EquivalenceSmallSemigroup(sgrp); -## SemigroupHomomorphismByImages ( Monoid( [ Transformation( [ 1, 2, 2 ] ) -## ] )->) -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="EquivalenceSmallSemigroup"> +# +# +# +# returns a mapping map from sgrp to the semigroup in +# Smallsemi equivalent to sgrp. The mapping +# is an isomorphism if such exists and an anti-isomorphism otherwise. +# The argument sgrp has to be a semigroup of size 8 or less, +# otherwise an error is signalled. +# sgrp:=Semigroup(Transformation( [ 1, 2, 2 ] ), +# > Transformation( [ 1, 2, 3 ] ));; +# gap> EquivalenceSmallSemigroup(sgrp); +# SemigroupHomomorphismByImages ( Monoid( [ Transformation( [ 1, 2, 2 ] ) +# ] )->) +# ]]> +# +# +# <#/GAPDoc> DeclareAttribute("EquivalenceSmallSemigroup", IsSemigroup); -########################################################################### -## -## <#GAPDoc Label="IdSmallSemigroup"> -## -## -## -## returns a pair [m, n] such that (m,n) is the ID of -## a semigroup in Smallsemi equivalent to sgrp. -## The argument sgrp has to be a semigroup of size 8 or less, -## otherwise an error is signalled. -## sgrp:=Semigroup(Transformation( [ 1, 2, 2 ] ), Transformation( [ 1, 2, 3 ] ));; -## gap> IdSmallSemigroup(sgrp); -## [ 2, 3 ] -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="IdSmallSemigroup"> +# +# +# +# returns a pair [m, n] such that (m,n) is the ID of +# a semigroup in Smallsemi equivalent to sgrp. +# The argument sgrp has to be a semigroup of size 8 or less, +# otherwise an error is signalled. +# sgrp := Semigroup(Transformation([1, 2, 2]), +# > Transformation([1, 2, 3]));; +# gap> IdSmallSemigroup(sgrp); +# [ 2, 3 ] +# ]]> +# +# +# <#/GAPDoc> DeclareAttribute("IdSmallSemigroup", IsSemigroup); -########################################################################### -## -## <#GAPDoc Label="InfoSmallsemi"> -## -## -## -## is the info class (see ) of -## Smallsemi. The info level is initially set to 1 which -## triggers a message whenever data is loaded into &GAP;. -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="InfoSmallsemi"> +# +# +# +# is the info class (see ) of +# Smallsemi. The info level is initially set to 1 which +# triggers a message whenever data is loaded into &GAP;. +# +# +# <#/GAPDoc> DeclareInfoClass("InfoSmallsemi"); -########################################################################### -## -## <#GAPDoc Label="InfoSmallsemiEnums"> -## -## -## -## is an info class (see ) for -## debugging the Smallsemi file enums.gi. -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="InfoSmallsemiEnums"> +# +# +# +# is an info class (see ) for +# debugging the Smallsemi file enums.gi. +# +# +# <#/GAPDoc> DeclareInfoClass("InfoSmallsemiEnums"); - -########################################################################### -## -## <#GAPDoc Label="IsSmallSemigroup"> -## -## -## -## returns true if sgrp is a semigroup from the library, -## that is if it was created using . Otherwise -## false is returned.

-## sgrp:=RandomSmallSemigroup(5); -## -## gap> IsSmallSemigroup(sgrp); -## true -## gap> sgrp:=Semigroup(Transformation([1]));; -## gap> IsSmallSemigroup(sgrp); -## false -## ]]> -## -## -## <#/GAPDoc> -## - +# <#GAPDoc Label="IsSmallSemigroup"> +# +# +# +# returns true if sgrp is a semigroup from the library, +# that is if it was created using . Otherwise +# false is returned.

+# sgrp:=RandomSmallSemigroup(5); +# +# gap> IsSmallSemigroup(sgrp); +# true +# gap> sgrp:=Semigroup(Transformation([1]));; +# gap> IsSmallSemigroup(sgrp); +# false +# ]]> +# +# +# <#/GAPDoc> DeclareCategory("IsSmallSemigroup", IsSemigroup); -########################################################################### -## -## <#GAPDoc Label="IsSmallSemigroupElt"> -## -## -## -## returns true if x is an element of a semigroup from the -## library, and false otherwise.

-## -## IsSmallSemigroupElt is a -## representation satisfying IsPositionalObjectRep and -## and -## IsAttributeStoringRep. -## IsSmallSemigroupElt(Transformation([1])); -## false -## gap> sgrp:=RandomSmallSemigroup(5);; -## gap> IsSmallSemigroupElt(Random(sgrp)); -## true -## ]]> -## -## -## <#/GAPDoc> -## - -DeclareRepresentation( "IsSmallSemigroupElt", -IsPositionalObjectRep and IsMultiplicativeElement and IsAssociativeElement and IsAttributeStoringRep, -[ 2 ] ); - -########################################################################### -## -## <#GAPDoc Label="RecoverMultiplicationTable"> -## -## -## -## -## return the multiplication table of the n-th semigroup with -## m elements from the library. -##

-## If m is greater than 8 or n greater than the number -## of semigroups of size m, then fail is returned. The -## NC version does not perform any tests on the input and will most likely -## run into an error in such a case. -## RecoverMultiplicationTable(10,2); -## fail -## gap> RecoverMultiplicationTable(1,2); -## fail -## gap> RecoverMultiplicationTable(2,1); -## [ [ 1, 1 ], [ 1, 1 ] ] -## gap> RecoverMultiplicationTable(8,11111111); -## [ [ 1, 1, 1, 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1, 1, 1, 3 ], -## [ 3, 3, 3, 3, 3, 3, 3, 3 ], [ 1, 1, 1, 4, 4, 4, 4, 1 ], -## [ 1, 2, 3, 4, 5, 6, 7, 1 ], [ 1, 2, 3, 4, 5, 6, 7, 1 ], -## [ 1, 2, 3, 4, 5, 6, 7, 1 ], [ 8, 8, 8, 8, 8, 8, 8, 8 ] ] -## gap> RecoverMultiplicationTable(2,11111111); -## fail -## ]]> -## Note that no semigroup is created calling this function but just the -## table is created. This makes it useful if one wants to perform very -## simple (i.e. quick in &GAP;) tests on a large number of semigroups which -## can be performed on the multiplication table. -##

-## To create a semigroup with the multiplication table obtained by -## RecoverMultiplicationTable(m,n) use the function -## with arguments m,n. -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="IsSmallSemigroupElt"> +# +# +# +# returns true if x is an element of a semigroup from the +# library, and false otherwise.

+# +# IsSmallSemigroupElt is a +# representation satisfying IsPositionalObjectRep and +# and +# IsAttributeStoringRep. +# IsSmallSemigroupElt(Transformation([1])); +# false +# gap> sgrp:=RandomSmallSemigroup(5);; +# gap> IsSmallSemigroupElt(Random(sgrp)); +# true +# ]]> +# +# +# <#/GAPDoc> +DeclareRepresentation("IsSmallSemigroupElt", + IsPositionalObjectRep + and IsMultiplicativeElement + and IsAssociativeElement + and IsAttributeStoringRep, + [2]); + +# <#GAPDoc Label="RecoverMultiplicationTable"> +# +# +# +# +# return the multiplication table of the n-th semigroup with +# m elements from the library. +#

+# If m is greater than 8 or n greater than the number +# of semigroups of size m, then fail is returned. The +# NC version does not perform any tests on the input and will most likely +# run into an error in such a case. +# RecoverMultiplicationTable(10,2); +# fail +# gap> RecoverMultiplicationTable(1,2); +# fail +# gap> RecoverMultiplicationTable(2,1); +# [ [ 1, 1 ], [ 1, 1 ] ] +# gap> RecoverMultiplicationTable(8,11111111); +# [ [ 1, 1, 1, 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1, 1, 1, 3 ], +# [ 3, 3, 3, 3, 3, 3, 3, 3 ], [ 1, 1, 1, 4, 4, 4, 4, 1 ], +# [ 1, 2, 3, 4, 5, 6, 7, 1 ], [ 1, 2, 3, 4, 5, 6, 7, 1 ], +# [ 1, 2, 3, 4, 5, 6, 7, 1 ], [ 8, 8, 8, 8, 8, 8, 8, 8 ] ] +# gap> RecoverMultiplicationTable(2,11111111); +# fail +# ]]> +# Note that no semigroup is created calling this function but just the +# table is created. This makes it useful if one wants to perform very +# simple (i.e. quick in &GAP;) tests on a large number of semigroups which +# can be performed on the multiplication table. +#

+# To create a semigroup with the multiplication table obtained by +# RecoverMultiplicationTable(m,n) use the function +# with arguments m,n. +# +# +# <#/GAPDoc> DeclareGlobalFunction("RecoverMultiplicationTable"); DeclareGlobalFunction("RecoverMultiplicationTableNC"); -########################################################################### -## -## <#GAPDoc Label="SemigroupByMultiplicationTableNC"> -## -## -## -## returns an object with -## and multiplication table table without -## checking if the multiplication defined by the table is associative.

-## -## If table is not associative, this can lead to errors and wrong -## results or might even crash &GAP;. -## -## s:=SemigroupByMultiplicationTableNC([[1,2],[2,1]]); -## -## gap> IsSmallSemigroup(s); -## false -## ]]> -## Note that this function is not used to create semigroups when -## is called. It can be useful in combination -## with if one wants to avoid that -## a semigroup knows it comes from the library. -## -## -## <#/GAPDoc> -## - +# <#GAPDoc Label="SemigroupByMultiplicationTableNC"> +# +# +# +# returns an object with +# and multiplication table table without +# checking if the multiplication defined by the table is associative.

+# +# If table is not associative, this can lead to errors and wrong +# results or might even crash &GAP;. +# +# s:=SemigroupByMultiplicationTableNC([[1,2],[2,1]]); +# +# gap> IsSmallSemigroup(s); +# false +# ]]> +# Note that this function is not used to create semigroups when +# is called. It can be useful in combination +# with if one wants to avoid that +# a semigroup knows it comes from the library. +# +# +# <#/GAPDoc> DeclareGlobalFunction("SemigroupByMultiplicationTableNC"); -########################################################################### -## -## <#GAPDoc Label="SmallSemigroup"> -## -## -## -## -## returns the semigroup with ID (m,n) from the library, that -## is the nth semigroup with m elements.

-## -## In SmallSemigroupNC no check is performed to verify that m and n -## are valid arguments.

-## -## In SmallSemigroup an error is signalled if the semigroups -## of size m are not classified or if n is greater than the number of semigroups -## with m elements. -## SmallSemigroup(8,1353452); -## -## gap> SmallSemigroupNC(5,1); -## -## gap> SmallSemigroupNC(5,1)=SmallSemigroup(5,1); -## true -## ]]> -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="SmallSemigroup"> +# +# +# +# +# returns the semigroup with ID (m,n) from the library, that +# is the nth semigroup with m elements.

+# +# In SmallSemigroupNC no check is performed to verify that m and +# n are valid arguments.

+# +# In SmallSemigroup an error is signalled if the semigroups of size +# m are not classified or if n is greater than the number of +# semigroups with m elements. +# SmallSemigroup(8,1353452); +# +# gap> SmallSemigroupNC(5,1); +# +# gap> SmallSemigroupNC(5,1)=SmallSemigroup(5,1); +# true +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("SmallSemigroup"); DeclareGlobalFunction("SmallSemigroupNC"); -############################################################################ -## -## <#GAPDoc Label="UnloadSmallsemiData"> -## -## -## -## deletes most or all of the data from the &GAP; workspace that was -## loaded by Smallsemi.

-## -## If the boolean use_later is false all data loaded by -## Smallsemi is deleted from the workspace, in which -## case Smallsemi is not guaranteed to work properly -## without restarting your &GAP; session. -##

-## If the boolean use_later is true only the recoverable data -## is deleted. This leaves roughly 10 MB of data in the workspace. -## -## -## <#/GAPDoc> -## - +# <#GAPDoc Label="UnloadSmallsemiData"> +# +# +# +# deletes most or all of the data from the &GAP; workspace that was +# loaded by Smallsemi. +#

+# +# If the boolean use_later is false all data loaded by +# Smallsemi is deleted from the workspace, in which +# case Smallsemi is not guaranteed to work properly +# without restarting your &GAP; session. +#

+# +# If the boolean use_later is true only the recoverable data +# is deleted. This leaves roughly 10 MB of data in the workspace. +# +# +# <#/GAPDoc> DeclareGlobalFunction("UnloadSmallsemiData"); -###################### -## GLOBAL VARIABLES ## -###################### - -########################################################################### -## -## <#GAPDoc Label="3NIL_DATA"> -## -## -## -## is a record carrying data to restore 3-nilpotent semigroups of -## size 8.

-## At the time Smallsemi is loaded only the component -## diag is bound and has the value fail. This changes -## when a 3-nilpotent semigroup of size 8 is called. Then diag -## becomes a list element from the component 3nildiags of the -## global variable corresponding to the -## diagonal of the last called 3-nilpotent semigroup of size 8.

-## The other components are strlist, a list of strings carrying -## the information about the entries of the stored multiplication -## tables; positions, a list of integers, the positions of the -## stored solutions relative to the first one with the same diagonal and -## next, an integer storing which position was last called for. -## LoadPackage("smallsemi"); -## true -## gap> 3NIL_DATA; -## rec( diag := fail ) -## gap> SmallSemigroup( 8, NrSmallSemigroups(8)-2 );; -## gap> 3NIL_DATA; -## rec( diag := [ 2, 3 ], strlist := [ "0013", "0313" ], -## positions := [ 1, 3, 4, 7 ], next := 4 ) -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalVariable("3NIL_DATA", - "record carrying the current 3-nilpotent data"); - -########################################################################### -## -## <#GAPDoc Label="BLUEPRINT_MATS"> -## -## -## -## see . -## Display( BLUEPRINT_MATS[3] ); -## [ [ 1, 1, 1, 1, 1, 1, 1, 1 ], -## [ 1, 1, 1, 1, 1, 1, 1, 1 ], -## [ 1, 1, 1, 1, 1, 1, 1, 1 ], -## [ 1, 1, 1 ], -## [ 1, 1, 1 ], -## [ 1, 1, 1 ], -## [ 1, 1, 1 ], -## [ 1, 1, 1 ] ] -## ]]> -## -## -## <#/GAPDoc> -## -# DeclareGlobalVariable("BLUEPRINT_MATS", -# "list of matrices to built 3-nilpotent semigroups"); - ########################################################################### -## -## <#GAPDoc Label="DATA2TO7"> -## -## -## -## is a list containing the raw data of the multiplication tables of -## semigroups of sizes 2 to 7. The i-th entry is a -## list of strings from which the multiplication tables of semigroups of -## size i+1 can be recovered.

-## -## The i-th entry is bound after the first call of -## -## with argument i+1, j for -## some valid j. The function -## -## will unbind all entries. -## IsBound(DATA2TO7[1]); -## false -## gap> RecoverMultiplicationTable(2,1);; -## gap> DATA2TO7[1]; -## [ "0100", "0101", "0011" ] -## gap> UnloadSmallsemiData(true); -## gap> DATA2TO7; -## [ ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalVariable("DATA2TO7","raw data for semigroup tables sizes 2-7"); - +# GLOBAL VARIABLES ########################################################################### -## -## <#GAPDoc Label="DATA8"> -## -## -## -## is a list containing the raw data of the multiplication tables of -## semigroups of size 8. The i-th entry is a list of strings -## from which it is possible to recover the multiplication tables of semigroups with -## diagonal equal to the i-th entry -## in the component diags of the record . -##

-## At most one entry of the list is bound at a time. The initial value -## is the empty list. The variable is flushable. -## -## -## <#/GAPDoc> -## -DeclareGlobalVariable("DATA8","raw data for semigroup tables size 8"); -########################################################################### -## -## <#GAPDoc Label="MOREDATA2TO8"> -## -## -## -## contains the precomputed information stored in the files infon.g -## for n in \{1,...,8\} in a list where the nth entry -## is a record with components named after the function values they store. -## For example, to retrieve the stored value of the function -## MinimalGeneratorsOfSemigroup for a semigroup S of size -## 5 do -## -## MOREDATA2TO8[5].MinimalGeneratorsOfSemigroup[IdSmallSemigroup(S)[2]]; -## -## -## -## <#/GAPDoc> +# <#GAPDoc Label="3NIL_DATA"> +# +# +# +# is a record carrying data to restore 3-nilpotent semigroups of +# size 8.

+# At the time Smallsemi is loaded only the component +# diag is bound and has the value fail. This changes +# when a 3-nilpotent semigroup of size 8 is called. Then diag +# becomes a list element from the component 3nildiags of the +# global variable corresponding to the +# diagonal of the last called 3-nilpotent semigroup of size 8.

+# The other components are strlist, a list of strings carrying +# the information about the entries of the stored multiplication +# tables; positions, a list of integers, the positions of the +# stored solutions relative to the first one with the same diagonal and +# next, an integer storing which position was last called for. +# LoadPackage("smallsemi"); +# true +# gap> 3NIL_DATA; +# rec( diag := fail ) +# gap> SmallSemigroup( 8, NrSmallSemigroups(8)-2 );; +# gap> 3NIL_DATA; +# rec( diag := [ 2, 3 ], strlist := [ "0013", "0313" ], +# positions := [ 1, 3, 4, 7 ], next := 4 ) +# ]]> +# +# +# <#/GAPDoc> +# +DeclareGlobalVariable("3NIL_DATA", + "record carrying the current 3-nilpotent data"); -# DeclareGlobalVariable("MOREDATA2TO8"); +# <#GAPDoc Label="DATA2TO7"> +# +# +# +# is a list containing the raw data of the multiplication tables of +# semigroups of sizes 2 to 7. The i-th entry is a +# list of strings from which the multiplication tables of semigroups of +# size i+1 can be recovered.

+# +# The i-th entry is bound after the first call of +# +# with argument i+1, j for +# some valid j. The function +# +# will unbind all entries. +# IsBound(DATA2TO7[1]); +# false +# gap> RecoverMultiplicationTable(2,1);; +# gap> DATA2TO7[1]; +# [ "0100", "0101", "0011" ] +# gap> UnloadSmallsemiData(true); +# gap> DATA2TO7; +# [ ] +# ]]> +# +# +# <#/GAPDoc> +DeclareGlobalVariable("DATA2TO7", "raw data for semigroup tables sizes 2-7"); + +# <#GAPDoc Label="DATA8"> +# +# +# +# is a list containing the raw data of the multiplication tables of semigroups +# of size 8. The i-th entry is a list of strings from which it is +# possible to recover the multiplication tables of semigroups with diagonal +# equal to the i-th entry in the component diags of the record +# . +#

+# At most one entry of the list is bound at a time. The initial value +# is the empty list. The variable is flushable. +# +# +# <#/GAPDoc> +DeclareGlobalVariable("DATA8", "raw data for semigroup tables size 8"); ######################## ## INTERNAL FUNCTIONS ## ######################## -########################################################################### -## -## <#GAPDoc Label="GENERATE_BLUEPRINT_MATS"> -## -## -## -## generates a list of matrices bound for k in \{2,...,7\} such -## that the k-th entry has k 'zero' rows and columns. To be stored in the -## variable BLUEPRINT_MATS. -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="GENERATE_BLUEPRINT_MATS"> +# +# +# +# generates a list of matrices bound for k in \{2,...,7\} such +# that the k-th entry has k 'zero' rows and columns. To be stored in the +# variable BLUEPRINT_MATS. +# +# +# <#/GAPDoc> DeclareGlobalFunction("GENERATE_BLUEPRINT_MATS"); -############################################################################# -## -## <#GAPDoc Label="READ_3NIL_DATA"> -## -## -## -## reads data to recover multiplication tables of 3-nilpotent -## semigroups of size 8 into the global variable . -## The data to be read is determined by diag. (All information for -## multiplication tables of which diag is the part of the diagonal -## belonging to the non zero rows and columns.) Is is assumed that -## diag is an element in the component 3nildiags of the -## record -## -## -## <#/GAPDoc> -## +# <#GAPDoc Label="READ_3NIL_DATA"> +# +# +# +# reads data to recover multiplication tables of 3-nilpotent +# semigroups of size 8 into the global variable . +# The data to be read is determined by diag. (All information for +# multiplication tables of which diag is the part of the diagonal +# belonging to the non zero rows and columns.) Is is assumed that +# diag is an element in the component 3nildiags of the +# record +# +# +# <#/GAPDoc> DeclareGlobalFunction("READ_3NIL_DATA"); -########################################################################### -## -## <#GAPDoc Label="READ_MOREDATA2TO8"> -## -## -## -## reads the precomputed information stored in the files infon.g for -## n in \{1,...,8\} into the variable MOREDATA2TO8. -## -## -## <#/GAPDoc> - +# <#GAPDoc Label="READ_MOREDATA2TO8"> +# +# +# +# reads the precomputed information stored in the files infon.g for +# n in \{1,...,8\} into the variable MOREDATA2TO8. +# +# +# <#/GAPDoc> DeclareGlobalFunction("READ_MOREDATA2TO8"); -########################################################################### -## -## <#GAPDoc Label="SmallSemigroupCreator"> -## -## -## -## returns a small semigroup s with multiplication table -## table. That is, an element in the category -## with -## , -## , -## , and -## with the property -## set to true.

-## -## Although this function can be used to create semigroups in the category -## where table is not a table in the -## library this may cause problems and there is no reason to do it!

-## -## If you want to create semigroups from multiplication table, then use either -## if you know the table is -## associative, or if -## you do not know. -## RecoverMultiplicationTable(5, 1000); -## [ [ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ], [ 1, 2, 3, 4, 5 ], [ 1, 2, 4, 5, 3 ], -## [ 1, 2, 5, 3, 4 ] ] -## gap> SmallSemigroupCreator(last); -## -## ]]> -## -## -## <#/GAPDoc> -## - +# <#GAPDoc Label="SmallSemigroupCreator"> +# +# +# +# returns a small semigroup s with multiplication table +# table. That is, an element in the category +# with +# , +# , +# , and +# with the property +# set to true.

+# +# Although this function can be used to create semigroups in the category +# where table is not a table in the +# library this may cause problems and there is no reason to do it!

+# +# If you want to create semigroups from multiplication table, then use either +# if you know the table is +# associative, or if +# you do not know. +# RecoverMultiplicationTable(5, 1000); +# [ [ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ], [ 1, 2, 3, 4, 5 ], [ 1, 2, 4, 5, 3 ], +# [ 1, 2, 5, 3, 4 ] ] +# gap> SmallSemigroupCreator(last); +# +# ]]> +# +# +# <#/GAPDoc> DeclareGlobalFunction("SmallSemigroupCreator"); -########################################################################### -## -## <#GAPDoc Label="SmallSemigroupEltFamily"> -## -## -## -## SmallSemigroupEltFamily is a global variable containing the family -## of elements satisfying IsSmallSemigroupElt.

-## -## The value of SmallSemigroupEltFamily is installed when -## Smallsemi is loaded. This is done to avoid the cost of -## repeatedly creating a new family when, say, running through the semigroups -## of order 8. -## SmallSemigroupEltFamily; -## NewFamily( "SmallSemigroupEltFamily", [ 2201 ], [ 35, 36, 38, 114, 117, 120, 2201 ] ) -## ]]> -## -## -## <#/GAPDoc> -## - -BindGlobal("SmallSemigroupEltFamily", NewFamily("SmallSemigroupEltFamily", IsSmallSemigroupElt)); - -########################################################################### -## -## <#GAPDoc Label="SmallSemigroupEltType"> -## -## -## -## SmallSemigroupEltType is a global variable containing the type of -## IsSmallSemigroupElt.

-## -## The value of SmallSemigroupEltType is installed when -## Smallsemi is loaded. This is done to avoid the cost of -## repeatedly creating a new family when, say, running through the semigroups -## of order 8. -## SmallSemigroupEltType; -## NewType( NewFamily( "SmallSemigroupEltFamily", [ 2201 ], -## [ 35, 36, 38, 114, 117, 120, 2201 ] ), [ 35, 36, 38, 114, 117, 120, 2201 ] ) -## ]]> -## -## -## <#/GAPDoc> -## - -BindGlobal("SmallSemigroupEltType", NewType(SmallSemigroupEltFamily, IsSmallSemigroupElt)); - -########################################################################### -## -## <#GAPDoc Label="SmallSemigroupType"> -## -## -## -## SmallSemigroupType is a global variable containing the type of -## the collections family of IsSmallSemigroupEltFamily.

-## -## The value of SmallSemigroupType is installed when -## Smallsemi is loaded. This is done to avoid the cost of -## repeatedly creating a new family when, say, running through the semigroups -## of order 8. -## -## SmallSemigroupType; -## NewType( NewFamily( "CollectionsFamily(...)", [ 52 ], -## [ 51, 52, 114, 115, 117, 118, 121, 133 ] ), -## [ 36, 38, 51, 52, 90, 91, 114, 115, 117, 118, 121, 133, 196, 420, 431, 432, -## 2200 ] ) -## ]]> -## -## -## <#/GAPDoc> -## - -BindGlobal("SmallSemigroupType", NewType(CollectionsFamily( SmallSemigroupEltFamily ), -IsSmallSemigroup and IsAttributeStoringRep)); +# <#GAPDoc Label="SmallSemigroupEltFamily"> +# +# +# +# SmallSemigroupEltFamily is a global variable containing the family +# of elements satisfying IsSmallSemigroupElt.

+# +# The value of SmallSemigroupEltFamily is installed when +# Smallsemi is loaded. This is done to avoid the cost of +# repeatedly creating a new family when, say, running through the semigroups +# of order 8. +# SmallSemigroupEltFamily; +# NewFamily( "SmallSemigroupEltFamily", [ 2201 ], [ 35, 36, 38, 114, 117, 120, +# 2201 ] )]]> +# +# +# <#/GAPDoc> +BindGlobal("SmallSemigroupEltFamily", + NewFamily("SmallSemigroupEltFamily", + IsSmallSemigroupElt)); + +# <#GAPDoc Label="SmallSemigroupEltType"> +# +# +# +# SmallSemigroupEltType is a global variable containing the type of +# IsSmallSemigroupElt.

+# +# The value of SmallSemigroupEltType is installed when +# Smallsemi is loaded. This is done to avoid the cost of +# repeatedly creating a new family when, say, running through the semigroups of +# order 8. +# SmallSemigroupEltType; +# NewType( NewFamily( "SmallSemigroupEltFamily", [ 2201 ], +# [ 35, 36, 38, 114, 117, 120, 2201 ] ), [ 35, 36, 38, 114, 117, 120, 2201 ] ) +# ]]> +# +# +# <#/GAPDoc> + +BindGlobal("SmallSemigroupEltType", + NewType(SmallSemigroupEltFamily, IsSmallSemigroupElt)); + +# <#GAPDoc Label="SmallSemigroupType"> +# +# +# +# SmallSemigroupType is a global variable containing the type of +# the collections family of IsSmallSemigroupEltFamily.

+# +# The value of SmallSemigroupType is installed when +# Smallsemi is loaded. This is done to avoid the cost of +# repeatedly creating a new family when, say, running through the semigroups +# of order 8. +# +# SmallSemigroupType; +# NewType( NewFamily( "CollectionsFamily(...)", [ 52 ], +# [ 51, 52, 114, 115, 117, 118, 121, 133 ] ), +# [ 36, 38, 51, 52, 90, 91, 114, 115, 117, 118, 121, 133, 196, 420, 431, 432, +# 2200 ] ) +# ]]> +# +# +# <#/GAPDoc> +BindGlobal("SmallSemigroupType", + NewType(CollectionsFamily(SmallSemigroupEltFamily), + IsSmallSemigroup and IsAttributeStoringRep)); diff --git a/gap/small.gi b/gap/small.gi index 49bbfbe..4e10290 100644 --- a/gap/small.gi +++ b/gap/small.gi @@ -1,305 +1,254 @@ ############################################################################# ## -#W small.gi Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2012 Andreas Distler & James D. Mitchell +## small.gi Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## ############################################################################# ## +# Returns the integer represented by with characters in [0-]. +BindGlobal("SMALLSEMI_BinInt", +function(str, bas) + local int, pot, c; -########################################################################### -## -#M EquivalenceSmallSemigroup( S ); -## -## returns an isomorphism to a semigroup from the library if such exists -## and an anti-isomorphism otherwise -## + int := 0; + pot := 1; + str := Reversed(str); + for c in str do + int := int + pot * Int([c]); + pot := pot * bas; + od; -InstallMethod( EquivalenceSmallSemigroup, "for a 'small semigroup'", -[IsSmallSemigroup], sgrp -> IdentityMapping( sgrp )); - -InstallMethod( EquivalenceSmallSemigroup, "for a semigroup", [IsSemigroup], -function( S ) - local size, nr, mt, stab, orbit, diag, perm, Sn, diaglits, pos, translits, - n, k, strlist, offset, line, i, tbllits, phi, small, transorbit, isIso, - equi, LitNum, NumLit, tbl2lits, diag2lits, onLiterals, is3nilpotent, - BinInt, imglist, ListToMatrix; - - LitNum := function(ln, n) - return [QuoInt(ln-1,n^2)+1,QuoInt((ln-1) mod n^2,n)+1,(ln-1) mod n+1]; - end; - - NumLit := function(lit,n) - # lit = [ row, col, val ] - return (lit[1]-1)*n^2 + (lit[2]-1)*n + lit[3]; - end; - - diag2lits := function(diag,n) - return List( [1..n], i -> NumLit( [i,i,diag[i]], n ) ); - end; - - tbl2lits := function(table,n) - local i,j,literals, val; - literals := []; - for i in [1..n] do - for j in [1..n] do - val := table[i][j]; - Add(literals, NumLit([i,j,val],n)); - od; - od; + return int; +end); - return literals; - end; +# returns an isomorphism to a semigroup from the library if such exists +# and an anti-isomorphism otherwise +InstallMethod(EquivalenceSmallSemigroup, "for a small semigroup", +[IsSmallSemigroup], IdentityMapping); - onLiterals := n->function(ln,pi) - local lit,imlit; - lit := LitNum(ln,n); - imlit := OnTuples(lit,pi); - if (n+1)^pi = n+2 then - imlit := Permuted(imlit,(1,2)); - fi; - return NumLit(imlit,n); - end; - - is3nilpotent := function( table ) - local n, zero, entries, i; - - n := Size( table ); - zero := First( [1..n], i -> table[i] = ListWithIdenticalEntries(n, i) - and table{[1..n]}[i] = ListWithIdenticalEntries(n, i)); - if zero = fail then - return false; - else - entries := Difference( Unique( Flat( table )), [ zero ] ); - # zero semigroup is 2-nilpotent - if entries = [ ] then return false; fi; - for i in entries do - if table[i] <> ListWithIdenticalEntries(n, zero) or - table{[1..n]}[i] <> ListWithIdenticalEntries(n, zero) then - return false; - fi; - od; +InstallMethod(EquivalenceSmallSemigroup, "for a semigroup", [IsSemigroup], +function(S) + local size, nr, mt, stab, orbit, diag, perm, diaglits, pos, translits, + n, k, strlist, offset, line, i, tbllits, phi, small, transorbit, isIso, + equi, LitNum, NumLit, tbl2lits, diag2lits, onLiterals, is3nilpotent, + BinInt, imglist, ListToMatrix; + + LitNum := function(ln, n) + return [QuoInt(ln - 1, n ^ 2) + 1, + QuoInt((ln - 1) mod n ^ 2, n) + 1, (ln - 1) mod n + 1]; + end; + + NumLit := {lit, n} -> (lit[1] - 1) * n ^ 2 + (lit[2] - 1) * n + lit[3]; + diag2lits := {diag, n} -> List([1 .. n], i -> NumLit([i, i, diag[i]], n)); + tbl2lits := {table, n} -> SMALLSEMI_TableToLiterals(table, n, NumLit); + onLiterals := n -> SMALLSEMI_OnLiterals(n, LitNum, NumLit); + + is3nilpotent := function(table) + local n, zero, entries, i; + + n := Size(table); + zero := First([1 .. n], i -> table[i] = ListWithIdenticalEntries(n, i) + and table{[1 .. n]}[i] = ListWithIdenticalEntries(n, i)); + if zero = fail then + return false; + else + entries := Difference(Unique(Flat(table)), [zero]); + # zero semigroup is 2-nilpotent + if IsEmpty(entries) then + return false; + fi; + for i in entries do + if table[i] <> ListWithIdenticalEntries(n, zero) or + table{[1 .. n]}[i] <> ListWithIdenticalEntries(n, zero) then + return false; fi; + od; + fi; + return true; + end; - return true; - end; - - BinInt := function( str, bas ) - local int,pot,c; - - int := 0; - pot := 1; - str := Reversed( str ); - for c in str do - int := int + pot*Int([c]); - pot := pot*bas; - od; - - return int; - end; - - ListToMatrix := function( line ) - local mat, ord, i; - - ord := RootInt( Length( line ) ); - mat := EmptyPlist( ord ); - - for i in [ 1..ord ] do - Add( mat, line{[ 1+(i-1)*ord .. i*ord ]} ); - od; - - return mat; - end; + BinInt := SMALLSEMI_BinInt; - if Size( S ) > 8 then - Error("only semigroups with up to 8 elements are contained in", - " the library."); - fi; + ListToMatrix := function(line) + local mat, ord, i; - # special case trivial semigroup - if Size( S ) = 1 then - small := SmallSemigroup(1, 1); - equi := SemigroupHomomorphismByImagesNC(S, small, Elements(S)); - SetIsBijective( equi, true ); + ord := RootInt(Length(line)); + mat := EmptyPlist(ord); - return equi; - fi; + for i in [1 .. ord] do + Add(mat, line{[1 + (i - 1) * ord .. i * ord]}); + od; - n := Size( S ); - mt := MultiplicationTable( S ); - diag := DiagonalOfMat( mt ); - phi := ActionHomomorphism( SymmetricGroup(n), [1..n^3], onLiterals(n) ); - - # get minimal representative of diagonal - diaglits := diag2lits( diag, n ); - orbit := Orbit( Image(phi), diaglits, OnSets ); - perm := RepresentativeAction(Image(phi), diaglits, Minimum(orbit), OnSets); - diag := List( Minimum(orbit), x->LitNum(x,n)[3] ); - - # work with stabiliser of new diagonal on changed table - tbllits := tbl2lits( mt, n ); - tbllits := OnSets( tbllits, perm ); - translits := List( tbllits, lit -> LitNum(lit,n) ); - translits := List( translits, lit -> NumLit( [lit[2],lit[1],lit[3]], n ) ); - translits := AsSet( translits ); - stab := Stabilizer( Image(phi), Minimum(orbit), OnSets); - - # search in list of isomorphic multiplication tables with same diagonal - orbit := Orbit( stab, tbllits, OnSets ); - # ... and anti-isomorphic - transorbit := Orbit( stab, translits, OnSets ); - - # determine whether minimum is isomorphic or anti-isomorphic - if Minimum( orbit ) > Minimum( transorbit ) then - isIso := false; - perm:=perm*RepresentativeAction(Image(phi), - translits, - Minimum(transorbit), - OnSets); - # the equivalent table stored in smallsemi as list - mt := List( Minimum(transorbit), x -> LitNum(x,n)[3]); - else - isIso := true; - perm:=perm*RepresentativeAction(Image(phi), - tbllits, - Minimum(orbit), - OnSets); - # the equivalent table stored in smallsemi as list - mt := List( Minimum(orbit), x -> LitNum(x,n)[3]); - fi; + return mat; + end; - # rest of code expects a matrix, not a list - mt := ListToMatrix( mt ); - - size := n; - # extract from the minimal table the string which is stored in the library - if size <= 7 or not is3nilpotent( mt ) then - pos := Position( MOREDATA2TO8[size].diags, diag ); - offset := MOREDATA2TO8[size].endpositions[pos]; - # ensure data is loaded - RecoverMultiplicationTableNC(size,offset+1); - if size <= 7 then - strlist := DATA2TO7[size-1]; - strlist := List( strlist, st -> st{[offset+1..Length(st)]}); - # translate table to string - line := Concatenation(List( Flat( mt-1 ), int -> String(int))); - # first entry is always equal 1 and thus not stored - Remove( line, 1 ); - else - strlist := DATA8[pos]; - line := Concatenation(List( Flat( mt-1 ), int -> String(int))); - # all non-diagonal entries are stored - for i in [1..8] do - Remove( line, 1+(i-1)*8 ); - od; - fi; - else - k := First( [1..8], i -> mt[i] <> [1,1,1,1,1,1,1,1] or - mt{[1..8]}[i] <> [1,1,1,1,1,1,1,1] ); - ## # special case 2 nilpotent semigroup - ## if k = fail then return [ size, NrSmallSemigroups(8) ]; fi; - pos := Position( MOREDATA2TO8[8].3nildiags, diag{[k..8]} ); - offset := MOREDATA2TO8[8].3nilendpositions[pos] + 11433106; - # ensure data is loaded - RecoverMultiplicationTableNC(size,offset+1); - strlist := 3NIL_DATA.strlist;; - # only non-diagonal entries of the non zero row-columns are stored - line := Concatenation( List( Flat( mt{[k..8]}{[k..8]} - 1 ), - int -> String(int) ) ); - for i in [1..8-k+1] do - Remove( line, 1+(i-1)*(8-k+1) ); - od; - fi; + if Size(S) > 8 then + Error("only semigroups with up to 8 elements are contained in", + " the library."); + fi; - # search for the position of the string in the data lists - if size <= 7 or not is3nilpotent( mt ) then - pos := 1; - for i in [ 1..Length( line ) ] do - while strlist[i][pos] < line[i] do - pos := pos + 1; - od; - od; + # special case trivial semigroup + if Size(S) = 1 then + small := SmallSemigroup(1, 1); + equi := SemigroupHomomorphismByImagesNC(S, small, Elements(S)); + SetIsBijective(equi, true); + return equi; + fi; + + n := Size(S); + mt := MultiplicationTable(S); + diag := DiagonalOfMat(mt); + phi := ActionHomomorphism(SymmetricGroup(n), [1 .. n ^ 3], onLiterals(n)); + + # get minimal representative of diagonal + diaglits := diag2lits(diag, n); + orbit := Orbit(Image(phi), diaglits, OnSets); + perm := RepresentativeAction(Image(phi), diaglits, Minimum(orbit), OnSets); + diag := List(Minimum(orbit), x -> LitNum(x, n)[3]); + + # work with stabiliser of new diagonal on changed table + tbllits := tbl2lits(mt, n); + tbllits := OnSets(tbllits, perm); + translits := List(tbllits, lit -> LitNum(lit, n)); + translits := List(translits, lit -> NumLit([lit[2], lit[1], lit[3]], n)); + translits := AsSet(translits); + stab := Stabilizer(Image(phi), Minimum(orbit), OnSets); + + # search in list of isomorphic multiplication tables with same diagonal + orbit := Orbit(stab, tbllits, OnSets); + # .. . and anti - isomorphic + transorbit := Orbit(stab, translits, OnSets); + + # determine whether minimum is isomorphic or anti - isomorphic + if Minimum(orbit) > Minimum(transorbit) then + isIso := false; + perm := perm * RepresentativeAction(Image(phi), + translits, + Minimum(transorbit), + OnSets); + # the equivalent table stored in smallsemi as list + mt := List(Minimum(transorbit), x -> LitNum(x, n)[3]); + else + isIso := true; + perm := perm * RepresentativeAction(Image(phi), + tbllits, + Minimum(orbit), + OnSets); + # the equivalent table stored in smallsemi as list + mt := List(Minimum(orbit), x -> LitNum(x, n)[3]); + fi; + + # rest of code expects a matrix, not a list + mt := ListToMatrix(mt); + + size := n; + # extract from the minimal table the string which is stored in the library + if size <= 7 or not is3nilpotent(mt) then + pos := Position(MOREDATA2TO8[size].diags, diag); + offset := MOREDATA2TO8[size].endpositions[pos]; + # ensure data is loaded + RecoverMultiplicationTableNC(size, offset + 1); + if size <= 7 then + strlist := DATA2TO7[size - 1]; + strlist := List(strlist, st -> st{[offset + 1 .. Length(st)]}); + # translate table to string + line := Concatenation(List(Flat(mt - 1), String)); + # first entry is always equal 1 and thus not stored + Remove(line, 1); else - pos := 1; - for i in [ 1..Length( line ) ] do - while IsBound(strlist[i][pos]) and strlist[i][pos] < line[i] - and ( not IsBound(strlist[i][pos+1]) - or strlist[i][pos] <= strlist[i][pos+1] ) do - pos := pos + 1; - od; - if not IsBound(strlist[i][pos]) or strlist[i][pos]>line[i] then - pos := pos - 1; - fi; - od; + strlist := DATA8[pos]; + line := Concatenation(List(Flat(mt - 1), String)); + # all non - diagonal entries are stored + for i in [1 .. 8] do + Remove(line, 1 + (i - 1) * 8); + od; fi; - - # fine tuning - while List(strlist, st -> st[pos]) < line and IsBound(strlist[1][pos+1]) do - pos := pos+1; + else + k := First([1 .. 8], i -> mt[i] <> [1, 1, 1, 1, 1, 1, 1, 1] or + mt{[1 .. 8]}[i] <> [1, 1, 1, 1, 1, 1, 1, 1]); + ## special case 2 nilpotent semigroup + ## if k = fail then return [ size, NrSmallSemigroups(8) ]; fi; + pos := Position(MOREDATA2TO8[8].3nildiags, diag{[k .. 8]}); + offset := MOREDATA2TO8[8].3nilendpositions[pos] + 11433106; + # ensure data is loaded + RecoverMultiplicationTableNC(size, offset + 1); + strlist := 3NIL_DATA.strlist; + # only non-diagonal entries of the non zero row-columns are stored + line := Concatenation(List(Flat(mt{[k .. 8]}{[k .. 8]} - 1), String)); + for i in [1 .. 8 - k + 1] do + Remove(line, 1 + (i - 1) * (8 - k + 1)); od; - while List( strlist, st -> st[pos] ) > line do - pos := pos-1; + fi; + + # search for the position of the string in the data lists + if size <= 7 or not is3nilpotent(mt) then + pos := 1; + for i in [1 .. Length(line)] do + while strlist[i][pos] < line[i] do + pos := pos + 1; + od; od; - - # correct number in current data (depending on diagonal) by offset - if size <= 7 or not is3nilpotent( mt ) then - nr := pos + offset; - else - nr := 3NIL_DATA.positions[pos] + offset + BinInt(line, k-1 ) - - BinInt( List( strlist, st -> st[pos] ), k-1 ); - # for safety reasons ... - while mt <> RecoverMultiplicationTableNC( 8, nr ) do - Info( InfoSmallsemi, 1, - "IdSmallSemigroup: That shouldn't really happen."); - nr := nr+1; - od; - fi; - - # the bijection mapping the input or its transposed to a small semigroup - equi := PreImages(phi,[perm])[1]; - small := SmallSemigroup( size, nr ); - imglist := Permuted(AsSSortedList(small), equi^-1); - if isIso then - equi := SemigroupHomomorphismByImagesNC(S, small, imglist); - SetIsBijective( equi, true ); - else - equi := MappingByFunction(S, small, - function(x) - local pos; - pos := Position(AsSSortedList(S),x); - return imglist[pos]; - end ); - SetRespectsMultiplication( equi, false ); - SetIsBijective( equi, true ); - fi; - - return equi; + else + pos := 1; + for i in [1 .. Length(line)] do + while IsBound(strlist[i][pos]) and strlist[i][pos] < line[i] + and (not IsBound(strlist[i][pos + 1]) + or strlist[i][pos] <= strlist[i][pos + 1]) do + pos := pos + 1; + od; + if not IsBound(strlist[i][pos]) or strlist[i][pos] > line[i] then + pos := pos - 1; + fi; + od; + fi; + + # fine tuning + while List(strlist, st -> st[pos]) < line and IsBound(strlist[1][pos + 1]) do + pos := pos + 1; + od; + while List(strlist, st -> st[pos]) > line do + pos := pos - 1; + od; + + # correct number in current data (depending on diagonal) by offset + if size <= 7 or not is3nilpotent(mt) then + nr := pos + offset; + else + nr := 3NIL_DATA.positions[pos] + offset + BinInt(line, k - 1) - + BinInt(List(strlist, st -> st[pos]), k - 1); + # for safety reasons ... + while mt <> RecoverMultiplicationTableNC(8, nr) do + Info(InfoSmallsemi, 1, + "IdSmallSemigroup: That shouldn't really happen."); + nr := nr + 1; + od; + fi; + + # the bijection mapping the input or its transposed to a small semigroup + equi := PreImages(phi, [perm])[1]; + small := SmallSemigroup(size, nr); + imglist := Permuted(AsSSortedList(small), equi ^ -1); + if isIso then + equi := SemigroupHomomorphismByImagesNC(S, small, imglist); + SetIsBijective(equi, true); + else + equi := MappingByFunction(S, + small, + x -> imglist[Position(AsSSortedList(S), x)]); + SetRespectsMultiplication(equi, false); + SetIsBijective(equi, true); + fi; + + return equi; end); -########################################################################### -## -#M IdSmallSemigroup( ) -## -InstallMethod( IdSmallSemigroup, "for a semigroup", [IsSemigroup], 0, -s -> IdSmallSemigroup( Range( EquivalenceSmallSemigroup( s )))); - -########################################################################### -## -#V InfoSmallsemi . . . info class for smallsemi, initial value 1 -## -SetInfoLevel( InfoSmallsemi, 1 ); +InstallMethod(IdSmallSemigroup, "for a semigroup", [IsSemigroup], +s -> IdSmallSemigroup(Range(EquivalenceSmallSemigroup(s)))); - -########################################################################### -## -#M IsomorphismTransformationSemigroup( ); -## -## converts a small semigroup into an isomorphic transformation semigroup. -## -## The reference documentation states monoids are embedded in T_n! AD -## +SetInfoLevel(InfoSmallsemi, 1); InstallMethod(IsomorphismTransformationSemigroup, [IsSmallSemigroup], function(S) @@ -307,7 +256,6 @@ function(S) table := TransposedMat(MultiplicationTable(S)); map := x -> TransformationNC(Concatenation(table[x!.index], [x!.index])); - T := Semigroup(List(MinimalGeneratingSet(S), map)); SetSize(T, Size(S)); SetMultiplicationTable(T, MultiplicationTable(S)); @@ -320,151 +268,133 @@ function(S) return iso; end); -########################################################################### -## -#F RecoverMultiplicationTable( , ) -#F RecoverMultiplicationTableNC( , ) -## -InstallGlobalFunction( RecoverMultiplicationTable, function( size, nr ) - local numbers; +InstallGlobalFunction(RecoverMultiplicationTable, function(size, nr) + local numbers; - # numbers of semigroups of sizes 1-8 - numbers := [ 1, 4, 18, 126, 1160, 15973, 836021, 1843120128 ]; + # numbers of semigroups of sizes 1 - 8 + numbers := [1, 4, 18, 126, 1160, 15973, 836021, 1843120128]; - if size > 8 or nr > numbers[ size ] then - return fail; - else - return RecoverMultiplicationTableNC( size, nr ); - fi; + if size > 8 or nr > numbers[size] then + return fail; + fi; + return RecoverMultiplicationTableNC(size, nr); end); -InstallGlobalFunction( RecoverMultiplicationTableNC, function( size, nr ) - local flatmat, ListToMatrix, i, data, file, pos, diag, k, mat, - int, rem, line, BinInt, m, j; +InstallGlobalFunction(RecoverMultiplicationTableNC, +function(size, nr) + local flatmat, ListToMatrix, i, data, file, pos, diag, k, mat, + int, rem, line, m, j; - if size = 1 then - return [[ 1 ]]; - fi; + if size = 1 then + return [[1]]; + fi; - # converts a list into the corresponding multiplication table - ListToMatrix := function( line ) - local mat,i; + # converts a list into the corresponding multiplication table + ListToMatrix := function(line) + local mat, i; - mat := EmptyPlist( size ); + mat := EmptyPlist(size); - for i in [ 1..size ] do - Add( mat, line{[ 1+(i-1)*size .. i*size ]} ); - od; - - return mat; - end; - - # returns the integer represented by with characters in [0-] - BinInt := function( str, bas ) - local int,pot,c; - - int := 0; - pot := 1; - str := Reversed( str ); - for c in str do - int := int + pot*Int([c]); - pot := pot*bas; - od; + for i in [1 .. size] do + Add(mat, line{[1 + (i - 1) * size .. i * size]}); + od; - return int; - end; + return mat; + end; # check whether data is already available, read otherwise - if size < 8 then - if not IsBound( DATA2TO7[ size-1 ] ) then - if size = 7 then - Info( InfoSmallsemi, 1, - "Smallsemi: loading data for semigroups of size 7." ); - fi; - file := Filename( DirectoriesPackageLibrary( "smallsemi", - "data/data2to7" ), - Concatenation( "data", String(size), ".gl" )); - DATA2TO7[ size-1 ] := SplitString( StringFile( file ), "\n" ); - # remove copyright - Remove( DATA2TO7[ size-1 ], 1 ); - fi; - data := DATA2TO7[ size-1 ]; - - elif nr <= 11433106 then # size = 8 - pos := PositionProperty( MOREDATA2TO8[8].endpositions, i -> i >= nr ); - diag := MOREDATA2TO8[8].diags[ pos-1 ]; - if pos-1 <> PositionBound( DATA8 ) then - if IsInt( PositionBound( DATA8 )) then - Unbind( DATA8[ PositionBound( DATA8 ) ] ); - fi; - Info( InfoSmallsemi, 1, - "Smallsemi: loading data for semigroups of size 8." ); - file := Filename( DirectoriesPackageLibrary( "smallsemi", - "data/data8" ), - Concatenation( "8diag", - Concatenation(List(diag,String)), - ".gl" )); - DATA8[ pos-1 ] := SplitString( StringFile( file ), "\n" ); - # remove copyright - Remove( DATA8[ pos-1 ], 1 ); - fi; - data := DATA8[ pos-1 ]; - nr := nr - MOREDATA2TO8[8].endpositions[ pos-1 ]; - - else # 3-nilpotent semigroup + if size < 8 then + if not IsBound(DATA2TO7[size - 1]) then + if size = 7 then + Info(InfoSmallsemi, 1, + "Smallsemi: loading data for semigroups of size 7."); + fi; + file := Filename(DirectoriesPackageLibrary("smallsemi", + "data/data2to7"), + Concatenation("data", String(size), ".gl")); + DATA2TO7[size - 1] := SplitString(StringFile(file), "\n"); + # remove copyright + Remove(DATA2TO7[size - 1], 1); + fi; + data := DATA2TO7[size - 1]; + + elif nr <= 11433106 then # size = 8 + pos := PositionProperty(MOREDATA2TO8[8].endpositions, i -> i >= nr); + diag := MOREDATA2TO8[8].diags[pos - 1]; + if pos - 1 <> PositionBound(DATA8) then + if IsInt(PositionBound(DATA8)) then + Unbind(DATA8[PositionBound(DATA8)]); + fi; + Info(InfoSmallsemi, 1, + "Smallsemi: loading data for semigroups of size 8."); + file := Filename(DirectoriesPackageLibrary("smallsemi", + "data/data8"), + Concatenation("8diag", + Concatenation(List(diag, String)), + ".gl")); + DATA8[pos - 1] := SplitString(StringFile(file), "\n"); + # remove copyright + Remove(DATA8[pos - 1], 1); + fi; + data := DATA8[pos - 1]; + nr := nr - MOREDATA2TO8[8].endpositions[pos - 1]; + + else # 3 - nilpotent semigroup # CODE HAS TO BE REVISED, UGLY CODING AND MISLEADING VARIABLE NAMES AD # get correct diagonal, adjust number - nr := nr - 11433106; - pos := PositionProperty( MOREDATA2TO8[8].3nilendpositions, i->i>=nr ); - diag := MOREDATA2TO8[8].3nildiags[ pos-1 ]; + nr := nr - 11433106; + pos := PositionProperty(MOREDATA2TO8[8].3nilendpositions, i -> i >= nr); + diag := MOREDATA2TO8[8].3nildiags[pos - 1]; if diag <> 3NIL_DATA.diag then - Info( InfoSmallsemi, 1, - "Smallsemi: loading data for semigroups of size 8." ); - READ_3NIL_DATA( diag ); + Info(InfoSmallsemi, 1, + "Smallsemi: loading data for semigroups of size 8."); + READ_3NIL_DATA(diag); fi; - nr := nr - MOREDATA2TO8[8].3nilendpositions[pos-1]; + nr := nr - MOREDATA2TO8[8].3nilendpositions[pos - 1]; # search from which stored solution to start from - for pos in [ 3NIL_DATA.next..Length(3NIL_DATA.positions) ] do - if 3NIL_DATA.positions[ pos-1 ] <= nr - and 3NIL_DATA.positions[ pos ] > nr then + for pos in [3NIL_DATA.next .. Length(3NIL_DATA.positions)] do + if 3NIL_DATA.positions[pos - 1] <= nr + and 3NIL_DATA.positions[pos] > nr then 3NIL_DATA.next := pos; - pos := pos-1; + pos := pos - 1; break; fi; od; - if Length(3NIL_DATA.positions) = 1 then pos := 1; fi; - if 3NIL_DATA.positions[ pos ] > nr then - for pos in [ 1..3NIL_DATA.next - 1 ] do - if 3NIL_DATA.positions[ pos ] > nr then + if Length(3NIL_DATA.positions) = 1 then + pos := 1; + fi; + if 3NIL_DATA.positions[pos] > nr then + for pos in [1 .. 3NIL_DATA.next - 1] do + if 3NIL_DATA.positions[pos] > nr then 3NIL_DATA.next := pos; - pos := pos-1; + pos := pos - 1; break; fi; od; - elif 3NIL_DATA.next <> pos+1 then + elif 3NIL_DATA.next <> pos + 1 then 3NIL_DATA.next := pos; fi; - m := Length( 3NIL_DATA.diag ); - line := List( [ 1..m^2-m ], i -> 3NIL_DATA.strlist[i][pos] ); + m := Length(3NIL_DATA.diag); + line := List([1 .. m ^ 2 - m], i -> 3NIL_DATA.strlist[i][pos]); - int := BinInt( line, 8-m ); - int := int + ( nr - 3NIL_DATA.positions[pos] ); + int := SMALLSEMI_BinInt(line, 8 - m); + int := int + (nr - 3NIL_DATA.positions[pos]); - mat := StructuralCopy( BLUEPRINT_MATS[8-m] ); + mat := StructuralCopy(BLUEPRINT_MATS[8 - m]); # based on 'IntBit' but putting values directly into matrix - for i in [ 1..m ] do - for j in [ 1..i-1 ] do - rem := RemInt( int, 8-m ); - int := (int - rem) / (8-m); - mat[9-i][9-j] := rem + 1; + for i in [1 .. m] do + for j in [1 .. i - 1] do + rem := RemInt(int, 8 - m); + int := (int - rem) / (8 - m); + mat[9 - i][9 - j] := rem + 1; od; - mat[9-i][9-i] := 3NIL_DATA.diag[m-i+1]; - for j in [ i+1..m ] do - rem := RemInt( int, 8-m ); - int := (int - rem) / (8-m); - mat[9-i][9-j] := rem + 1; + mat[9 - i][9 - i] := 3NIL_DATA.diag[m - i + 1]; + for j in [i + 1 .. m] do + rem := RemInt(int, 8 - m); + int := (int - rem) / (8 - m); + mat[9 - i][9 - j] := rem + 1; od; od; @@ -472,425 +402,304 @@ InstallGlobalFunction( RecoverMultiplicationTableNC, function( size, nr ) fi; # set up list with first idempotent - flatmat := EmptyPlist( size^2 ); + flatmat := EmptyPlist(size ^ 2); flatmat[1] := 1; if size = 8 then - for i in [ 1..7 ] do - for k in [ 1..8 ] do - flatmat[ 1+k+9*(i-1) ] := INT_CHAR(data[ k+8*(i-1) ][nr])-47; - od; - flatmat[ 1+9*i ] := diag[i+1]; + for i in [1 .. 7] do + for k in [1 .. 8] do + flatmat[1 + k + 9 * (i - 1)] := + INT_CHAR(data[k + 8 * (i - 1)][nr]) - 47; od; + flatmat[1 + 9 * i] := diag[i + 1]; + od; else - for i in [ 2..size^2 ] do - flatmat[i] := INT_CHAR( data[i-1][nr] ) - 47; - od; + for i in [2 .. size ^ 2] do + flatmat[i] := INT_CHAR(data[i - 1][nr]) - 47; + od; fi; - return ListToMatrix( flatmat ); + return ListToMatrix(flatmat); end); -########################################################################### -## -#F SmallSemigroupCreator( ) -## - InstallGlobalFunction(SmallSemigroupCreator, -function ( A ) -local elms, M; +function(A) + local elms, S; -M:=Objectify(SmallSemigroupType, rec(table:=A));; -SetIsAssociative(M, true); -SetSize( M, Length(A)); + S := Objectify(SmallSemigroupType, rec(table := A)); + SetIsAssociative(S, true); + SetSize(S, Length(A)); -elms := Immutable( List( [1..Length(A)], function ( i ) return -Objectify( SmallSemigroupEltType, rec( index:=i, semi:=M) ); end ) ); + elms := Immutable(List([1 .. Length(A)], + i -> Objectify(SmallSemigroupEltType, + rec(index := i, semi := S)))); -SetIsSSortedList( elms, true ); -SetGeneratorsOfMagma(M, elms); -SetAsSSortedList( M, elms ); -SetMultiplicationTable( M, A ); + SetIsSSortedList(elms, true); + SetGeneratorsOfMagma(S, elms); + SetAsSSortedList(S, elms); + SetMultiplicationTable(S, A); -return M; + return S; end); -########################################################################### -## -#F SemigroupByMultiplicationTableNC( ) -## -InstallGlobalFunction( SemigroupByMultiplicationTableNC, function( A ) - A:= MagmaByMultiplicationTable( A ); - SetIsAssociative( A, true ); +InstallGlobalFunction(SemigroupByMultiplicationTableNC, +function(A) + A := MagmaByMultiplicationTable(A); + SetIsAssociative(A, true); + return A; +end); - return A; -end ); +InstallGlobalFunction(SmallSemigroup, +function(arg...) + local size, nr; + + if Length(arg) = 2 and ForAll(arg, IsPosInt) then + size := arg[1]; + nr := arg[2]; + elif Length(arg) = 1 and ForAll(arg[1], IsPosInt) then + size := arg[1][1]; + nr := arg[1][2]; + else + Error("the argument must be 2 positive integers or a", + " list of 2 positive integers"); + fi; + + while size > 8 do; + Error("semigroups of size ", size, " are not available, \n", + "you can change the value of < size > and 'return;'\n"); + od; + + while nr > NrSmallSemigroups(size) do + Error("there are only ", + NrSmallSemigroups(size), + " semigroups of size ", + size, + ", \nyou can change the value of and 'return;'\n"); + od; + return SmallSemigroupNC(size, nr); +end); +InstallGlobalFunction(SmallSemigroupNC, +function(size, nr) + local table, S; -########################################################################### -## -#F SmallSemigroup( , ) -## + table := RecoverMultiplicationTableNC(size, nr); + S := SmallSemigroupCreator(table); + SetIdSmallSemigroup(S, [Size(S), nr]); + return S; +end); -InstallGlobalFunction( SmallSemigroup, -function( arg ) -local table, S, size, nr; - -if Length(arg)=2 and ForAll(arg, IsPosInt) then - size:=arg[1]; - nr:=arg[2]; -elif Length(arg)=1 and ForAll(arg[1], IsPosInt) then - size:=arg[1][1]; - nr:=arg[1][2]; -else - Error( "input must be 2 positive integers or a list of 2 positive integers" ); -fi; - -while size > 8 do; - Error( "semigroups of size ", size, " are not available,\n", - "you can change the value of and 'return;'\n" ); -od; - -while nr > NrSmallSemigroups(size) do - Error( "there are only ", NrSmallSemigroups(size), " semigroups of size ", - size, ",\n", - "you can change the value of and 'return;'\n" ); -od; - -return SmallSemigroupNC( size, nr ); -end ); - -########################################################################### -## -#F SmallSemigroupNC( , ) -## +InstallGlobalFunction(UnloadSmallsemiData, function(uselater) + local pos; -InstallGlobalFunction( SmallSemigroupNC, -function( size, nr ) -local table, s; + # unbind data for semigroups sizes 2 to 7 + for pos in [1 .. 6] do + Unbind(DATA2TO7[pos]); + od; -table := RecoverMultiplicationTableNC( size, nr ); -s:=SmallSemigroupCreator(table); -SetIdSmallSemigroup(s, [Size(s), nr]); -return s; -end ); + # unbind data for semigroups size 8 which are not 3 - nilpotent + pos := PositionBound(DATA8); + if pos <> fail then + Unbind(DATA8[pos]); + fi; -############################################################################ -## -#F UnloadSmallsemiData( ) -## -InstallGlobalFunction( UnloadSmallsemiData, function( uselater ) - local pos; - - # unbind data for semigroups sizes 2 to 7 - for pos in [1..6] do - Unbind( DATA2TO7[pos] ); - od; - - # unbind data for semigroups size 8 which are not 3-nilpotent - pos := PositionBound( DATA8 ); - if pos <> fail then - Unbind( DATA8[pos] ); - fi; - - # unbind data for semigroups size 8 which are 3-nilpotent - 3NIL_DATA.diag := fail ; - Unbind( 3NIL_DATA.strlist ); - Unbind( 3NIL_DATA.positions ); - Unbind( 3NIL_DATA.next ); - - # unbind data essential for the use of smallsemi - if not uselater then - - for pos in [2..7] do - Unbind( BLUEPRINT_MATS[pos] ); - od; - - # unbind data records from info files - for pos in [1..8] do - Unbind( MOREDATA2TO8[pos] ); - od; - - fi; -end); + # unbind data for semigroups size 8 which are 3 - nilpotent + 3NIL_DATA.diag := fail ; + Unbind(3NIL_DATA.strlist); + Unbind(3NIL_DATA.positions); + Unbind(3NIL_DATA.next); + # unbind data essential for the use of smallsemi + if not uselater then -###################### -## GLOBAL VARIABLES ## -###################### + for pos in [2 .. 7] do + Unbind(BLUEPRINT_MATS[pos]); + od; -############################################################################# -## -#V 3NIL_DATA . . . record carrying the current 3-nilpotent data -## -InstallFlushableValue( 3NIL_DATA, rec( diag := fail ) ); + # unbind data records from info files + for pos in [1 .. 8] do + Unbind(MOREDATA2TO8[pos]); + od; + fi; +end); ############################################################################# -## -#V DATA2TO7 . . . raw data for semigroup tables sizes 2-7 -## -InstallFlushableValue( DATA2TO7, [ ] ); - - +# GLOBAL VARIABLES ############################################################################# -## -#V DATA8 . . . raw data for semigroup tables size 8 -## -InstallFlushableValue( DATA8, [ ] ); - -######################## -## INTERNAL FUNCTIONS ## -######################## +InstallFlushableValue(3NIL_DATA, rec(diag := fail)); +InstallFlushableValue(DATA2TO7, []); +InstallFlushableValue(DATA8, []); ############################################################################# -## -#F GENERATE_BLUEPRINT_MATS -## -InstallGlobalFunction( GENERATE_BLUEPRINT_MATS, function( ) - local mats, k, i; - - mats := EmptyPlist( 7 ); - for k in [ 2..7 ] do - # size 8 matrix - mats[k] := EmptyPlist( 8 ); - # first k zero rows (the zero is '1') - for i in [ 1..k ] do - mats[k][i] := ListWithIdenticalEntries( 8, 1 ); - od; - # zero columns (the zero is '1') - for i in [ k+1..8 ] do - mats[k][i] := ListWithIdenticalEntries( k, 1 ); - od; - od; - - return mats; -end); +# INTERNAL FUNCTIONS +############################################################################# +InstallGlobalFunction(GENERATE_BLUEPRINT_MATS, function() + local mats, k, i; -############################################################################# -## -#F READ_3NIL_DATA( ) -## -InstallGlobalFunction( READ_3NIL_DATA, function( diag ) - local diagstr, file, posdiffs, i; - - # set diagonal - 3NIL_DATA.diag := diag; - diagstr := Concatenation( List( diag, String )); - - # read cayle table data - file := Filename( DirectoriesPackageLibrary("smallsemi","data/data8-3nil"), - Concatenation( "diag", diagstr, ".gl" )); - 3NIL_DATA.strlist := SplitString( StringFile( file ), "\n" );; - # remove copyright - Remove( 3NIL_DATA.strlist, 1 ); - - # read position differences information - file := Filename( DirectoriesPackageLibrary("smallsemi","data/data8-3nil"), - Concatenation( "diag", diagstr, "pos.gl" )); - posdiffs := EvalString( StringFile( file )); - - # create actual position list - 3NIL_DATA.positions := [ posdiffs[1] ]; - for i in [ 2..Length( posdiffs ) ] do - 3NIL_DATA.positions[i] := 3NIL_DATA.positions[i-1] + posdiffs[i]; + mats := EmptyPlist(7); + for k in [2 .. 7] do + # size 8 matrix + mats[k] := EmptyPlist(8); + # first k zero rows (the zero is '1') + for i in [1 .. k] do + mats[k][i] := ListWithIdenticalEntries(8, 1); od; + # zero columns (the zero is '1') + for i in [k + 1 .. 8] do + mats[k][i] := ListWithIdenticalEntries(k, 1); + od; + od; - # reset counter - 3NIL_DATA.next := 2; + return mats; end); +InstallGlobalFunction(READ_3NIL_DATA, function(diag) + local diagstr, file, posdiffs, i; + + # set diagonal + 3NIL_DATA.diag := diag; + diagstr := Concatenation(List(diag, String)); + + # read cayle table data + file := Filename(DirectoriesPackageLibrary("smallsemi", "data/data8-3nil"), + Concatenation("diag", + diagstr, + ".gl")); + 3NIL_DATA.strlist := SplitString(StringFile(file), "\n"); + # remove copyright + Remove(3NIL_DATA.strlist, 1); + + # read position differences information + file := Filename(DirectoriesPackageLibrary("smallsemi", "data/data8-3nil"), + Concatenation("diag", + diagstr, + "pos.gl")); + posdiffs := EvalString(StringFile(file)); + + # create actual position list + 3NIL_DATA.positions := [posdiffs[1]]; + for i in [2 .. Length(posdiffs)] do + 3NIL_DATA.positions[i] := 3NIL_DATA.positions[i - 1] + posdiffs[i]; + od; + + # reset counter + 3NIL_DATA.next := 2; +end); -########################################################################### -## -#F READ_MOREDATA2TO8( ) -## -InstallGlobalFunction( READ_MOREDATA2TO8, +InstallGlobalFunction(READ_MOREDATA2TO8, function() -local dir, files, md, n, file, i, prop; -dir:=DirectoriesPackageLibrary( "smallsemi", "data"); - -Info( InfoSmallsemi, 1, - "Smallsemi: loading data for semigroup properties. Please be patient." ); - -md:=[]; - -for n in [1..8] do - file:=Filename(dir, Concatenation("info", String(n), ".g")); - if not file=fail then - md[n]:=EvalString(StringFile(file)); - else - md[n]:=rec(); - fi; - for prop in Filtered( RecNames(md[n]),x->IsUpperAlphaChar(x[1])) do - # for position lists with more than one entry the first entry - # and the differences are stored; recover actual position list - if Length( md[n].(prop) ) >= 2 then - for i in [ 2..Length( md[n].(prop) ) ] do - md[n].(prop)[i] := md[n].(prop)[i-1] + md[n].(prop)[i]; - od; - fi; - od; -od; + local dir, md, n, file, i, prop; + dir := DirectoriesPackageLibrary("smallsemi", "data"); -return md; + Info(InfoSmallsemi, 1, + "Smallsemi: loading data for semigroup properties. Please be patient."); -end); + md := []; + for n in [1 .. 8] do + file := Filename(dir, Concatenation("info", String(n), ".g")); + if file <> fail then + md[n] := EvalString(StringFile(file)); + else + md[n] := rec(); + fi; + for prop in Filtered(RecNames(md[n]), x -> IsUpperAlphaChar(x[1])) do + # for position lists with more than one entry the first entry + # and the differences are stored; recover actual position list + if Length(md[n].(prop)) >= 2 then + for i in [2 .. Length(md[n].(prop))] do + md[n].(prop)[i] := md[n].(prop)[i - 1] + md[n].(prop)[i]; + od; + fi; + od; + od; + return md; +end); ############################################################################ -## -## Methods for 'Small Semigroups' -## -############################################################################# -## -#M \=( , ) . . . for two objects in IsSmallSemigroup -## - -InstallMethod( \=, "for two small semis", IsIdenticalObj, - [ IsSmallSemigroup, IsSmallSemigroup ], 10, - function( x, y ) - return IdSmallSemigroup(x)=IdSmallSemigroup(y); - end ); +# Methods for 'Small Semigroups' +############################################################################ -InstallMethod( \<, "for two small semis", IsIdenticalObj, [IsSmallSemigroup, - IsSmallSemigroup], - function( x , y ) - return IdSmallSemigroup(x) IdSmallSemigroup(x) = IdSmallSemigroup(y)); +InstallMethod(\<, "for two small semis", IsIdenticalObj, +[IsSmallSemigroup, IsSmallSemigroup], +{x, y} -> IdSmallSemigroup(x) < IdSmallSemigroup(y)); -############################################################################# -## -#M Representative( ) . . . for an object in IsSmallSemigroup -## -InstallMethod( Representative, "for a small semigroup", [ IsSmallSemigroup ], -x-> Elements(x)[1] ); +InstallMethod(Representative, "for a small semigroup", [IsSmallSemigroup], +x -> Elements(x)[1]); -############################################################################# -## -#M PrintObj( ) . . . for an object in IsSmallSemigroup -## InstallMethod(PrintObj, "for a small semigroup", [IsSmallSemigroup], function(x) -Print(""); -return; + Print(""); end); -############################################################################# -## -#M String( ) . . . for an object in IsSmallSemigroup -## InstallMethod(String, "for a small semigroup", [IsSmallSemigroup], -function(x) -return Concatenation(""); -end); +x -> Concatenation("")); -############################################################################# -## -#M ViewObj( ) . . . for an object in IsSmallSemigroup -## InstallMethod(ViewObj, "for a small semigroup", [IsSmallSemigroup], function(x) -Print(""); -return; + Print(""); end); - ############################################################################ -## -## Methods for 'Small Semigroup Elements' -## +# Methods for 'Small Semigroup Elements' ############################################################################# -## -#M \=( , ) . . . for two objects in IsSmallSemigroupElt -#M \<( , ) . . . for two objects in IsSmallSemigroupElt -#M \*( , ) . . . for two objects in IsSmallSemigroupElt -## -InstallMethod( \=, - "for two elements of a small semi", - IsIdenticalObj, - [ IsSmallSemigroupElt, - IsSmallSemigroupElt ], - function( x, y ) return x!.index = y!.index and x!.semi=y!.semi; end ); - -InstallMethod( \<, - "for two elements of a small semi", - IsIdenticalObj, - [ IsSmallSemigroupElt, - IsSmallSemigroupElt ], - function( x, y ) return x!.index < y!.index and x!.semi=y!.semi; end ); - -InstallMethod( \*, - "for two elements of a small semi", - IsIdenticalObj, - [ IsSmallSemigroupElt, - IsSmallSemigroupElt ], - function( x, y ) - local table; - if x!.semi=y!.semi then - table:=x!.semi!.table; - return AsList(x!.semi)[table[ x!.index ][ y!.index ]]; - else - Error( "cannot multiply elements from different semigroups in ", - "'Smallsemi'" ); - fi; - end ); -############################################################################# -## -#M OneOp( ) . . . for an object in IsSmallSemigroupElt -## -InstallOtherMethod(OneOp, "for a small semigroup elt", [ IsSmallSemigroupElt ], -function( x ) -local table, pos; +InstallMethod(\=, "for two elements of a small semi", +IsIdenticalObj, [IsSmallSemigroupElt, IsSmallSemigroupElt], +{x, y} -> x!.index = y!.index and x!.semi = y!.semi); + +InstallMethod(\<, "for two elements of a small semi", +IsIdenticalObj, [IsSmallSemigroupElt, IsSmallSemigroupElt], +{x, y} -> x!.index < y!.index and x!.semi = y!.semi); + +InstallMethod(\*, "for two elements of a small semi", +IsIdenticalObj, [IsSmallSemigroupElt, IsSmallSemigroupElt], +function(x, y) + local table; + if x!.semi = y!.semi then + table := x!.semi!.table; + return AsList(x!.semi)[table[x!.index][y!.index]]; + fi; + Error("cannot multiply elements from different semigroups in ", + "'Smallsemi'"); +end); + +InstallOtherMethod(OneOp, "for a small semigroup elt", +[IsSmallSemigroupElt], +function(x) + local table, pos; -table:=x!.semi!.table; -pos:=Position(table, [1..Length(table)]); + table := x!.semi!.table; + pos := Position(table, [1 .. Length(table)]); -if not pos=fail then - if List(table, x-> x[pos])=[1..Length(table)] then - return AsList(x!.semi)[pos]; - fi; -fi; + if pos <> fail then + if List(table, x -> x[pos]) = [1 .. Length(table)] then + return AsList(x!.semi)[pos]; + fi; + fi; -return fail; + return fail; end); -############################################################################# -## -#M PrintObj( ) . . . for an object in IsSmallSemigroupElt -## -InstallMethod(PrintObj, "for a small semigroup elt", [IsSmallSemigroupElt], +InstallMethod(PrintObj, "for a small semigroup elt", [IsSmallSemigroupElt], function(x) -Print("s", x!.index); -return; + Print("s", x!.index); end); -############################################################################# -## -#M String( ) . . . for an object in IsSmallSemigroupElt -## InstallMethod(String, "for a small semigroup elt", [IsSmallSemigroupElt], -function(x) -return Concatenation("s", String(x!.index)); -end); +x -> Concatenation("s", String(x!.index))); -############################################################################# -## -#M ViewObj( ) . . . for an object in IsSmallSemigroupElt -## InstallMethod(ViewObj, "for a small semigroup elt", [IsSmallSemigroupElt], function(x) -Print("s", x!.index); -return; -end); -InstallMethod(ViewString, "for a small semigroup elt", [IsSmallSemigroupElt], -function(x) -return Concatenation("s", String(x!.index)); + Print("s", x!.index); end); - -#JDM include InverseOp? +InstallMethod(ViewString, "for a small semigroup elt", [IsSmallSemigroupElt], +x -> Concatenation("s", String(x!.index))); diff --git a/gap/utils.gd b/gap/utils.gd index fa94d29..e65da68 100644 --- a/gap/utils.gd +++ b/gap/utils.gd @@ -1,7 +1,7 @@ ############################################################################# ## -#W utils.gd Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2012 Andreas Distler & James D. Mitchell +## utils.gd Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## diff --git a/gap/utils.gi b/gap/utils.gi index 2a3b15d..a8c971b 100644 --- a/gap/utils.gi +++ b/gap/utils.gi @@ -1,7 +1,7 @@ ############################################################################# ## -#W utils.gi Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2014 Andreas Distler & James D. Mitchell +## utils.gi Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## @@ -14,18 +14,20 @@ function() record := rec(); record.InfoWarningLevel := InfoLevel(InfoWarning); SetInfoLevel(InfoWarning, 0); - Read(Filename(DirectoriesPackageLibrary("smallsemi","tst"),"testall.g"));; + Read(Filename(DirectoriesPackageLibrary("smallsemi", "tst"), "testall.g")); SetInfoLevel(InfoWarning, record.InfoWarningLevel); return; end); InstallGlobalFunction(SmallsemiManualExamples, function() - return ExtractExamples(DirectoriesPackageLibrary("smallsemi","doc"), - "smallsemi.xml", [ "data.xml", "examples.xml", "intro.xml", - "../gap/coclass.gd", "../gap/enums.gd", "../gap/greensstar.gd", - "../gap/properties.gd", "../gap/small.gd", "../gap/autovars.g", - "../PackageInfo.g" ], "Single"); + return ExtractExamples(DirectoriesPackageLibrary("smallsemi", "doc"), + "smallsemi.xml", + ["data.xml", "examples.xml", "intro.xml", + "../gap/3nil.gd", "../gap/coclass.gd", + "../gap/enums.gd", "../gap/greensstar.gd", + "../gap/properties.gd", "../gap/small.gd", + "../gap/autovars.g", "../PackageInfo.g"], "Single"); end); InstallGlobalFunction(SmallsemiTestManualExamples, @@ -39,9 +41,9 @@ function() SetInfoLevel(InfoWarning, 0); SetInfoLevel(InfoSmallsemi, 0); - RunExamples(SmallsemiManualExamples()); + RunExamples(SmallsemiManualExamples(), + rec(compareFunction := "uptowhitespace")); SetInfoLevel(InfoWarning, record.InfoWarningLevel); SetInfoLevel(InfoSmallsemi, record.InfoSmallsemiLevel); - return; end); diff --git a/init.g b/init.g index 76c49ce..cba9e85 100644 --- a/init.g +++ b/init.g @@ -1,7 +1,7 @@ ############################################################################# ## -#W init.g Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2015 Andreas Distler & James D. Mitchell +## init.g Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## @@ -14,8 +14,9 @@ ReadPackage("smallsemi", "gap/enums.gd"); ReadPackage("smallsemi", "gap/utils.gd"); ReadPackage("smallsemi", "gap/greensstar.gd"); ReadPackage("smallsemi", "gap/coclass.gd"); +ReadPackage("smallsemi", "gap/3nil.gd"); -DeclareAutoreadableVariables( "smallsemi", "gap/autovars.g", - [ "MOREDATA2TO8", - "PrecomputedSmallSemisInfo", - "BLUEPRINT_MATS" ] ); +DeclareAutoreadableVariables("smallsemi", "gap/autovars.g", + ["MOREDATA2TO8", + "PrecomputedSmallSemisInfo", + "BLUEPRINT_MATS"]); diff --git a/read.g b/read.g index 9617526..3aeb821 100644 --- a/read.g +++ b/read.g @@ -1,7 +1,7 @@ ############################################################################# ## -#W read.g Smallsemi - a GAP library of semigroups -#Y Copyright (C) 2008-2015 Andreas Distler & James D. Mitchell +## read.g Smallsemi - a GAP library of semigroups +## Copyright (C) 2008-2024 Andreas Distler & James D. Mitchell ## ## Licensing information can be found in the README file of this package. ## @@ -14,3 +14,4 @@ ReadPackage("smallsemi", "gap/enums.gi"); ReadPackage("smallsemi", "gap/utils.gi"); ReadPackage("smallsemi", "gap/greensstar.gi"); ReadPackage("smallsemi", "gap/coclass.gi"); +ReadPackage("smallsemi", "gap/3nil.gi"); diff --git a/tst/smallsemi02.tst b/tst/smallsemi02.tst index ea524d8..e93172b 100644 --- a/tst/smallsemi02.tst +++ b/tst/smallsemi02.tst @@ -10,7 +10,7 @@ # gap> START_TEST("smallsemi02.tst"); -# doc/../gap/small.gd:231-238 +# doc/../gap/small.gd:204-211 gap> SmallSemigroup(8,1353452); gap> SmallSemigroupNC(5,1); @@ -18,7 +18,7 @@ gap> SmallSemigroupNC(5,1); gap> SmallSemigroupNC(5,1)=SmallSemigroup(5,1); true -# doc/../gap/small.gd:96-104 +# doc/../gap/small.gd:81-89 gap> sgrp:=RandomSmallSemigroup(5); gap> IsSmallSemigroup(sgrp); @@ -27,53 +27,54 @@ gap> sgrp:=Semigroup(Transformation([1]));; gap> IsSmallSemigroup(sgrp); false -# doc/../gap/small.gd:125-131 +# doc/../gap/small.gd:106-112 gap> IsSmallSemigroupElt(Transformation([1])); false gap> sgrp:=RandomSmallSemigroup(5);; gap> IsSmallSemigroupElt(Random(sgrp)); true -# doc/../gap/small.gd:155-169 +# doc/../gap/small.gd:135-149 gap> RecoverMultiplicationTable(10,2); fail -gap> RecoverMultiplicationTable(1,2); +gap> RecoverMultiplicationTable(1,2); fail gap> RecoverMultiplicationTable(2,1); [ [ 1, 1 ], [ 1, 1 ] ] gap> RecoverMultiplicationTable(8,11111111); -[ [ 1, 1, 1, 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1, 1, 1, 3 ], - [ 3, 3, 3, 3, 3, 3, 3, 3 ], [ 1, 1, 1, 4, 4, 4, 4, 1 ], - [ 1, 2, 3, 4, 5, 6, 7, 1 ], [ 1, 2, 3, 4, 5, 6, 7, 1 ], +[ [ 1, 1, 1, 1, 1, 1, 1, 1 ], [ 1, 1, 1, 1, 1, 1, 1, 3 ], + [ 3, 3, 3, 3, 3, 3, 3, 3 ], [ 1, 1, 1, 4, 4, 4, 4, 1 ], + [ 1, 2, 3, 4, 5, 6, 7, 1 ], [ 1, 2, 3, 4, 5, 6, 7, 1 ], [ 1, 2, 3, 4, 5, 6, 7, 1 ], [ 8, 8, 8, 8, 8, 8, 8, 8 ] ] gap> RecoverMultiplicationTable(2,11111111); fail -# doc/../gap/small.gd:198-203 +# doc/../gap/small.gd:175-180 gap> s:=SemigroupByMultiplicationTableNC([[1,2],[2,1]]); gap> IsSmallSemigroup(s); false -# doc/../gap/small.gd:46-50 -gap> sgrp:=Semigroup(Transformation( [ 1, 2, 2 ] ), Transformation( [ 1, 2, 3 ] ));; +# doc/../gap/small.gd:40-45 +gap> sgrp := Semigroup(Transformation([1, 2, 2]), +> Transformation([1, 2, 3]));; gap> IdSmallSemigroup(sgrp); [ 2, 3 ] -# doc/../gap/small.gd:23-29 -gap> sgrp:=Semigroup(Transformation( [ 1, 2, 2 ] ), +# doc/../gap/small.gd:20-26 +gap> sgrp:=Semigroup(Transformation( [ 1, 2, 2 ] ), > Transformation( [ 1, 2, 3 ] ));; gap> EquivalenceSmallSemigroup(sgrp); -SemigroupHomomorphismByImages ( Monoid( [ Transformation( [ 1, 2, 2 ] ) +SemigroupHomomorphismByImages ( Monoid( [ Transformation( [ 1, 2, 2 ] ) ] )->) -# doc/../gap/properties.gd:22-27 +# doc/../gap/properties.gd:20-25 gap> s := SmallSemigroup(5,6); gap> Annihilators(s); [ s1, s2 ] -# doc/../gap/properties.gd:42-49 +# doc/../gap/properties.gd:37-44 gap> s:=SmallSemigroup(8,10101);; gap> DiagonalOfMultiplicationTable(s); [ 1, 1, 1, 1, 1, 1, 1, 1 ] @@ -81,7 +82,7 @@ gap> s:=SmallSemigroup(7,10101);; gap> DiagonalOfMultiplicationTable(s); [ 1, 1, 1, 1, 1, 1, 1 ] -# doc/../gap/properties.gd:65-94 +# doc/../gap/properties.gd:57-86 gap> s:=SmallSemigroup(6, 3838);; gap> DisplaySmallSemigroup(s); IsBand: false @@ -111,7 +112,7 @@ GreensLClasses: [ {s1}, {s2}, {s3}, {s4}, {s6} ] GreensHClasses: [ {s1}, {s2}, {s3}, {s4}, {s5}, {s6} ] GreensDClasses: [ {s1}, {s2}, {s3}, {s4}, {s6} ] -# doc/../gap/properties.gd:110-123 +# doc/../gap/properties.gd:98-111 gap> s:=SmallSemigroup(5,116); gap> x:=Elements(s)[3]; @@ -125,7 +126,7 @@ false gap> x^3=x^1; false -# doc/../gap/properties.gd:143-153 +# doc/../gap/properties.gd:127-137 gap> s:=SmallSemigroup(5,519);; gap> IsBand(s); false @@ -136,7 +137,7 @@ true gap> IdSmallSemigroup(s); [ 5, 1010 ] -# doc/../gap/properties.gd:170-180 +# doc/../gap/properties.gd:151-161 gap> s:=SmallSemigroup(5,519);; gap> IsBrandtSemigroup(s); false @@ -147,8 +148,8 @@ true gap> IdSmallSemigroup(s); [ 5, 149 ] -# doc/../gap/properties.gd:200-219 -gap> s:=SmallSemigroup(5,519);; +# doc/../gap/properties.gd:177-196 +gap> s:=SmallSemigroup(5,519);; gap> IsBand(s); false gap> s:=OneSmallSemigroup(5, IsBand, true); @@ -167,7 +168,7 @@ true gap> IdSmallSemigroup(s); [ 5, 148 ] -# doc/../gap/properties.gd:237-255 +# doc/../gap/properties.gd:211-229 gap> s:=SmallSemigroup(6,871);; gap> IsCommutativeSemigroup(s); false @@ -186,19 +187,19 @@ true gap> IsCommutative(s); true -# doc/../gap/properties.gd:271-282 +# doc/../gap/properties.gd:242-253 gap> s:=SmallSemigroup(6,13131); gap> IsCompletelyRegularSemigroup(s); false -gap> s:=OneSmallSemigroup(6, IsCompletelyRegularSemigroup, true); +gap> s:=OneSmallSemigroup(6, IsCompletelyRegularSemigroup, true); gap> IsCompletelyRegularSemigroup(s); true gap> IdSmallSemigroup(s); [ 6, 3164 ] -# doc/../gap/properties.gd:300-313 +# doc/../gap/properties.gd:269-282 gap> s:=SmallSemigroup(1,1); gap> IsFullTransformationSemigroupCopy(s); @@ -212,7 +213,7 @@ gap> IdSmallSemigroup(s); gap> s:=OneSmallSemigroup(6, IsFullTransformationSemigroupCopy, true); fail -# doc/../gap/properties.gd:331-339 +# doc/../gap/properties.gd:296-304 gap> s:=SmallSemigroup(7,7); gap> IsGroupAsSemigroup(s); @@ -221,7 +222,7 @@ gap> s:=SmallSemigroup(4,37);; gap> IsGroupAsSemigroup(s); true -# doc/../gap/properties.gd:357-374 +# doc/../gap/properties.gd:320-337 gap> s:=SmallSemigroup(3, 13); gap> IsIdempotentGenerated(s); @@ -232,14 +233,14 @@ gap> IsIdempotentGenerated(s); false gap> IdSmallSemigroup(s); [ 3, 1 ] -gap> s:=OneSmallSemigroup(4, IsIdempotentGenerated, true, +gap> s:=OneSmallSemigroup(4, IsIdempotentGenerated, true, > IsSingularSemigroupCopy, true); fail -gap> s:=OneSmallSemigroup(2, IsIdempotentGenerated, true, +gap> s:=OneSmallSemigroup(2, IsIdempotentGenerated, true, > IsSingularSemigroupCopy, true); -# doc/../gap/properties.gd:392-401 +# doc/../gap/properties.gd:352-361 gap> s:=OneSmallSemigroup(7, IsInverseSemigroup, true); gap> IsInverseSemigroup(s); @@ -249,7 +250,7 @@ gap> s:=SmallSemigroup(7, 101324); gap> IsInverseSemigroup(s); false -# doc/../gap/properties.gd:417-426 +# doc/../gap/properties.gd:375-384 gap> s:=SmallSemigroup(5, 438); gap> IsLeftZeroSemigroup(s); @@ -259,7 +260,7 @@ gap> s:=SmallSemigroup(5, 1141); gap> IsLeftZeroSemigroup(s); true -# doc/../gap/properties.gd:439-454 +# doc/../gap/properties.gd:395-410 gap> s:=RandomSmallSemigroup(7); gap> IsMonogenicSemigroup(s); @@ -275,7 +276,7 @@ gap> s:=SmallSemigroup( 7, 406945); gap> IsMonogenicSemigroup(s); false -# doc/../gap/properties.gd:469-482 +# doc/../gap/properties.gd:423-436 gap> s:=SmallSemigroup(4, 126); gap> IsMonoidAsSemigroup(s); @@ -289,7 +290,7 @@ s1 gap> IdSmallSemigroup(s); [ 4, 7 ] -# doc/../gap/properties.gd:499-510 +# doc/../gap/properties.gd:451-462 gap> s:=OneSmallSemigroup(7, IsMultSemigroupOfNearRing, true); gap> IdSmallSemigroup(s); @@ -301,7 +302,7 @@ gap> s:=SmallSemigroup(2,2); gap> IsMultSemigroupOfNearRing(s); false -# doc/../gap/properties.gd:527-540 +# doc/../gap/properties.gd:476-489 gap> s:=SmallSemigroup(7, 760041); gap> IsNGeneratedSemigroup(s, 4); @@ -315,7 +316,7 @@ gap> s:=OneSmallSemigroup(4, x-> Length(MinimalGeneratingSet(x)), 4); gap> IsNGeneratedSemigroup(s, 4); true -# doc/../gap/properties.gd:563-571 +# doc/../gap/properties.gd:510-518 gap> s:=SmallSemigroup(4, 75);; gap> IsNIdempotentSemigroup(s, 1); false @@ -324,7 +325,7 @@ false gap> IsNIdempotentSemigroup(s, 3); true -# doc/../gap/properties.gd:601-612 +# doc/../gap/properties.gd:546-557 gap> s:=SmallSemigroup(5,116); gap> IsNilpotentSemigroup(s); @@ -336,7 +337,7 @@ gap> s:=SmallSemigroup(7, 657867);; gap> IsNilpotent(s); true -# doc/../gap/properties.gd:630-638 +# doc/../gap/properties.gd:572-580 gap> s:=SmallSemigroup(6, 15858);; gap> IsSemigroupWithClosedIdempotents(s); true @@ -345,7 +346,7 @@ true gap> IsOrthodoxSemigroup(s); true -# doc/../gap/properties.gd:655-662 +# doc/../gap/properties.gd:594-601 gap> s:=SmallSemigroup(5, 216);; gap> IsRectangularBand(s); false @@ -353,25 +354,25 @@ gap> s:=SmallSemigroup(6, 15854);; gap> IsRectangularBand(s); true -# doc/../gap/properties.gd:680-691 +# doc/../gap/properties.gd:616-627 gap> s:=SmallSemigroup(3, 10);; gap> IsRegularSemigroup(s); true gap> s:=SmallSemigroup(3, 1);; gap> IsRegularSemigroup(s); false -gap> s:=OneSmallSemigroup(4, IsFullTransformationSemigroupCopy, true); +gap> s:=OneSmallSemigroup(4, IsFullTransformationSemigroupCopy, true); gap> IsRegularSemigroup(s); true -# doc/../gap/properties.gd:708-713 +# doc/../gap/properties.gd:642-647 gap> s:=SmallSemigroup(5, 438); gap> IsRightZeroSemigroup(s); false -# doc/../gap/properties.gd:731-740 +# doc/../gap/properties.gd:662-671 gap> s:=SmallSemigroup(5,116); gap> IsSelfDualSemigroup(s); @@ -381,7 +382,7 @@ gap> s:=RandomSmallSemigroup(5, IsSelfDualSemigroup, true); gap> IsSelfDualSemigroup(s); true -# doc/../gap/properties.gd:756-766 +# doc/../gap/properties.gd:684-694 gap> s:=SmallSemigroup(5, 677);; gap> IsSemigroupWithClosedIdempotents(s); true @@ -392,7 +393,7 @@ gap> s:=SmallSemigroup(5, 327);; gap> IsSemigroupWithClosedIdempotents(s); false -# doc/../gap/properties.gd:787-796 +# doc/../gap/properties.gd:714-723 gap> s:=SmallSemigroup(5,1); gap> IsSemigroupWithZero(s); @@ -402,7 +403,7 @@ gap> s:=SmallSemigroup(4,26); gap> IsSemigroupWithZero(s); false -# doc/../gap/properties.gd:818-827 +# doc/../gap/properties.gd:742-751 gap> s:=SmallSemigroup(7, 835080);; gap> IsSimpleSemigroup(s); true @@ -412,7 +413,7 @@ gap> s:=SmallSemigroup(7, 208242);; gap> IsSimpleSemigroup(s); false -# doc/../gap/properties.gd:844-857 +# doc/../gap/properties.gd:766-779 gap> s:=SmallSemigroup(1,1); gap> IsSingularSemigroupCopy(s); @@ -426,10 +427,10 @@ gap> IdSmallSemigroup(s); gap> s:=OneSmallSemigroup(4, IsSingularSemigroupCopy, true); fail -# doc/../gap/properties.gd:877-888 -gap> g:=Group((1,2),(3,4)); +# doc/../gap/properties.gd:796-807 +gap> g:=Group((1,2),(3,4)); Group([ (1,2), (3,4) ]) -gap> IdSmallSemigroup(g); +gap> IdSmallSemigroup(g); [ 4, 7 ] gap> s := Range(InjectionZeroMagma(g)); @@ -438,7 +439,7 @@ gap> IdSmallSemigroup(s); gap> IsZeroGroup(s); true -# doc/../gap/properties.gd:905-918 +# doc/../gap/properties.gd:822-835 gap> s:=OneSmallSemigroup(5, IsZeroSemigroup, true); gap> IsZeroSemigroup(s); @@ -452,7 +453,7 @@ gap> IdSmallSemigroup(s); gap> IsZeroSemigroup(s); false -# doc/../gap/properties.gd:921-928 +# doc/../gap/properties.gd:838-845 gap> IsZeroSemigroup(SmallSemigroup(6,1)); true gap> IsZeroSemigroup(SmallSemigroup(7,1)); @@ -460,17 +461,17 @@ true gap> IsZeroSemigroup(SmallSemigroup(8,1)); true -# doc/../gap/properties.gd:945-954 +# doc/../gap/properties.gd:859-868 gap> s:=SmallSemigroup(7, 519799); gap> IsZeroSimpleSemigroup(s); false -gap> s:=RandomSmallSemigroup(7, IsZeroSimpleSemigroup, true); +gap> s:=RandomSmallSemigroup(7, IsZeroSimpleSemigroup, true); gap> IsZeroSimpleSemigroup(s); true -# doc/../gap/properties.gd:967-977 +# doc/../gap/properties.gd:878-888 gap> s:=SmallSemigroup(8, 1478885610);; gap> MinimalGeneratingSet(s); [ s4, s5, s6, s7, s8 ] @@ -481,7 +482,7 @@ gap> s:=SmallSemigroup(4, 4);; gap> MinimalGeneratingSet(s); [ s2, s3, s4 ] -# doc/../gap/properties.gd:994-1001 +# doc/../gap/properties.gd:903-910 gap> s := SmallSemigroup(5, 1121);; gap> NilpotencyDegree(s); fail @@ -489,7 +490,7 @@ gap> s := SmallSemigroup(7, 393450);; gap> NilpotencyDegree(s); 3 -# doc/../gap/properties.gd:1004-1011 +# doc/../gap/properties.gd:913-920 gap> s := SmallSemigroup(8, 11433106+1231);; gap> NilpotencyDegree(s); 3 @@ -497,21 +498,21 @@ gap> s := SmallSemigroup(8,NrSmallSemigroups(8));; gap> NilpotencyDegree(s); 3 -# doc/../gap/coclass.gd:21-34 -gap> NilpotentSemigroupsByCoclass(5,1); -[ , - , - , - , - , - , +# doc/../gap/coclass.gd:19-32 +gap> NilpotentSemigroupsByCoclass(5, 1); +[ , + , + , + , + , + , ] -gap> NilpotentSemigroupsByCoclass(7,0); +gap> NilpotentSemigroupsByCoclass(7, 0); [ ] -gap> NilpotentSemigroupsByCoclass(4,2,3); +gap> NilpotentSemigroupsByCoclass(4, 2, 3); [ ] -# doc/../gap/greensstar.gd:227-235 +# doc/../gap/greensstar.gd:167-175 gap> s := SmallSemigroup(7, 280142); gap> elm := AsList(s)[5];; @@ -520,7 +521,7 @@ gap> jclass := JStarClass(s, elm); gap> AsList(jclass); [ s2, s3, s4, s5 ] -# doc/../gap/greensstar.gd:184-196 +# doc/../gap/greensstar.gd:133-145 gap> s := SmallSemigroup(7, 280142); gap> elm := AsList(s)[5];; @@ -533,15 +534,15 @@ gap> AsList(RStarClass(hclass)); gap> AsList(DStarClass(hclass)); [ s2, s3, s4, s5 ] -# doc/../gap/greensstar.gd:142-147 +# doc/../gap/greensstar.gd:99-104 gap> s := SmallSemigroup(6, 54); gap> JStarClasses(s); [ {s1}, {s2}, {s4}, {s5}, {s6} ] -# doc/../gap/enums.gd:44-60 +# doc/../gap/enums.gd:48-64 gap> AllSmallSemigroups(2); -[ , , +[ , , , ] gap> AllSmallSemigroups([2,3], IsRegularSemigroup, true, > x-> Length(GreensRClasses(x)), 1); @@ -549,14 +550,14 @@ gap> AllSmallSemigroups([2,3], IsRegularSemigroup, true, gap> enum:=EnumeratorOfSmallSemigroups(8, IsInverseSemigroup, true, > IsCommutativeSemigroup, true);; gap> AllSmallSemigroups(enum, x-> Length(GreensRClasses(x)), 1); -[ , , +[ , , ] gap> iter:=IteratorOfSmallSemigroups(7, x-> Length(GreensRClasses(x)), 1);; gap> AllSmallSemigroups(iter, IsCommutative, true, > IsSimpleSemigroup, true); [ ] -# doc/../gap/enums.gd:135-151 +# doc/../gap/enums.gd:138-154 gap> enum:=EnumeratorOfSmallSemigroups(7); gap> EnumeratorOfSmallSemigroups([2,3], IsRegularSemigroup, true); @@ -573,7 +574,7 @@ gap> EnumeratorOfSmallSemigroups(iter, IsCommutativeSemigroup, true, > IsSimpleSemigroup, false); -# doc/../gap/enums.gd:183-190 +# doc/../gap/enums.gd:189-196 gap> enum:=EnumeratorOfSmallSemigroupsByIds([[7,1],[6,1],[5,1]]); gap> enum:=EnumeratorOfSmallSemigroupsByIds(7, [1..1000]); @@ -581,30 +582,30 @@ gap> enum:=EnumeratorOfSmallSemigroupsByIds(7, [1..1000]); gap> enum:=EnumeratorOfSmallSemigroupsByIds([2,3], [[1..2],[1..10]]); -# doc/../gap/enums.gd:298-304 +# doc/../gap/enums.gd:302-308 gap> enum:=EnumeratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, > IsRegularSemigroup, true);; gap> FuncsOfSmallSemisInEnum(enum); -[ , true, , +[ , true, , false ] -# doc/../gap/enums.gd:363-369 +# doc/../gap/enums.gd:359-365 gap> enum:=IteratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, > IsRegularSemigroup, true);; gap> FuncsOfSmallSemisInIter(enum); -[ , true, , +[ , true, , false ] -# doc/../gap/enums.gd:254-262 +# doc/../gap/enums.gd:264-272 gap> enum:=EnumeratorOfSmallSemigroups(5, x-> Length(GreensRClasses(x)), 1);; gap> IdsOfSmallSemigroups(enum, IsCommutativeSemigroup, true, > IsSimpleSemigroup, false); [ ] gap> IdsOfSmallSemigroups([2,3], IsRegularSemigroup, true); -[ [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], +[ [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 3, 17 ], [ 3, 18 ] ] -# doc/../gap/enums.gd:278-282 +# doc/../gap/enums.gd:285-289 gap> enum:=EnumeratorOfSmallSemigroupsByIds([[2,1], [3,1], [4,1]]);; gap> IsEnumeratorOfSmallSemigroups(enum); true @@ -617,12 +618,12 @@ false gap> IsIdSmallSemigroup([3,18]); true -# doc/../gap/enums.gd:343-347 +# doc/../gap/enums.gd:341-345 gap> iter:=IteratorOfSmallSemigroups(8);; gap> IsIteratorOfSmallSemigroups(iter); true -# doc/../gap/enums.gd:416-436 +# doc/../gap/enums.gd:409-430 gap> iter:=IteratorOfSmallSemigroups(8); gap> NextIterator(iter); @@ -640,22 +641,23 @@ gap> NextIterator(iter); fail gap> enum:=EnumeratorOfSmallSemigroups(5, x-> Length(Idempotents(x))=1, true); -gap> iter:=IteratorOfSmallSemigroups(enum, x-> Length(GreensRClasses(x))=2, true); +gap> iter:=IteratorOfSmallSemigroups(enum, +> x-> Length(GreensRClasses(x))=2, true); -# doc/../gap/enums.gd:452-457 +# doc/../gap/enums.gd:443-448 gap> enum:=EnumeratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, > IsRegularSemigroup, true);; gap> NamesFuncsSmallSemisInEnum(enum); [ "IsRegularSemigroup", true, "IsSimpleSemigroup", false ] -# doc/../gap/enums.gd:474-479 +# doc/../gap/enums.gd:461-466 gap> iter:=IteratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false, > IsRegularSemigroup, true);; gap> NamesFuncsSmallSemisInIter(iter); [ "IsRegularSemigroup", true, "IsSimpleSemigroup", false ] -# doc/../gap/enums.gd:501-512 +# doc/../gap/3nil.gd:24-35 gap> Nr3NilpotentSemigroups( 4 ); 8 gap> Nr3NilpotentSemigroups( 9, "UpToIsomorphism" ); @@ -667,7 +669,7 @@ gap> Nr3NilpotentSemigroups( 16, "SelfDual" ); gap> Nr3NilpotentSemigroups( 19, "Commutative" ); 12094270656160403920767935604624748908993169949317454767617795 -# doc/../gap/enums.gd:558-570 +# doc/../gap/enums.gd:509-521 gap> List([1..8], NrSmallSemigroups); [ 1, 4, 18, 126, 1160, 15973, 836021, 1843120128 ] gap> NrSmallSemigroups(8, IsCommutative, true, IsInverseSemigroup, true); @@ -680,7 +682,7 @@ gap> NrSmallSemigroups(8, IsRegularSemigroup, true, gap> NrSmallSemigroups(5, NilpotencyDegree, 3); 84 -# doc/../gap/enums.gd:616-625 +# doc/../gap/enums.gd:565-574 gap> OneSmallSemigroup(8, IsCommutative, true, IsInverseSemigroup, true); gap> OneSmallSemigroup([1..8], IsCliffordSemigroup, true); @@ -690,7 +692,7 @@ gap> iter:=IteratorOfSmallSemigroups(8, IsCommutative, false); gap> OneSmallSemigroup(iter); -# doc/../gap/enums.gd:654-667 +# doc/../gap/enums.gd:600-613 gap> PositionsOfSmallSemigroups(3); [ [ 1 .. 18 ] ] gap> PositionsOfSmallSemigroups(3, IsRegularSemigroup, false); @@ -704,25 +706,25 @@ gap> PositionsOfSmallSemigroups(enum, Is1IdempotentSemigroup, true, > Is2GeneratedSemigroup, true, IsCliffordSemigroup, false); [ [ 1, 2 ] ] -# doc/../gap/enums.gd:685-690 +# doc/../gap/enums.gd:627-632 gap> enum := EnumeratorOfSmallSemigroups([2..4],IsSimpleSemigroup,true);; gap> PositionsOfSmallSemisInEnum > (enum); [ [ 2, 4 ], [ 17, 18 ], [ 7, 37, 52, 122, 123 ] ] -# doc/../gap/autovars.g:30-41 +# doc/../gap/autovars.g:58-69 gap> PrecomputedSmallSemisInfo[3]; -[ "Is2GeneratedSemigroup", "Is3GeneratedSemigroup", "Is4GeneratedSemigroup", - "Is5GeneratedSemigroup", "Is6GeneratedSemigroup", "Is7GeneratedSemigroup", - "Is8GeneratedSemigroup", "IsBand", "IsCommutative", - "IsCompletelyRegularSemigroup", "IsFullTransformationSemigroupCopy", - "IsGroupAsSemigroup", "IsIdempotentGenerated", "IsInverseSemigroup", - "IsMonogenicSemigroup", "IsMonoidAsSemigroup", "IsMultSemigroupOfNearRing", - "IsMunnSemigroup", "IsRegularSemigroup", "IsSelfDualSemigroup", - "IsSemigroupWithoutClosedIdempotents", "IsSimpleSemigroup", +[ "Is2GeneratedSemigroup", "Is3GeneratedSemigroup", "Is4GeneratedSemigroup", + "Is5GeneratedSemigroup", "Is6GeneratedSemigroup", "Is7GeneratedSemigroup", + "Is8GeneratedSemigroup", "IsBand", "IsCommutative", + "IsCompletelyRegularSemigroup", "IsFullTransformationSemigroupCopy", + "IsGroupAsSemigroup", "IsIdempotentGenerated", "IsInverseSemigroup", + "IsMonogenicSemigroup", "IsMonoidAsSemigroup", "IsMultSemigroupOfNearRing", + "IsMunnSemigroup", "IsRegularSemigroup", "IsSelfDualSemigroup", + "IsSemigroupWithoutClosedIdempotents", "IsSimpleSemigroup", "IsSingularSemigroupCopy", "IsZeroSemigroup", "IsZeroSimpleSemigroup" ] -# doc/../gap/enums.gd:731-741 +# doc/../gap/enums.gd:675-685 gap> RandomSmallSemigroup(8, IsCommutative, true, > IsInverseSemigroup, true); @@ -733,23 +735,23 @@ gap> iter:=IteratorOfSmallSemigroups([1..7]); gap> RandomSmallSemigroup(iter); -# doc/../gap/enums.gd:756-761 +# doc/../gap/enums.gd:698-703 gap> enum:=EnumeratorOfSmallSemigroups([2..4], IsSimpleSemigroup, false); gap> SizesOfSmallSemisInEnum(enum); [ 2, 3, 4 ] -# doc/../gap/enums.gd:776-781 +# doc/../gap/enums.gd:716-721 gap> iter:=IteratorOfSmallSemigroups(7, IsCommutative, false); gap> SizesOfSmallSemisInIter(iter); [ 7 ] -# doc/../gap/enums.gd:799-805 +# doc/../gap/enums.gd:736-742 gap> UpToIsomorphism([SmallSemigroup(5,126),SmallSemigroup(6,2)]); [ , ] gap> UpToIsomorphism([SmallSemigroup(5,126),SmallSemigroup(5,3)]); -[ , , +[ , , ] #