diff --git a/doc/semicons.xml b/doc/semicons.xml index 8221b93ff..a24635c28 100644 --- a/doc/semicons.xml +++ b/doc/semicons.xml @@ -355,6 +355,36 @@ true]]> <#/GAPDoc> +<#GAPDoc Label="PowerSemigroup"> + + + + A semigroup or monoid. + + + The power semigroup \mathcal{P}(S) over the finite semigroup + S consists of the set of all non-empty subsets of S, along + with the binary operation of setwise multiplication, defined by + (X, Y) \mapsto \{xy : x \in X, y \in Y\} +

+ If S is a monoid, then PowerSemigroup returns a monoid. +

+ Power semigroups grow exponentially; for a semigroup S of size + n, the corresponding power semigroup has size 2^{n}-1, so + its multiplication table may exhaust memory. + + S := SemigroupByMultiplicationTable([[1, 2], [2, 1]]);; +gap> S1 := PowerSemigroup(S);; +gap> MultiplicationTable(S1); +[ [ 1, 2, 3 ], [ 2, 1, 3 ], [ 3, 3, 3 ] ] +gap> IsMonoid(S1); +true +]]> + + +<#/GAPDoc> + <#GAPDoc Label="StrongSemilatticeOfSemigroups"> diff --git a/doc/z-chap08.xml b/doc/z-chap08.xml index 6f498f35c..dc69a227b 100644 --- a/doc/z-chap08.xml +++ b/doc/z-chap08.xml @@ -37,6 +37,18 @@ +

+ Power semigroups + The power semigroup of a semigroup S is the semigroup + consisting of the power set of S excluding the empty set, along with + the binary operation of setwise multiplication, defined by + (X, Y) \mapsto \{xy : x \in X, y \in Y\}. + <#Include Label = "PowerSemigroup"> +
+ + + +
Strong semilattices of semigroups diff --git a/gap/semigroups/semicons.gd b/gap/semigroups/semicons.gd index 10089096e..d6a288a8a 100644 --- a/gap/semigroups/semicons.gd +++ b/gap/semigroups/semicons.gd @@ -22,6 +22,7 @@ DeclareGlobalFunction("LeftZeroSemigroup"); DeclareGlobalFunction("RightZeroSemigroup"); DeclareConstructor("BrandtSemigroupCons", [IsSemigroup, IsGroup, IsPosInt]); DeclareGlobalFunction("BrandtSemigroup"); +DeclareOperation("PowerSemigroup", [IsSemigroup and IsFinite]); DeclareCategory("IsSSSE", IsAssociativeElement); DeclareCategoryCollections("IsSSSE"); diff --git a/gap/semigroups/semicons.gi b/gap/semigroups/semicons.gi index f8e3c5fd1..abd48b2d9 100644 --- a/gap/semigroups/semicons.gi +++ b/gap/semigroups/semicons.gi @@ -967,6 +967,61 @@ for _IsXSemigroup in ["IsTransformationSemigroup", od; Unbind(_IsXSemigroup); +InstallMethod(PowerSemigroup, "for a semigroup", +[IsSemigroup and IsFinite], +function(S) + local n, N, subs, x, getindex, multtable, precompute, subsproduct, + table, result; + + n := Size(S); + if n > 12 then + Info(InfoWarning, 1, + "PowerSemigroup: the argument has ", n, " elements, so the result ", + "will have 2^", n, " - 1 elements and its multiplication table ", + "may exceed memory limits, "); + fi; + + N := (2 ^ n) - 1; + + # want subsets in binary-code order, not lexicographical, so easier to index + # e.g. {1, 2, 3} -> {1}, {2}, {1, 2}, {3}..., i.e. 001, 010, 011, 100... + subs := [[]]; + for x in [1 .. n] do + Append(subs, List(subs, s -> Concatenation(s, [x]))); + od; + Remove(subs, 1); + + getindex := s -> Sum(s, j -> 2 ^ (j - 1)); + + multtable := MultiplicationTable(S); + + # precompute[i][j] is the product: (element i of S) times (subset j of S) + precompute := List([1 .. n], + i -> List(subs, sub -> Set(sub, j -> multtable[i][j]))); + + # the product of two subsets X, Y is equivalent to + # (x_1 * Y) union (x_2 * Y) union (x_3 * Y)... + # so is just a union of the precomputed values above + subsproduct := {sub, subindex} -> Union(List(sub, + i -> precompute[i][subindex])); + + table := List(subs, + sub -> List([1 .. N], + subindex -> getindex(subsproduct(sub, subindex)))); + + if IsMonoidAsSemigroup(S) then + result := MonoidByMultiplicationTable(table); + else + result := SemigroupByMultiplicationTable(table); + fi; + + if IsCommutative(S) then + SetIsCommutative(result, true); + fi; + + return result; +end); + InstallMethod(StrongSemilatticeOfSemigroups, "for a digraph, a list, and a list", [IsDigraph, IsList, IsList], diff --git a/tst/standard/semigroups/semicons.tst b/tst/standard/semigroups/semicons.tst index 34986b2d0..86dec2e06 100644 --- a/tst/standard/semigroups/semicons.tst +++ b/tst/standard/semigroups/semicons.tst @@ -972,6 +972,27 @@ gap> S := BrandtSemigroup(IsIntegerMatrixSemigroup, DihedralGroup(4), 3); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `BrandtSemigroupCons' on 3 arguments +# constructions: power semigroups +gap> PowerSemigroup(FreeSemigroup(1)); +Error, no method found! For debugging hints type ?Recovery from NoMethodFound +Error, no 1st choice method found for `PowerSemigroup' on 1 arguments +gap> S := PowerSemigroup(TrivialSemigroup());; +gap> IsTrivial(S); +true +gap> S := PowerSemigroup(CyclicGroup(2));; +gap> HasIsCommutative(S); +true +gap> IsMonoid(S); +true +gap> S1 := SemigroupByMultiplicationTable([[1, 2, 3], [2, 1, 3], [3, 3, 3]]);; +gap> IsomorphismSemigroups(S, S1) <> fail; +true +gap> S := PowerSemigroup(LeftZeroSemigroup(2));; +gap> HasIsCommutative(S); +false +gap> IsMonoid(S); +false + # constructions: strong semilattices of semigroups: trivial argument checks gap> D := CompleteDigraph(2);; gap> S1 := TrivialSemigroup();;