Skip to content

Commit

Permalink
attr: initial methods for MinimalSemigroupGenSet
Browse files Browse the repository at this point in the history
  • Loading branch information
wilfwilson committed Nov 7, 2017
1 parent 3af8d71 commit 1b8451e
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 6 deletions.
19 changes: 13 additions & 6 deletions doc/attr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,9 @@ gap> Length(SmallGeneratingSet(S));
<Returns>A minimal generating set for a semigroup.</Returns>
<Description>

<B>Warning:</B> currently, no methods are installed to compute these
attributes.<P/>
<B>Warning:</B> currently, there are few methods installed for
<C>MinimalSemigroupGeneratingSet</C>, and no methods are installed to
compute the remaining attributes. <P/>

The attributes <C>MinimalXGeneratingSet</C> return a minimal generating set
for the semigroup <A>S</A>, with respect to length. The returned value of
Expand All @@ -353,10 +354,12 @@ gap> Length(SmallGeneratingSet(S));
<Ref Func="InverseSemigroup" BookName="ref"/>, or
<Ref Func="InverseMonoid" BookName="ref"/>.<P/>

For certain types of semigroup, for example monogenic semigroups, a
<C>MinimalXGeneratingSet</C> may be known a priori, or may be deduced as a
by-product of other functions. However, since there are no methods installed
to compute these attributes directly, for most semigroups it is not
For certain semigroups, for example monogenic semigroups, a
<C>MinimalSemigroupGeneratingSet</C> may be known a priori, may be deduced
as a by-product of other functions, or may be be computed directly. <P/>

However, in general, there are no methods installed to compute
<C>MinimalXGeneratingSet</C> directly, so for most semigroups it is not
currently possible to find a <C>MinimalXGeneratingSet</C> with the
&Semigroups; package. <P/>

Expand All @@ -367,6 +370,10 @@ gap> Length(SmallGeneratingSet(S));
gap> S := MonogenicSemigroup(3, 6);;
gap> MinimalSemigroupGeneratingSet(S);
[ Transformation( [ 2, 3, 4, 5, 6, 1, 6, 7, 8 ] ) ]
gap> S := FullTransformationMonoid(4);;
gap> MinimalSemigroupGeneratingSet(S);
[ Transformation( [ 1, 4, 2, 3 ] ), Transformation( [ 4, 3, 1, 2 ] ),
Transformation( [ 1, 2, 3, 1 ] ) ]
gap> S := Semigroup([
> PartialPerm([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]),
> PartialPerm([1, 2, 3, 4], [5, 2, 4, 1]),
Expand Down
84 changes: 84 additions & 0 deletions gap/attributes/attr.gi
Original file line number Diff line number Diff line change
Expand Up @@ -960,3 +960,87 @@ function(S)
od;
return out;
end);

InstallMethod(MinimalSemigroupGeneratingSet, "for a free semigroup",
[IsFreeSemigroup],
GeneratorsOfSemigroup);

InstallMethod(MinimalSemigroupGeneratingSet, "for a semigroup",
[IsSemigroup],
function(S)
local gens, indecomp, id, T, zero, iso, inv, G, x, D, non_unit_gens, classes,
po, nbs;

if IsGroupAsSemigroup(S) then
iso := IsomorphismPermGroup(S);
inv := InverseGeneralMapping(iso);
G := Range(iso);
return Images(inv, MinimalGeneratingSet(G));
elif IsMonogenicSemigroup(S) then
return [Representative(MaximalDClasses(S)[1])];
fi;

gens := IrredundantGeneratingSubset(S);

# A semigroup that has a 2-generating set but is not monogenic has rank 2.
if Length(gens) = 2 then
return gens;
fi;

# A generating set for a semigroup that has either a one/zero adjoined is
# minimal if and only if it contains that one/zero, and is minimal for the
# semigroup without the one/zero.
if IsMonoidAsSemigroup(S) and IsTrivial(GroupOfUnits(S)) then
id := MultiplicativeNeutralElement(S);
T := Semigroup(Filtered(gens, x -> x <> id));
return Concatenation([id], MinimalSemigroupGeneratingSet(T));
elif IsSemigroupWithAdjoinedZero(S) then
zero := MultiplicativeZero(S);
T := Semigroup(Filtered(gens, x -> x <> zero));
return Concatenation([zero], MinimalSemigroupGeneratingSet(T));
fi;

# The indecomposable elements are contains in any generating set. If the
# indecomposable elements (or if not, the indecomposable elements plus a
# single element) generate the semigroup, then you have a minimal generating
# set.
indecomp := IndecomposableElements(S);
if Length(gens) = Length(indecomp) then
return indecomp;
elif not IsEmpty(indecomp) then
x := Difference(gens, Semigroup(indecomp));
if Length(x) = 1 then
return Concatenation(x, indecomp);
fi;
fi;

# A generating set for a monoid that consists of a minimal generating set for
# the group of units and exactly one generator in each D-class immediately
# below the group of units is minimal.
if IsMonoidAsSemigroup(S) then
D := DClass(S, MultiplicativeNeutralElement(S));
non_unit_gens := Filtered(gens, x -> not x in D);
classes := List(non_unit_gens, x -> Position(DClasses(S), DClass(S, x)));
if IsDuplicateFreeList(classes) then
po := Digraph(PartialOrderOfDClasses(S));
po := DigraphReflexiveTransitiveReduction(po);
nbs := OutNeighboursOfVertex(po, Position(DClasses(S), D));
if ForAll(classes, x -> x in nbs) then
iso := IsomorphismPermGroup(GroupOfUnits(S));
inv := InverseGeneralMapping(iso);
G := Range(iso);
return Concatenation(Images(inv, MinimalGeneratingSet(G)),
non_unit_gens);
fi;
fi;
fi;

# An irredundant generating set of a finite semigroup that contains at most
# one generator per D-class is minimal.
if IsFinite(S) and (IsDTrivial(S) or
Length(Set(gens, x -> DClass(S, x))) = Length(gens)) then
return gens;
fi;

ErrorNoReturn("not yet implemented,");
end);
117 changes: 117 additions & 0 deletions tst/standard/attr.tst
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,123 @@ gap> S := MonogenicSemigroup(3, 2);;
gap> IndecomposableElements(S) = [S.1];
true

#T# MinimalSemigroupGeneratingSet: for a monogenic semigroup, 1
gap> S := MonogenicSemigroup(IsTransformationSemigroup, 4, 5);
<commutative non-regular transformation semigroup of size 8, degree 9 with 1
generator>
gap> MinimalSemigroupGeneratingSet(S);
[ Transformation( [ 2, 3, 4, 5, 1, 5, 6, 7, 8 ] ) ]
gap> x := MinimalSemigroupGeneratingSet(S)[1];
Transformation( [ 2, 3, 4, 5, 1, 5, 6, 7, 8 ] )
gap> S := Semigroup(x, x ^ 2);
<transformation semigroup of degree 9 with 2 generators>
gap> x := MinimalSemigroupGeneratingSet(S);
[ Transformation( [ 2, 3, 4, 5, 1, 5, 6, 7, 8 ] ) ]
gap> Length(x);
1
gap> S = Semigroup(x);
true

#T# MinimalSemigroupGeneratingSet: for a 2-generated semigroup, 1
gap> S := SymmetricInverseMonoid(1);
<symmetric inverse monoid of degree 1>
gap> x := MinimalSemigroupGeneratingSet(S);
[ <empty partial perm>, <identity partial perm on [ 1 ]> ]
gap> Length(x);
2
gap> S = Semigroup(x);
true

#T# MinimalSemigroupGeneratingSet: for a semigroup with identity adjoined, 1
gap> S := Monoid(RectangularBand(IsBipartitionSemigroup, 2, 2));
<bipartition monoid of degree 2 with 2 generators>
gap> x := MinimalSemigroupGeneratingSet(S);;
gap> Length(x);
3
gap> S = Semigroup(x);
true

#T# MinimalSemigroupGeneratingSet: for a semigroup with zero adjoined, 1
gap> S := ReesZeroMatrixSemigroup(Group(()), [[(), ()]]);
<Rees 0-matrix semigroup 2x1 over Group(())>
gap> x := MinimalSemigroupGeneratingSet(S);
[ 0, (1,(),1), (2,(),1) ]
gap> Length(x);
3
gap> S = Semigroup(x);
true

#T# MinimalSemigroupGeneratingSet: decomposable elements, 1
gap> S := Semigroup(ZeroSemigroup(IsPartialPermSemigroup, 4));
<partial perm semigroup of rank 3 with 3 generators>
gap> x := MinimalSemigroupGeneratingSet(S);
[ [1,2], [3,4], [5,6] ]
gap> Length(x);
3
gap> S = Semigroup(x);
true
gap> S := Semigroup(Elements(S));
<partial perm semigroup of rank 3 with 4 generators>
gap> x := MinimalSemigroupGeneratingSet(S);
[ [1,2], [3,4], [5,6] ]
gap> Length(x);
3

#T# MinimalSemigroupGeneratingSet: decomposable elements, 2
gap> S := Monoid([
> Transformation([1, 1, 1, 2]),
> Transformation([1, 1, 2, 1]),
> Transformation([1, 1, 2, 2]),
> Transformation([1, 1, 1, 1, 6, 5])]);
<transformation monoid of degree 6 with 4 generators>
gap> x := MinimalSemigroupGeneratingSet(S);
[ IdentityTransformation, Transformation( [ 1, 1, 1, 1, 6, 5 ] ),
Transformation( [ 1, 1, 1, 2 ] ), Transformation( [ 1, 1, 2, 1 ] ),
Transformation( [ 1, 1, 2, 2 ] ) ]
gap> Length(x);
5
gap> S = Semigroup(x);
true

#T# MinimalSemigroupGeneratingSet: for a group as semigroup, 1
gap> S = Semigroup(x);
true
gap> S := Semigroup([
> Transformation([1, 3, 2, 1]),
> Transformation([2, 1, 3, 2]),
> Transformation([3, 1, 2, 3])]);
<transformation semigroup of degree 4 with 3 generators>
gap> x := MinimalSemigroupGeneratingSet(S);;
gap> Length(x);
2
gap> S = Semigroup(x);
true

#T# MinimalSemigroupGeneratingSet: for a monoid, 1
gap> S := FullTransformationMonoid(4);
<full transformation monoid of degree 4>
gap> x := MinimalSemigroupGeneratingSet(S);;
gap> Length(x);
3
gap> S = Semigroup(x);
true

#T# MinimalSemigroupGeneratingSet: for a d-trivial semigroup, 1
gap> n := 3;;
gap> S := UnitriangularBooleanMatMonoid(n);
<monoid of 3x3 boolean matrices with 3 generators>
gap> x := MinimalSemigroupGeneratingSet(S);;
gap> Length(x);
4
gap> S = Semigroup(x);
true

#T# MinimalSemigroupGeneratingSet: not yet implemented, 1
gap> S := PartitionMonoid(4);
<regular bipartition *-monoid of size 4140, degree 4 with 4 generators>
gap> x := MinimalSemigroupGeneratingSet(S);
Error, not yet implemented,

#T# SEMIGROUPS_UnbindVariables
gap> Unbind(D);
gap> Unbind(G);
Expand Down

0 comments on commit 1b8451e

Please sign in to comment.