Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions doc/semicons.xml
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,36 @@ true]]></Example>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="PowerSemigroup">
<ManSection>
<Oper Name="PowerSemigroup" Arg="S"/>
<Returns>
A semigroup or monoid.
</Returns>
<Description>
The power semigroup <M>\mathcal{P}(S)</M> over the finite semigroup
<A>S</A> consists of the set of all non-empty subsets of <A>S</A>, along
with the binary operation of setwise multiplication, defined by
<Display>(X, Y) \mapsto \{xy : x \in X, y \in Y\}</Display>
<P/>
If <A>S</A> is a monoid, then <C>PowerSemigroup</C> returns a monoid.
<P/>
Power semigroups grow exponentially; for a semigroup <A>S</A> of size
<M>n</M>, the corresponding power semigroup has size <M>2^{n}-1</M>, so
its multiplication table may exhaust memory.

<Example><![CDATA[
gap> 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
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="StrongSemilatticeOfSemigroups">
<ManSection>
<Oper Name="StrongSemilatticeOfSemigroups" Arg="D, L, H"/>
Expand Down
12 changes: 12 additions & 0 deletions doc/z-chap08.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@
<!--**********************************************************************-->
<!--**********************************************************************-->

<Section>
<Heading> Power semigroups </Heading>
The <E>power semigroup</E> of a semigroup <M>S</M> is the semigroup
consisting of the power set of <C>S</C> excluding the empty set, along with
the binary operation of setwise multiplication, defined by
<Display>(X, Y) \mapsto \{xy : x \in X, y \in Y\}</Display>.
<#Include Label = "PowerSemigroup">
</Section>

<!--**********************************************************************-->
<!--**********************************************************************-->

<Section Label = "Strong semilattices of semigroups">
<Heading>
Strong semilattices of semigroups
Expand Down
1 change: 1 addition & 0 deletions gap/semigroups/semicons.gd
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
55 changes: 55 additions & 0 deletions gap/semigroups/semicons.gi
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
21 changes: 21 additions & 0 deletions tst/standard/semigroups/semicons.tst
Original file line number Diff line number Diff line change
Expand Up @@ -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();;
Expand Down
Loading