#############################################################################
##
#W  attr.xml
#Y  Copyright (C) 2011-17                                James D. Mitchell
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

<#GAPDoc Label="EndomorphismMonoid">
<ManSection>
  <Attr Name="EndomorphismMonoid" Arg="digraph" Label="for a digraph"/>
  <Oper Name="EndomorphismMonoid" Arg="digraph, colors"
    Label="for a digraph and vertex coloring"/>
  <Returns> A monoid.</Returns>
  <Description>
    An endomorphism of <A>digraph</A> is a homomorphism
    <Ref Oper="DigraphHomomorphism" BookName="digraphs"/> from <A>digraph</A>
    back to itself.<P/>

    <C>EndomorphismMonoid</C>, called with a single argument,
    returns the monoid of all endomorphisms of <A>digraph</A>. <P/>

    If the <A>colors</A> argument is specified, then it will return
    the monoid of endomorphisms which respect the given colouring.
    The colouring <A>colors</A> can be in one of two forms: <P/>

    <List>
      <Item>
        A list of positive integers of size the number of vertices of
        <A>digraph</A>, where <A>colors</A><C>[i]</C> is the colour of vertex
        <C>i</C>.
      </Item>
      <Item>
        A list of lists, such that <A>colors</A><C>[i]</C> is a list of all
        vertices with colour <C>i</C>.
      </Item>
    </List>

    See also <Ref Func="GeneratorsOfEndomorphismMonoid" BookName="digraphs"/>.
    Note that the performance of <C>EndomorphismMonoid</C> may differ from that
    of <Ref Func="GeneratorsOfEndomorphismMonoid" BookName="digraphs"/> since
    the former incrementally adds newly discovered endomorphisms to the monoid
    using <Ref Oper="ClosureMonoid"/>.

    <Example><![CDATA[
gap> gr := Digraph(List([1 .. 3], x -> [1 .. 3]));;
gap> EndomorphismMonoid(gr);
<transformation monoid of degree 3 with 3 generators>
gap> gr := CompleteDigraph(3);;
gap> EndomorphismMonoid(gr);
<transformation group of size 6, degree 3 with 2 generators>
gap> S := EndomorphismMonoid(gr, [1, 2, 2]);;
gap> IsGroupAsSemigroup(S);
true
gap> Size(S);
2
gap> S := EndomorphismMonoid(gr, [[1], [2, 3]]);;
gap> S := EndomorphismMonoid(gr, [1, 2, 2]);;
gap> IsGroupAsSemigroup(S);
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="StructureDescription">
  <ManSection>
    <Attr Name="StructureDescription" Arg="class" Label="for an H-class"/>
    <Returns>A string or <K>fail</K>.</Returns>
    <Description>
      <C>StructureDescription</C> returns the value of
      <Ref Attr="StructureDescription" BookName="ref"/> when it is applied to
      a group isomorphic to the group &H;-class <A>class</A>. If <A>class</A> is
      not a group &H;-class, then <K>fail</K> is returned.
      <Example><![CDATA[
gap> S := Semigroup(
> PartialPerm([1, 2, 3, 4, 6, 7, 8, 9],
>             [1, 9, 4, 3, 5, 2, 10, 7]),
> PartialPerm([1, 2, 4, 7, 8, 9],
>             [6, 2, 4, 9, 1, 3]));;
gap> H := HClass(S, PartialPerm([1, 2, 3, 4, 7, 9],
>                               [1, 7, 3, 4, 9, 2]));;
gap> StructureDescription(H);
"C6"]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsGreensDGreaterThanFunc">
<ManSection>
  <Attr Name="IsGreensDGreaterThanFunc" Arg="S"/>
  <Returns>A function.</Returns>
  <Description>
    <C>IsGreensDGreaterThanFunc(<A>S</A>)</C> returns a function <C>func</C>
    such that for any two elements <C>x</C> and <C>y</C> of <A>S</A>,
    <C>func(x, y)</C> return <K>true</K> if the &D;-class of <C>x</C> in
    <A>S</A> is greater than or equal to the &D;-class of <C>y</C> in <A>S</A>
    under the usual ordering of Green's &D;-classes of a semigroup.

  <Example><![CDATA[
gap> S := Semigroup(Transformation([1, 3, 4, 1, 3]),
>                   Transformation([2, 4, 1, 5, 5]),
>                   Transformation([2, 5, 3, 5, 3]),
>                   Transformation([5, 5, 1, 1, 3]));;
gap> reps := ShallowCopy(AsSet(DClassReps(S)));
[ Transformation( [ 1, 1, 1, 1, 1 ] ),
  Transformation( [ 1, 3, 1, 3, 3 ] ),
  Transformation( [ 1, 3, 4, 1, 3 ] ),
  Transformation( [ 2, 4, 1, 5, 5 ] ) ]
gap> Sort(reps, IsGreensDGreaterThanFunc(S));
gap> reps;
[ Transformation( [ 2, 4, 1, 5, 5 ] ),
  Transformation( [ 1, 3, 4, 1, 3 ] ),
  Transformation( [ 1, 3, 1, 3, 3 ] ),
  Transformation( [ 1, 1, 1, 1, 1 ] ) ]
gap> IsGreensLessThanOrEqual(DClass(S, reps[2]),
>                            DClass(S, reps[1]));
true
gap> S := DualSymmetricInverseMonoid(4);;
gap> IsGreensDGreaterThanFunc(S)(S.1, S.3);
true
gap> IsGreensDGreaterThanFunc(S)(S.3, S.1);
false
gap> IsGreensLessThanOrEqual(DClass(S, S.3),
>                            DClass(S, S.1));
true
gap> IsGreensLessThanOrEqual(DClass(S, S.1),
>                            DClass(S, S.3));
false]]></Example>
    </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="StructureDescriptionMaximalSubgroups">
  <ManSection>
    <Attr Name="StructureDescriptionMaximalSubgroups" Arg="S"/>
    <Returns>Distinct structure descriptions of the maximal subgroups
      of a semigroup.</Returns>
    <Description>
      <C>StructureDescriptionMaximalSubgroups</C> returns the distinct values of
      <Ref Attr="StructureDescription" BookName="ref"/> when it is applied to
      the maximal subgroups of the semigroup <A>S</A>.
    <Example><![CDATA[
gap> S := DualSymmetricInverseSemigroup(6);
<inverse block bijection monoid of degree 6 with 3 generators>
gap> StructureDescriptionMaximalSubgroups(S);
[ "1", "C2", "S3", "S4", "S5", "S6" ]
gap> S := Semigroup(
>  PartialPerm([1, 3, 4, 5, 8],
>              [8, 3, 9, 4, 5]),
>  PartialPerm([1, 2, 3, 4, 8],
>              [10, 4, 1, 9, 6]),
>  PartialPerm([1, 2, 3, 4, 5, 6, 7, 10],
>              [4, 1, 6, 7, 5, 3, 2, 10]),
>  PartialPerm([1, 2, 3, 4, 6, 8, 10],
>              [4, 9, 10, 3, 1, 5, 2]));;
gap> StructureDescriptionMaximalSubgroups(S);
[ "1", "C2", "C3", "C4" ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="MinimalDClass">
  <ManSection>
    <Attr Name="MinimalDClass" Arg="S"/>
    <Returns>The minimal &D;-class of a semigroup.</Returns>
    <Description>
      The minimal ideal of a semigroup is the least ideal with respect to
      containment. <C>MinimalDClass</C> returns the &D;-class corresponding to
      the minimal ideal of the semigroup <A>S</A>. Equivalently,
      <C>MinimalDClass</C> returns the minimal &D;-class with respect to the
      partial order of &D;-classes.<P/>

      It is significantly easier to find the minimal &D;-class of a semigroup,
      than to find its &D;-classes. <P/>

      See also <Ref Attr="PartialOrderOfDClasses"/>,
      <Ref Oper="IsGreensLessThanOrEqual" BookName="ref"/>,
      <Ref Attr="MinimalIdeal"/> and
      <Ref Attr="RepresentativeOfMinimalIdeal"/>.
      <Example><![CDATA[
gap> D := MinimalDClass(JonesMonoid(8));
<Green's D-class: <bipartition: [ 1, 2 ], [ 3, 4 ], [ 5, 6 ],
  [ 7, 8 ], [ -1, -2 ], [ -3, -4 ], [ -5, -6 ], [ -7, -8 ]>>
gap> S := InverseSemigroup(
> PartialPerm([1, 2, 3, 5, 7, 8, 9], [2, 6, 9, 1, 5, 3, 8]),
> PartialPerm([1, 3, 4, 5, 7, 8, 9], [9, 4, 10, 5, 6, 7, 1]));;
gap> MinimalDClass(S);
<Green's D-class: <empty partial perm>>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="MaximalXClasses">
  <ManSection>
    <Heading>MaximalXClasses</Heading>
    <Attr Name="MaximalDClasses" Arg="S"/>
    <Attr Name="MaximalLClasses" Arg="S"/>
    <Attr Name="MaximalRClasses" Arg="S"/>
    <Returns>The maximal &D;, &L;, or &R;-classes of a semigroup.</Returns>
    <Description>
      Let <C>X</C> be one of Green's &D;-, &L;-, or &R;-relations. Then
      <C>MaximalXClasses</C> returns the maximal Green's <C>X</C>-classes with
      respect to the partial order of <C>X</C>-classes. <P/>

      See also <Ref Attr="PartialOrderOfDClasses"/>,
      <Ref Oper="IsGreensLessThanOrEqual" BookName="ref"/>, and
      <Ref Attr="MinimalDClass"/>.

      <Example><![CDATA[
gap> MaximalDClasses(BrauerMonoid(8));
[ <Green's D-class: <block bijection: [ 1, -1 ], [ 2, -2 ],
      [ 3, -3 ], [ 4, -4 ], [ 5, -5 ], [ 6, -6 ], [ 7, -7 ],
      [ 8, -8 ]>> ]
gap> MaximalDClasses(FullTransformationMonoid(5));
[ <Green's D-class: IdentityTransformation> ]
gap> S := Semigroup(
> PartialPerm([1, 2, 3, 4, 5, 6, 7], [3, 8, 1, 4, 5, 6, 7]),
> PartialPerm([1, 2, 3, 6, 8], [2, 6, 7, 1, 5]),
> PartialPerm([1, 2, 3, 4, 6, 8], [4, 3, 2, 7, 6, 5]),
> PartialPerm([1, 2, 4, 5, 6, 7, 8], [7, 1, 4, 2, 5, 6, 3]));;
gap> MaximalDClasses(S);
[ <Green's D-class: [2,8](1,3)(4)(5)(6)(7)>,
  <Green's D-class: [8,3](1,7,6,5,2)(4)> ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="PrincipalFactor">
<ManSection>
  <Attr Name="PrincipalFactor" Arg="D"/>
  <Attr Name="NormalizedPrincipalFactor" Arg="D"/>
  <Returns>A Rees (0-)matrix semigroup.</Returns>
  <Description>
    If <A>D</A> is a &D;-class of semigroup, then
    <C>PrincipalFactor(<A>D</A>)</C> is just shorthand for
    <C>Range(InjectionPrincipalFactor(<A>D</A>))</C>, and
    <C>NormalizedPrincipalFactor(<A>D</A>)</C> is shorthand for
    <C>Range(InjectionNormalizedPrincipalFactor(<A>D</A>))</C>.
    <P/>

    See <Ref Attr="InjectionPrincipalFactor"/> and <Ref
      Attr="InjectionNormalizedPrincipalFactor"/> for more details.
    <Example><![CDATA[
gap> S := Semigroup([PartialPerm([1, 2, 3], [1, 3, 4]),
>  PartialPerm([1, 2, 3], [2, 5, 3]),
>  PartialPerm([1, 2, 3, 4], [2, 4, 1, 5]),
>  PartialPerm([1, 3, 5], [5, 1, 3])]);;
gap> PrincipalFactor(MinimalDClass(S));
<Rees matrix semigroup 1x1 over Group(())>
gap> MultiplicativeZero(S);
<empty partial perm>
gap> S := Semigroup(
> Bipartition([[1, 2, 3, 4, 5, -1, -3], [-2, -5], [-4]]),
> Bipartition([[1, -5], [2, 3, 4, 5, -1, -3], [-2, -4]]),
> Bipartition([[1, 5, -4], [2, 4, -1, -5], [3, -2, -3]]));;
gap> D := MinimalDClass(S);
<Green's D-class: <bipartition: [ 1, 2, 3, 4, 5, -1, -3 ],
  [ -2, -5 ], [ -4 ]>>
gap> NormalizedPrincipalFactor(D);
<Rees matrix semigroup 1x5 over Group(())>]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="SmallGeneratingSet">
<ManSection>
  <Attr Name="SmallGeneratingSet" Arg="coll"/>
  <Attr Name="SmallSemigroupGeneratingSet" Arg="coll"/>
  <Attr Name="SmallMonoidGeneratingSet" Arg="coll"/>
  <Attr Name="SmallInverseSemigroupGeneratingSet" Arg="coll"/>
  <Attr Name="SmallInverseMonoidGeneratingSet" Arg="coll"/>
  <Returns>A small generating set for a semigroup.</Returns>
  <Description>
    The attributes <C>SmallXGeneratingSet</C> return a relatively small
    generating subset of the collection of elements <A>coll</A>, which can also
    be a semigroup. The returned value of <C>SmallXGeneratingSet</C>, where
    applicable, has the property that
    <Log>
      X(SmallXGeneratingSet(coll)) = X(coll);</Log>
    where <C>X</C> is any of
    <Ref Func="Semigroup" BookName="ref"/>,
    <Ref Func="Monoid" BookName="ref"/>,
    <Ref Func="InverseSemigroup" BookName="ref"/>, or
    <Ref Func="InverseMonoid" BookName="ref"/>.<P/>

    If the number of generators for <A>S</A> is already relatively small, then
    these functions will often return the original generating set.  These
    functions may return different results in different &GAP; sessions.<P/>

    <C>SmallGeneratingSet</C> returns the smallest of the returned values of
    <C>SmallXGeneratingSet</C> which is applicable to <A>coll</A>; see <Ref
      Attr="Generators"/>.<P/>

    As neither irredundancy, nor minimal length are proven, these functions
    usually return an answer much more quickly than <Ref
      Oper="IrredundantGeneratingSubset"/>. These functions can be used whenever
    a small generating set is desired which does not necessarily needs to be
    minimal.

      <Log><![CDATA[
gap> S := Semigroup([
> Transformation([1, 2, 3, 2, 4]),
> Transformation([1, 5, 4, 3, 2]),
> Transformation([2, 1, 4, 2, 2]),
> Transformation([2, 4, 4, 2, 1]),
> Transformation([3, 1, 4, 3, 2]),
> Transformation([3, 2, 3, 4, 1]),
> Transformation([4, 4, 3, 3, 5]),
> Transformation([5, 1, 5, 5, 3]),
> Transformation([5, 4, 3, 5, 2]),
> Transformation([5, 5, 4, 5, 5])]);;
gap> SmallGeneratingSet(S);
[ Transformation( [ 1, 5, 4, 3, 2 ] ), Transformation( [ 3, 2, 3, 4, 1 ] ),
  Transformation( [ 5, 4, 3, 5, 2 ] ), Transformation( [ 1, 2, 3, 2, 4 ] ),
  Transformation( [ 4, 4, 3, 3, 5 ] ) ]
gap> S := RandomInverseMonoid(IsPartialPermMonoid, 10000, 10);;
gap> SmallGeneratingSet(S);
[ [ 1 .. 10 ] -> [ 3, 2, 4, 5, 6, 1, 7, 10, 9, 8 ],
  [ 1 .. 10 ] -> [ 5, 10, 8, 9, 3, 2, 4, 7, 6, 1 ],
  [ 1, 3, 4, 5, 6, 7, 8, 9, 10 ] -> [ 1, 6, 4, 8, 2, 10, 7, 3, 9 ] ]
gap> M := MathieuGroup(24);;
gap> mat := List([1 .. 1000], x -> Random(M));;
gap> Append(mat, [1 .. 1000] * 0);
gap> mat := List([1 .. 138], x -> List([1 .. 57], x -> Random(mat)));;
gap> R := ReesZeroMatrixSemigroup(M, mat);;
gap> U := Semigroup(List([1 .. 200], x -> Random(R)));
<subsemigroup of 57x138 Rees 0-matrix semigroup with 100 generators>
gap> Length(SmallGeneratingSet(U));
84
gap> S := RandomSemigroup(IsBipartitionSemigroup, 100, 4);
<bipartition semigroup of degree 4 with 96 generators>
gap> Length(SmallGeneratingSet(S));
13]]></Log>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="MinimalGeneratingSet">
<ManSection>
  <Attr Name="MinimalSemigroupGeneratingSet" Arg="S"/>
  <Attr Name="MinimalMonoidGeneratingSet" Arg="S"/>
  <Attr Name="MinimalInverseSemigroupGeneratingSet" Arg="S"/>
  <Attr Name="MinimalInverseMonoidGeneratingSet" Arg="S"/>
  <Returns>A minimal generating set for a semigroup.</Returns>
  <Description>
    The attribute <C>MinimalXGeneratingSet</C> returns a minimal generating set
    for the semigroup <A>S</A>, with respect to length. The returned value of
    <C>MinimalXGeneratingSet</C>, where applicable, is a minimal-length list
    of elements of <A>S</A> with the property that
    <Log>
      X(MinimalXGeneratingSet(S)) = S;
    </Log>
    where <C>X</C> is one of
    <Ref Func="Semigroup" BookName="ref"/>,
    <Ref Func="Monoid" BookName="ref"/>,
    <Ref Func="InverseSemigroup" BookName="ref"/>, or
    <Ref Func="InverseMonoid" BookName="ref"/>.<P/>

    For many types of semigroup, it is not currently possible to find a
    <C>MinimalXGeneratingSet</C> with the &SEMIGROUPS; package. <P/>

    See also <Ref Attr="SmallGeneratingSet"/> and <Ref
      Oper="IrredundantGeneratingSubset"/>.

      <Example><![CDATA[
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 := Monoid([
>  PartialPerm([2, 3, 4, 5, 1, 0, 6, 7]),
>  PartialPerm([3, 4, 5, 1, 2, 0, 0, 6])]);
<partial perm monoid of rank 8 with 2 generators>
gap> IsMonogenicMonoid(S);
true
gap> MinimalMonoidGeneratingSet(S);
[ [8,7,6](1,2,3,4,5) ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="MultiplicativeZero">
  <ManSection>
    <Attr Name="MultiplicativeZero" Arg="S"/>
    <Returns>
     The zero element of a semigroup.
    </Returns>
    <Description>
      <C>MultiplicativeZero</C> returns the zero element of the semigroup
      <A>S</A> if it exists and <K>fail</K> if it does not.
      See also <Ref Attr="MultiplicativeZero" BookName="ref"/>.
      <Example><![CDATA[
gap> S := Semigroup(Transformation([1, 4, 2, 6, 6, 5, 2]),
>                   Transformation([1, 6, 3, 6, 2, 1, 6]));;
gap> MultiplicativeZero(S);
Transformation( [ 1, 1, 1, 1, 1, 1, 1 ] )
gap> S := Semigroup(Transformation([2, 8, 3, 7, 1, 5, 2, 6]),
>                   Transformation([3, 5, 7, 2, 5, 6, 3, 8]),
>                   Transformation([6, 7, 4, 1, 4, 1, 6, 2]),
>                   Transformation([8, 8, 5, 1, 7, 5, 2, 8]));;
gap> MultiplicativeZero(S);
fail
gap> S := InverseSemigroup(
> PartialPerm([1, 3, 4], [5, 3, 1]),
> PartialPerm([1, 2, 3, 4], [4, 3, 1, 2]),
> PartialPerm([1, 3, 4, 5], [2, 4, 5, 3]));;
gap> MultiplicativeZero(S);
<empty partial perm>
gap> S := PartitionMonoid(6);
<regular bipartition *-monoid of size 4213597, degree 6 with 4
 generators>
gap> MultiplicativeZero(S);
fail
gap> S := DualSymmetricInverseMonoid(6);
<inverse block bijection monoid of degree 6 with 3 generators>
gap> MultiplicativeZero(S);
<block bijection: [ 1, 2, 3, 4, 5, 6, -1, -2, -3, -4, -5, -6 ]>]]>
</Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="MinimalIdeal">
  <ManSection>
    <Attr Name="MinimalIdeal" Arg="S"/>
    <Returns>
    The minimal ideal of a semigroup.
    </Returns>
    <Description>
    The minimal ideal of a semigroup is the least ideal with respect to
    containment. <P/>

    It is significantly easier to find the minimal &D;-class of a semigroup,
    than to find its &D;-classes. <P/>

    See also <Ref Attr="RepresentativeOfMinimalIdeal"/>,
    <Ref Attr="PartialOrderOfDClasses"/>,
    <Ref Oper="IsGreensLessThanOrEqual" BookName="ref"/>, and
    <Ref Attr="MinimalDClass"/>.
    <Example><![CDATA[
gap> S := Semigroup(
> Transformation([3, 4, 1, 3, 6, 3, 4, 6, 10, 1]),
> Transformation([8, 2, 3, 8, 4, 1, 3, 4, 9, 7]));;
gap> MinimalIdeal(S);
<simple transformation semigroup ideal of degree 10 with 1 generator>
gap> Elements(MinimalIdeal(S));
[ Transformation( [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] ),
  Transformation( [ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ] ),
  Transformation( [ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ] ),
  Transformation( [ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 ] ),
  Transformation( [ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ] ) ]
gap> x := Transformation([8, 8, 8, 8, 8, 8, 8, 8, 8, 8]);;
gap> D := DClass(S, x);;
gap> ForAll(GreensDClasses(S), x -> IsGreensLessThanOrEqual(D, x));
true
gap> MinimalIdeal(POI(10));
<partial perm group of rank 0>
gap> MinimalIdeal(BrauerMonoid(6));
<simple bipartition *-semigroup ideal of degree 6 with 1 generator>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="LengthOfLongestDClassChain">
  <ManSection>
    <Attr Name="LengthOfLongestDClassChain" Arg="S"/>
    <Returns>
    A non-negative integer.
    </Returns>
    <Description>
      If <A>S</A> is a semigroup, then <C>LengthOfLongestDClassChain</C> returns
      the length of the longest chain in the partial order defined by
      <C>PartialOrderOfDClasses(<A>S</A>)</C>.  See <Ref Attr =
        "PartialOrderOfDClasses" />. <P/>

      The partial order on the &D;-classes is defined by <M>x\leq y</M> if and
      only if <M>S ^ 1xS ^ 1</M> is a subset of  <M>S ^ 1yS ^ 1</M>. A
      <E>chain</E> of &D;-classes is a collection of <C>n</C> &D;-classes
      <M>D_{1}, D_{2}, \ldots D_{n}</M> such that <M>D_{1} &lt; D_{2} &lt;
        \cdots &lt; D_{n}</M>.  The <E>length</E> of such a chain is <C>n -
        1</C>.

      <Example><![CDATA[
gap> S := TrivialSemigroup();;
gap> LengthOfLongestDClassChain(S);
0
gap> T := ZeroSemigroup(5);;
gap> LengthOfLongestDClassChain(T);
1
gap> U := MonogenicSemigroup(14, 7);;
gap> LengthOfLongestDClassChain(U);
13
gap> V := FullTransformationMonoid(6);
<full transformation monoid of degree 6>
gap> LengthOfLongestDClassChain(V);
5]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RepresentativeOfMinimalIdeal">
  <ManSection>
    <Attr Name="RepresentativeOfMinimalIdeal" Arg="S"/>
    <Attr Name="RepresentativeOfMinimalDClass" Arg="S"/>
    <Returns>
      An element of the minimal ideal of a semigroup.
    </Returns>
    <Description>
      The minimal ideal of a semigroup is the least ideal with respect to
      containment.<P/>

      This method returns a representative element of the
      minimal ideal of <A>S</A> without having
      to create the minimal ideal itself.
      In general, beyond being a member of the minimal ideal,
      the returned element is not guaranteed to have any special properties.
      However, the element will coincide with the zero element of <A>S</A>
      if one exists.
      <P/>

      This method works particularly well if <A>S</A> is a semigroup
      of transformations or partial permutations.<P/>

      See also <Ref Attr="MinimalIdeal"/> and <Ref Attr="MinimalDClass"/>.
    <Example><![CDATA[
gap> S := SymmetricInverseSemigroup(10);;
gap> RepresentativeOfMinimalIdeal(S);
<empty partial perm>
gap> B := Semigroup([
> Bipartition([[1, 2], [3, 6, -2], [4, 5, -3, -4], [-1, -6], [-5]]),
> Bipartition([[1, -1], [2], [3], [4, -3], [5, 6, -5, -6],
>   [-2, -4]])]);;
gap> RepresentativeOfMinimalIdeal(B);
<bipartition: [ 1, 2 ], [ 3, 6 ], [ 4, 5 ], [ -1, -5, -6 ],
 [ -2, -4 ], [ -3 ]>
gap> S := Semigroup(Transformation([5, 1, 6, 2, 2, 4]),
>                   Transformation([3, 5, 5, 1, 6, 2]));;
gap> RepresentativeOfMinimalDClass(S);
Transformation( [ 5, 6, 6, 3, 3, 5 ] )
gap> MinimalDClass(S);
<Green's D-class: Transformation( [ 5, 6, 6, 3, 3, 5 ] )>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsomorphismPermGroup">
<ManSection>
  <Attr Name="IsomorphismPermGroup" Arg="S"/>
  <Returns> An isomorphism. </Returns>
  <Description>
    If the semigroup <A>S</A> is mathematically a group, so that it satisfies
    <Ref Prop="IsGroupAsSemigroup"/>, then <C>IsomorphismPermGroup</C> returns
    an isomorphism to a permutation group.<P/>

    If <A>S</A> is not a group then an error is given.<P/>

    See also <Ref Attr="IsomorphismPermGroup" BookName="ref"/>.

<Example><![CDATA[
gap> S := Semigroup(Transformation([2, 2, 3, 4, 6, 8, 5, 5]),
>                   Transformation([3, 3, 8, 2, 5, 6, 4, 4]));;
gap> IsGroupAsSemigroup(S);
true
gap> iso := IsomorphismPermGroup(S);;
gap> Source(iso) = S and Range(iso) = Group([(5, 6, 8), (2, 3, 8, 4)]);
true
gap> StructureDescription(Range(IsomorphismPermGroup(S)));
"S6"
gap> S := Range(IsomorphismPartialPermSemigroup(SymmetricGroup(4)));
<partial perm group of size 24, rank 4 with 2 generators>
gap> Range(IsomorphismPermGroup(S));
Group([ (1,2,3,4), (1,2) ])
gap> G := GroupOfUnits(PartitionMonoid(4));
<block bijection group of degree 4 with 2 generators>
gap> StructureDescription(G);
"S4"
gap> iso := IsomorphismPermGroup(G);;
gap> RespectsMultiplication(iso);
true
gap> inv := InverseGeneralMapping(iso);;
gap> ForAll(G, x -> (x ^ iso) ^ inv = x);
true
gap> ForAll(G, x -> ForAll(G, y -> (x * y) ^ iso = x ^ iso * y ^ iso));
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="GroupOfUnits">
  <ManSection>
    <Attr Name="GroupOfUnits" Arg="S"/>
    <Returns>The group of units of a semigroup or <K>fail</K>.</Returns>
    <Description>
      <C>GroupOfUnits</C> returns the group of units of the semigroup <A>S</A>
      as a subsemigroup of <A>S</A> if it exists and returns <K>fail</K> if it
      does not. Use <Ref Attr="IsomorphismPermGroup"/> if you require a
      permutation representation of the group of units.<P/>

      If a semigroup <A>S</A> has an identity <C>e</C>, then the <E>group of
        units</E> of <A>S</A> is the set of those <C>s</C> in <A>S</A> such that
      there exists <C>t</C> in <A>S</A> where <C>s*t=t*s=e</C>. Equivalently,
      the group of units is the &H;-class of the identity of <A>S</A>.<P/>

      See also
      <Ref Oper="GreensHClassOfElement" BookName="ref"/>,
      <Ref Prop="IsMonoidAsSemigroup"/>, and
      <Ref Meth="MultiplicativeNeutralElement" BookName="ref"/>.

      <Example><![CDATA[
gap> S := Semigroup(
> Transformation([1, 2, 5, 4, 3, 8, 7, 6]),
> Transformation([1, 6, 3, 4, 7, 2, 5, 8]),
> Transformation([2, 1, 6, 7, 8, 3, 4, 5]),
> Transformation([3, 2, 3, 6, 1, 6, 1, 2]),
> Transformation([5, 2, 3, 6, 3, 4, 7, 4]));;
gap> Size(S);
5304
gap> StructureDescription(GroupOfUnits(S));
"C2 x S4"
gap> S := InverseSemigroup(
> PartialPerm([1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
>             [2, 4, 5, 3, 6, 7, 10, 9, 8, 1]),
> PartialPerm([1, 2, 3, 4, 5, 6, 7, 8, 10],
>             [8, 2, 3, 1, 4, 5, 10, 6, 9]));;
gap> StructureDescription(GroupOfUnits(S));
"C8"
gap> S := InverseSemigroup(
> PartialPerm([1, 3, 4], [4, 3, 5]),
> PartialPerm([1, 2, 3, 5], [3, 1, 5, 2]));;
gap> GroupOfUnits(S);
fail
gap> S := Semigroup(
> Bipartition([[1, 2, 3, -1, -3], [-2]]),
> Bipartition([[1, -1], [2, 3, -2, -3]]),
> Bipartition([[1, -2], [2, -3], [3, -1]]),
> Bipartition([[1], [2, 3, -2], [-1, -3]]));;
gap> StructureDescription(GroupOfUnits(S));
"C3"]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IdempotentGeneratedSubsemigroup">
  <ManSection>
    <Attr Name="IdempotentGeneratedSubsemigroup" Arg="S"/>
    <Returns>A semigroup.
    </Returns>
    <Description>
      <C>IdempotentGeneratedSubsemigroup</C> returns the subsemigroup of the
      semigroup <A>S</A> generated by the idempotents of <A>S</A>.<P/>

      See also <Ref Attr="Idempotents"/> and <Ref Attr="SmallGeneratingSet"/>.
<Example><![CDATA[
gap> S := Semigroup(Transformation([1, 1]),
>                   Transformation([2, 1]),
>                   Transformation([1, 2, 2]),
>                   Transformation([1, 2, 3, 4, 5, 1]),
>                   Transformation([1, 2, 3, 4, 5, 5]),
>                   Transformation([1, 2, 3, 4, 6, 5]),
>                   Transformation([1, 2, 3, 5, 4]),
>                   Transformation([1, 2, 3, 7, 4, 5, 7]),
>                   Transformation([1, 2, 4, 8, 8, 3, 8, 7]),
>                   Transformation([1, 2, 8, 4, 5, 6, 7, 8]),
>                   Transformation([7, 7, 7, 4, 5, 6, 1]));;
gap> IdempotentGeneratedSubsemigroup(S) =
> Monoid(Transformation([1, 1]),
>        Transformation([1, 2, 1]),
>        Transformation([1, 2, 2]),
>        Transformation([1, 2, 3, 1]),
>        Transformation([1, 2, 3, 2]),
>        Transformation([1, 2, 3, 4, 1]),
>        Transformation([1, 2, 3, 4, 2]),
>        Transformation([1, 2, 3, 4, 4]),
>        Transformation([1, 2, 3, 4, 5, 1]),
>        Transformation([1, 2, 3, 4, 5, 2]),
>        Transformation([1, 2, 3, 4, 5, 5]),
>        Transformation([1, 2, 3, 4, 5, 7, 7]),
>        Transformation([1, 2, 3, 4, 7, 6, 7]),
>        Transformation([1, 2, 3, 6, 5, 6]),
>        Transformation([1, 2, 3, 7, 5, 6, 7]),
>        Transformation([1, 2, 8, 4, 5, 6, 7, 8]),
>        Transformation([2, 2]));
true
gap> S := SymmetricInverseSemigroup(5);
<symmetric inverse monoid of degree 5>
gap> IdempotentGeneratedSubsemigroup(S);
<inverse partial perm monoid of rank 5 with 5 generators>
gap> S := DualSymmetricInverseSemigroup(5);
<inverse block bijection monoid of degree 5 with 3 generators>
gap> IdempotentGeneratedSubsemigroup(S);
<inverse block bijection monoid of degree 5 with 10 generators>
gap> IsSemilattice(last);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="InjectionPrincipalFactor">
<ManSection>
  <Attr Name="InjectionPrincipalFactor" Arg="D"/>
  <Attr Name="InjectionNormalizedPrincipalFactor" Arg="D"/>
  <Attr Name="IsomorphismReesMatrixSemigroup" Arg="D" Label="for a D-class"/>
  <Returns>A injective mapping.</Returns>
  <Description>
    If the &D;-class <A>D</A> is a subsemigroup of a semigroup <C>S</C>, then
    the <E>principal factor</E> of <A>D</A> is just <A>D</A> itself.  If
    <A>D</A> is not a subsemigroup of <C>S</C>, then the principal factor of
    <A>D</A> is the semigroup with elements <A>D</A> and a new element <C>0</C>
    with multiplication of <M>x,y\in D</M> defined by:
    <Alt Not="Text">
      <Display>
        xy=\left\{\begin{array}{ll}
        x*y\ (\textrm{in }S)&amp;\textrm{if }x*y\in D\\
        0&amp;\textrm{if }xy\not\in D.
        \end{array}\right.
      </Display>
    </Alt>
    <Alt Only="Text">
      <C>xy</C> equals the product of <C>x</C> and <C>y</C> if it belongs to
      <A>D</A> and <C>0</C> if it does not. <P/>
    </Alt>
    <C>InjectionPrincipalFactor</C> returns an injective function
    from the &D;-class <A>D</A> to a Rees (0-)matrix semigroup, which
    contains the principal factor of <A>D</A> as a subsemigroup. <P/>

    If <A>D</A> is a subsemigroup of its parent semigroup, then the
    function returned by <C>InjectionPrincipalFactor</C> or
    <C>IsomorphismReesMatrixSemigroup</C> is an isomorphism from <A>D</A> to a
    Rees matrix semigroup; see <Ref Func="ReesMatrixSemigroup"
      BookName="ref"/>.<P/>

    If <A>D</A> is not a semigroup, then the function returned by
    <C>InjectionPrincipalFactor</C> is an injective function from <A>D</A> to a
    Rees 0-matrix semigroup isomorphic to the principal factor of <A>D</A>; see
    <Ref Func="ReesZeroMatrixSemigroup" BookName="ref"/>. In this case,
    <C>IsomorphismReesMatrixSemigroup</C> and
    <C>IsomorphismReesZeroMatrixSemigroup</C> returns an error.<P/>

    <C>InjectionNormalizedPrincipalFactor</C> returns the composition of
    <C>InjectionPrincipalFactor</C> with <Ref Attr="RZMSNormalization"/> or
    <Ref Attr="RMSNormalization"/> as appropriate.<P/>

    See also <Ref Attr="PrincipalFactor"/>.

    <Example><![CDATA[
gap> S := InverseSemigroup(
> PartialPerm([1, 2, 3, 6, 8, 10],
>             [2, 6, 7, 9, 1, 5]),
> PartialPerm([1, 2, 3, 4, 6, 7, 8, 10],
>             [3, 8, 1, 9, 4, 10, 5, 6]));;
gap> x := PartialPerm([1, 2, 5, 6, 7, 9],
>                     [1, 2, 5, 6, 7, 9]);;
gap> D := GreensDClassOfElement(S, x);
<Green's D-class: <identity partial perm on [ 1, 2, 5, 6, 7, 9 ]>>
gap> R := Range(InjectionPrincipalFactor(D));
<Rees 0-matrix semigroup 3x3 over Group(())>
gap> MatrixOfReesZeroMatrixSemigroup(R);
[ [ (), 0, 0 ], [ 0, (), 0 ], [ 0, 0, () ] ]
gap> Size(R);
10
gap> Size(D);
9
gap> S := Semigroup(
> Bipartition([[1, 2, 3, -3, -5], [4], [5, -2], [-1, -4]]),
> Bipartition([[1, 3, 5], [2, 4, -3], [-1, -2, -4, -5]]),
> Bipartition([[1, 5, -2, -4], [2, 3, 4, -1, -5], [-3]]),
> Bipartition([[1, 5, -1, -2, -3], [2, 4, -4], [3, -5]]));;
gap> D := GreensDClassOfElement(S,
> Bipartition([[1, 5, -2, -4], [2, 3, 4, -1, -5], [-3]]));
<Green's D-class: <bipartition: [ 1, 5, -2, -4 ], [ 2, 3, 4, -1, -5 ]
   , [ -3 ]>>
gap> InjectionNormalizedPrincipalFactor(D);
MappingByFunction( <Green's D-class: <bipartition: [ 1, 5, -2, -4 ],
  [ 2, 3, 4, -1, -5 ], [ -3 ]>>, <Rees matrix semigroup 1x1 over
  Group([ (1,2) ])>, function( x ) ... end, function( x ) ... end )]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsomorphismReesZeroMatrixSemigroup">
<ManSection>
  <Attr Name="IsomorphismReesMatrixSemigroup" Arg="S" Label="for a semigroup"/>
  <Attr Name="IsomorphismReesZeroMatrixSemigroup" Arg="S"/>
  <Attr Name="IsomorphismReesMatrixSemigroupOverPermGroup" Arg="S"/>
  <Attr Name="IsomorphismReesZeroMatrixSemigroupOverPermGroup" Arg="S"/>
  <Returns>An isomorphism.</Returns>
  <Description>
    If the semigroup <A>S</A> is finite and simple, then
    <C>IsomorphismReesMatrixSemigroup</C> returns an isomorphism to a Rees
    matrix semigroup over some group (usually a permutation group), and
    <C>IsomorphismReesMatrixSemigroupOverPermGroup</C> returns an isomorphism to
    a Rees matrix semigroup over a permutation group.  <P/>

    If <A>S</A> is finite and 0-simple, then
    <C>IsomorphismReesZeroMatrixSemigroup</C> returns an isomorphism to a Rees
    0-matrix semigroup over some group (usually a permutation group), and
    <C>IsomorphismReesZeroMatrixSemigroupOverPermGroup</C> returns an
    isomorphism to a Rees 0-matrix semigroup over a permutation group. <P/>

    See also <Ref Attr="InjectionPrincipalFactor"/>.

    <Example><![CDATA[
gap> S := Semigroup(PartialPerm([1]));
<trivial partial perm group of rank 1 with 1 generator>
gap> iso := IsomorphismReesMatrixSemigroup(S);;
gap> Source(iso) = S;
true
gap> Range(iso);
<Rees matrix semigroup 1x1 over Group(())>
gap> S := Semigroup(PartialPerm([1]), PartialPerm([]));
<partial perm monoid of rank 1 with 2 generators>
gap> Range(IsomorphismReesZeroMatrixSemigroup(S));
<Rees 0-matrix semigroup 1x1 over Group(())>]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IrredundantGeneratingSubset">
  <ManSection>
    <Oper Name="IrredundantGeneratingSubset" Arg="coll"/>
    <Returns>
      A list of irredundant generators.
    </Returns>
    <Description>
      If <A>coll</A> is a collection of elements of a semigroup, then this
      function returns a subset <C>U</C> of <A>coll</A> such that no element of
      <C>U</C> is generated by the other elements of <C>U</C>.<P/>

      <Log><![CDATA[
gap> S := Semigroup([
> Transformation([5, 1, 4, 6, 2, 3]),
> Transformation([1, 2, 3, 4, 5, 6]),
> Transformation([4, 6, 3, 4, 2, 5]),
> Transformation([5, 4, 6, 3, 1, 3]),
> Transformation([2, 2, 6, 5, 4, 3]),
> Transformation([3, 5, 5, 1, 2, 4]),
> Transformation([6, 5, 1, 3, 3, 4]),
> Transformation([1, 3, 4, 3, 2, 1])]);;
gap> IrredundantGeneratingSubset(S);
[ Transformation( [ 1, 3, 4, 3, 2, 1 ] ),
  Transformation( [ 2, 2, 6, 5, 4, 3 ] ),
  Transformation( [ 3, 5, 5, 1, 2, 4 ] ),
  Transformation( [ 5, 1, 4, 6, 2, 3 ] ),
  Transformation( [ 5, 4, 6, 3, 1, 3 ] ),
  Transformation( [ 6, 5, 1, 3, 3, 4 ] ) ]
gap> S := RandomInverseMonoid(IsPartialPermMonoid, 1000, 10);
<inverse partial perm monoid of degree 10 with 1000 generators>
gap> SmallGeneratingSet(S);
[ [ 1 .. 10 ] -> [ 6, 5, 1, 9, 8, 3, 10, 4, 7, 2 ],
  [ 1 .. 10 ] -> [ 1, 4, 6, 2, 8, 5, 7, 10, 3, 9 ],
  [ 1, 2, 3, 4, 6, 7, 8, 9 ] -> [ 7, 5, 10, 1, 8, 4, 9, 6 ]
  [ 1 .. 9 ] -> [ 4, 3, 5, 7, 10, 9, 1, 6, 8 ] ]
gap> IrredundantGeneratingSubset(last);
[ [ 1 .. 9 ] -> [ 4, 3, 5, 7, 10, 9, 1, 6, 8 ],
  [ 1 .. 10 ] -> [ 1, 4, 6, 2, 8, 5, 7, 10, 3, 9 ],
  [ 1 .. 10 ] -> [ 6, 5, 1, 9, 8, 3, 10, 4, 7, 2 ] ]
gap> S := RandomSemigroup(IsBipartitionSemigroup, 1000, 4);
<bipartition semigroup of degree 4 with 749 generators>
gap> SmallGeneratingSet(S);
[ <bipartition: [ 1, -3 ], [ 2, -2 ], [ 3, -1 ], [ 4, -4 ]>,
  <bipartition: [ 1, 3, -2 ], [ 2, -1, -3 ], [ 4, -4 ]>,
  <bipartition: [ 1, -4 ], [ 2, 4, -1, -3 ], [ 3, -2 ]>,
  <bipartition: [ 1, -1, -3 ], [ 2, -4 ], [ 3, 4, -2 ]>,
  <bipartition: [ 1, -2, -4 ], [ 2 ], [ 3, -3 ], [ 4, -1 ]>,
  <bipartition: [ 1, -2 ], [ 2, -1, -3 ], [ 3, 4, -4 ]>,
  <bipartition: [ 1, 3, -1 ], [ 2, -3 ], [ 4, -2, -4 ]>,
  <bipartition: [ 1, -1 ], [ 2, 4, -4 ], [ 3, -2, -3 ]>,
  <bipartition: [ 1, 3, -1 ], [ 2, -2 ], [ 4, -3, -4 ]>,
  <bipartition: [ 1, 2, -2 ], [ 3, -1, -4 ], [ 4, -3 ]>,
  <bipartition: [ 1, -2, -3 ], [ 2, -4 ], [ 3 ], [ 4, -1 ]>,
  <bipartition: [ 1, -1 ], [ 2, 4, -3 ], [ 3, -2 ], [ -4 ]>,
  <bipartition: [ 1, -3 ], [ 2, -1 ], [ 3, 4, -4 ], [ -2 ]>,
  <bipartition: [ 1, 2, -4 ], [ 3, -1 ], [ 4, -2 ], [ -3 ]>,
  <bipartition: [ 1, -3 ], [ 2, -4 ], [ 3, -1, -2 ], [ 4 ]> ]
gap> IrredundantGeneratingSubset(last);
[ <bipartition: [ 1, 2, -4 ], [ 3, -1 ], [ 4, -2 ], [ -3 ]>,
  <bipartition: [ 1, 3, -1 ], [ 2, -2 ], [ 4, -3, -4 ]>,
  <bipartition: [ 1, 3, -2 ], [ 2, -1, -3 ], [ 4, -4 ]>,
  <bipartition: [ 1, -1 ], [ 2, 4, -3 ], [ 3, -2 ], [ -4 ]>,
  <bipartition: [ 1, -3 ], [ 2, -1 ], [ 3, 4, -4 ], [ -2 ]>,
  <bipartition: [ 1, -3 ], [ 2, -2 ], [ 3, -1 ], [ 4, -4 ]>,
  <bipartition: [ 1, -3 ], [ 2, -4 ], [ 3, -1, -2 ], [ 4 ]>,
  <bipartition: [ 1, -2, -3 ], [ 2, -4 ], [ 3 ], [ 4, -1 ]>,
  <bipartition: [ 1, -2, -4 ], [ 2 ], [ 3, -3 ], [ 4, -1 ]> ]]]></Log>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RZMSDigraph">
<ManSection>
  <Attr Name="RZMSDigraph" Arg="R"/>
  <Returns>A digraph.</Returns>
  <Description>
    If <A>R</A> is an <M>n</M> by <M>m</M> Rees 0-matrix semigroup <M>M^{0}[I,
      T, \Lambda; P]</M> (so that <M>I = \{1,2,\ldots,n\}</M> and <M>\Lambda =
      \{1,2,\ldots,m\}</M>) then <C>RZMSDigraph</C> returns a symmetric
    bipartite digraph with <M>n+m</M> vertices.  An index <M>i \in I</M>
    corresponds to the vertex <M>i</M> and an index <M>j \in \Lambda</M>
    corresponds to the vertex <M>j + n</M>.

    <P/>

    Two vertices <M>v</M> and <M>w</M> in
    <C>RZMSDigraph(</C><A>R</A><C>)</C> are adjacent if and only if <M>v\in
      I</M>, <M>w - n\in \Lambda</M>, and <C>P[w - n][v]</C> <M>\neq 0</M>.
    <P/>

    This digraph is commonly called the <E>Graham-Houghton graph</E> of
    <A>R</A>.
<Example><![CDATA[
gap> R := PrincipalFactor(
> DClass(FullTransformationMonoid(5),
>        Transformation([2, 4, 1, 5, 5])));
<Rees 0-matrix semigroup 10x5 over Group([ (1,2,3,4), (1,2) ])>
gap> gr := RZMSDigraph(R);
<immutable bipartite digraph with bicomponent sizes 10 and 5>
gap> e := DigraphEdges(gr)[1];
[ 1, 11 ]
gap> Matrix(R)[e[2] - 10][e[1]] <> 0;
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RZMSConnectedComponents">
<ManSection>
  <Attr Name="RZMSConnectedComponents" Arg="R"/>
  <Returns>The connected components of a Rees 0-matrix semigroup.</Returns>
  <Description>
    If <A>R</A> is an <M>n</M> by <M>m</M> Rees 0-matrix semigroup <M>M^{0}[I,
      T, \Lambda; P]</M> (so that <M>I = \{1,2,\ldots,n\}</M> and <M>\Lambda =
      \{1,2,\ldots,m\}</M>) then <C>RZMSConnectedComponents</C> returns the
    connected components of <A>R</A>.

    <P/>

    <E>Connectedness</E> is an equivalence relation on the indices of
    <A>R</A>: the equivalence classes of the relation are called the
    <E>connected components</E> of <A>R</A>, and two indices in <M>I \cup
      \Lambda</M> are connected if and only if their corresponding vertices in
    <C>RZMSDigraph(</C><A>R</A><C>)</C> are connected (see <Ref
      Attr="RZMSDigraph"/>).
    If <A>R</A> has <M>n</M> connected components, then
    <C>RZMSConnectedComponents</C> will return a list of pairs:

    <P/>

    <C>[ [ </C><M>I_{1}, \Lambda_{1}</M><C> ], </C><M>\ldots</M><C>, [
    </C><M>I_{k}, \Lambda_{k}</M><C> ] ]</C>

    <P/>

    where <M>I = I_1 \sqcup \cdots \sqcup I_k</M>, <M>\Lambda = \Lambda_1
      \sqcup \cdots \sqcup \Lambda_k</M>, and for each <M>l</M> the set
    <M>I_{l}\cup\Lambda_{l}</M> is a connected component of <A>R</A>. Note that
    at most one of <M>I_l</M> and <M>\Lambda_l</M> is possibly empty.  The
    ordering of the connected components in the result in unspecified.
<Example><![CDATA[
gap> R := ReesZeroMatrixSemigroup(SymmetricGroup(5),
> [[(), 0, (1, 3), (4, 5), 0],
>  [0, (), 0, 0, (1, 3, 4, 5)],
>  [0, 0, (1, 5)(2, 3), 0, 0],
>  [0, (2, 3)(1, 4), 0, 0, 0]]);
<Rees 0-matrix semigroup 5x4 over Sym( [ 1 .. 5 ] )>
gap> RZMSConnectedComponents(R);
[ [ [ 1, 3, 4 ], [ 1, 3 ] ], [ [ 2, 5 ], [ 2, 4 ] ] ]]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RZMSNormalization">
<ManSection>
  <Attr Name="RZMSNormalization" Arg="R"/>
  <Returns>An isomorphism.</Returns>
  <Description>
    If <A>R</A> is a Rees 0-matrix semigroup <M>M^{0}[I, T, \Lambda; P]</M> then
    <C>RZMSNormalization</C> returns an isomorphism from <A>R</A> to a
    <E>normalized</E> Rees 0-matrix semigroup <M>S = M^{0}[I, T, \Lambda;
      Q]</M>. The structure matrix <M>Q</M> is obtained by <E>normalizing</E>
    the matrix <M>P</M> (see <Ref Attr="Matrix" BookName="ref"/>) and has the
    following properties:
    <List>
      <Item>
        The matrix <M>Q</M> is in block diagonal form, and the blocks are
        ordered by decreasing size along the leading diagonal (the size of
        a block is defined to be the number of rows it contains multiplied by
        the number of columns it contains). <P/>

        If the index sets <M>I</M> and <M>\Lambda</M> are partitioned into
        <M>k</M> parts according to the <Ref Attr="RZMSConnectedComponents"/> of
        <M>S</M>, giving a disjoint union <M>I=I_1\cup\ldots\cup I_k</M> and
        <M>\Lambda=\Lambda_1\cup\ldots\cup\Lambda_k</M>, then the <M>r</M>th
        block corresponds to the sub-matrix <M>Q_{r}</M> of <M>Q</M> defined by
        <M>I_{r}</M> and <M>\Lambda_{r}</M>.
      </Item>
      <Item>
        The first non-zero entry in a row occurs no sooner than
        the first non-zero entry in any previous row.
      </Item>
      <Item>
        The first non-zero entry in a column occurs no sooner than
        the first non-zero entry in any previous column.
      </Item>
      <Item>
        The previous two items imply that if the matrix <M>P</M> has any
        rows/columns consisting entirely of zeroes, then these will become the
        final rows/columns of <M>Q</M>.
      </Item>
    </List>

    Furthermore, if <M>T</M> is a group (i.e. a semigroup for which <Ref
      Prop="IsGroupAsSemigroup"/> returns <K>true</K>), then the non-zero
    entries of the structure matrix <M>Q</M> are chosen such that the following
    hold:

    <List>
      <Item>
        The first non-zero entry of every row and every column is equal to the
        identity of <M>T</M>.
      </Item>
      <Item>
        For each <M>r</M>, let <M>Q_{r}</M> be the sub-matrix of <M>Q</M>
        defined by <M>I_r</M> and <M>\Lambda_r</M> (as above), and let
        <M>T_r</M> be the subsemigroup of <M>T</M> generated by the non-zero
        entries of <M>Q_{r}</M>.  Then the idempotent generated subsemigroup of
        <M>S</M> is equal to:

        <List>
          <Item>
            <M>\bigcup_{r=1}^{k} M^{0}[I_r, T_r, \Lambda_r, Q_r]</M>, where the
            zeroes of these Rees 0-matrix semigroups are all identified with the
            zero of <M>S</M>.
          </Item>
        </List>
      </Item>
    </List>

    The normalization given by <C>RZMSNormalization</C> is based on Theorem 2
    of <Cite Key = "Graham1968Graph" /> and is sometimes called <E>Graham normal
      form</E>.  Note that isomorphic Rees 0-matrix semigroups can have
    normalizations which are not equal.<P/>
<Example><![CDATA[
gap> R := ReesZeroMatrixSemigroup(Group(()),
> [[0, (), 0],
>  [(), 0, 0],
>  [0, 0, ()]]);
<Rees 0-matrix semigroup 3x3 over Group(())>
gap> iso := RZMSNormalization(R);
<Rees 0-matrix semigroup 3x3 over Group(())> ->
<Rees 0-matrix semigroup 3x3 over Group(())>
gap> S := Range(iso);
<Rees 0-matrix semigroup 3x3 over Group(())>
gap> Matrix(S);
[ [ (), 0, 0 ], [ 0, (), 0 ], [ 0, 0, () ] ]
gap> R := ReesZeroMatrixSemigroup(SymmetricGroup(4),
> [[0, 0, 0, (1, 3, 2)],
>  [(2, 3), 0, 0, 0],
>  [0, 0, (1, 3), (1, 2)],
>  [0, (4, 1, 2, 3), 0, 0]]);
<Rees 0-matrix semigroup 4x4 over Sym( [ 1 .. 4 ] )>
gap> S := Range(RZMSNormalization(R));
<Rees 0-matrix semigroup 4x4 over Sym( [ 1 .. 4 ] )>
gap> Matrix(S);
[ [ (), (), 0, 0 ], [ 0, (), 0, 0 ], [ 0, 0, (), 0 ], [ 0, 0, 0, () ]
 ]]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RMSNormalization">
<ManSection>
  <Attr Name="RMSNormalization" Arg="R"/>
  <Returns>An isomorphism.</Returns>
  <Description>
    If <A>R</A> is a Rees matrix semigroup over a group <C>G</C> (i.e. a
    semigroup for which <Ref Prop="IsGroupAsSemigroup"/> returns <K>true</K>),
    then <C>RMSNormalization</C> returns an isomorphism from <A>R</A> to a
    <E>normalized</E> Rees matrix semigroup <C>S</C> over <C>G</C>. <P/>

    The semigroup <C>S</C> is normalized in the sense that the first entry of
    each row and column of the <Ref Attr="Matrix" BookName="ref"/> of <C>S</C>
    is the identity element of <C>G</C>.
<Example><![CDATA[
gap> R := ReesMatrixSemigroup(SymmetricGroup(4),
> [[(1, 2), (2, 4, 3), (2, 1, 4)],
>  [(1, 3, 2), (1, 2)(3, 4), ()],
>  [(2, 3), (1, 3, 2, 4), (2, 3)]]);
<Rees matrix semigroup 3x3 over Sym( [ 1 .. 4 ] )>
gap> iso := RMSNormalization(R);
<Rees matrix semigroup 3x3 over Sym( [ 1 .. 4 ] )> ->
<Rees matrix semigroup 3x3 over Sym( [ 1 .. 4 ] )>
gap> S := Range(iso);
<Rees matrix semigroup 3x3 over Sym( [ 1 .. 4 ] )>
gap> Matrix(S);
[ [ (), (), () ], [ (), (1,2), (1,4,2,3) ], [ (), (1,4,2,3), (2,4) ] ]]]>
</Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="UnderlyingSemigroupOfSemigroupWithAdjoinedZero">
  <ManSection>
    <Attr Name="UnderlyingSemigroupOfSemigroupWithAdjoinedZero" Arg="S"/>
    <Returns>
      A semigroup, or <K>fail</K>.
    </Returns>
    <Description>
      If <A>S</A> is a semigroup for which the property <Ref
        Prop="IsSemigroupWithAdjoinedZero"/> is true, (i.e. <A>S</A> has a
      <Ref Attr="MultiplicativeZero"/> and the set <M><A>S</A> \setminus \{ 0
        \}</M> is a subsemigroup of <A>S</A>), then this method returns the
      semigroup <M><A>S</A> \setminus \{ 0 \}</M>. <P/>

      Otherwise, if <A>S</A> is a semigroup for which the property <Ref
        Prop="IsSemigroupWithAdjoinedZero"/> is <K>false</K>, then this method
      returns <K>fail</K>.

      <Example><![CDATA[
gap> S := Semigroup([
> Transformation([2, 3, 4, 5, 1, 6]),
> Transformation([2, 1, 3, 4, 5, 6]),
> Transformation([6, 6, 6, 6, 6, 6])]);
<transformation semigroup of degree 6 with 3 generators>
gap> MultiplicativeZero(S);
Transformation( [ 6, 6, 6, 6, 6, 6 ] )
gap> G := UnderlyingSemigroupOfSemigroupWithAdjoinedZero(S);
<transformation semigroup of degree 5 with 2 generators>
gap> IsGroupAsSemigroup(G);
true
gap> IsZeroGroup(S);
true
gap> S := SymmetricInverseMonoid(6);;
gap> MultiplicativeZero(S);
<empty partial perm>
gap> G := UnderlyingSemigroupOfSemigroupWithAdjoinedZero(S);
fail]]>
</Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="GeneratorsSmallest">
<ManSection>
  <Attr Name = "GeneratorsSmallest" Arg = "S" Label = "for a semigroup"/>
  <Returns>A set of elements.</Returns>
  <Description>
    For a semigroup <A>S</A>, <C>GeneratorsSmallest</C> returns the
    lexicographically least set of elements <C>X</C> such that <C>X</C>
    generates <A>S</A> as a semigroup, and such that <C>X</C> is
    lexicographically ordered and has the property that each <C>X[i]</C> is not
    generated by <C>X[1], X[2], ..., X[i-1]</C>. <P/>

    It can be difficult to find the set of generators <C>X</C>, and it might
    contain a substantial proportion of the elements of <A>S</A>. <P/>

    Two semigroups have the same set of elements if and only if
    their smallest generating sets are equal. However, due to the complexity of
    determining the <C>GeneratorsSmallest</C>, this is not the method used by
    the &SEMIGROUPS; package when comparing semigroups.

    <Example><![CDATA[
gap> S := Monoid([
>  Transformation([1, 3, 4, 1]),
>  Transformation([2, 4, 1, 2]),
>  Transformation([3, 1, 1, 3]),
>  Transformation([3, 3, 4, 1])]);
<transformation monoid of degree 4 with 4 generators>
gap> GeneratorsSmallest(S);
[ Transformation( [ 1, 1, 1, 1 ] ), Transformation( [ 1, 1, 1, 2 ] ),
  Transformation( [ 1, 1, 1, 3 ] ), Transformation( [ 1, 1, 1 ] ),
  Transformation( [ 1, 1, 2, 1 ] ), Transformation( [ 1, 1, 2, 2 ] ),
  Transformation( [ 1, 1, 3, 1 ] ), Transformation( [ 1, 1, 3, 3 ] ),
  Transformation( [ 1, 1 ] ), Transformation( [ 1, 1, 4, 1 ] ),
  Transformation( [ 1, 2, 1, 1 ] ), Transformation( [ 1, 2, 2, 1 ] ),
  IdentityTransformation, Transformation( [ 1, 3, 1, 1 ] ),
  Transformation( [ 1, 3, 4, 1 ] ), Transformation( [ 2, 1, 1, 2 ] ),
  Transformation( [ 2, 2, 2 ] ), Transformation( [ 2, 4, 1, 2 ] ),
  Transformation( [ 3, 3, 3 ] ), Transformation( [ 3, 3, 4, 1 ] ) ]
gap> T := Semigroup(Bipartition([[1, 2, 3], [4, -1], [-2], [-3], [-4]]),
>                   Bipartition([[1, -3, -4], [2, 3, 4, -2], [-1]]),
>                   Bipartition([[1, 2, 3, 4, -2], [-1, -4], [-3]]),
>                   Bipartition([[1, 2, 3, 4], [-1], [-2], [-3, -4]]),
>                   Bipartition([[1, 2, -1, -2], [3, 4, -3], [-4]]));
<bipartition semigroup of degree 4 with 5 generators>
gap> GeneratorsSmallest(T);
[ <bipartition: [ 1, 2, 3, 4, -1, -2, -3 ], [ -4 ]>,
  <bipartition: [ 1, 2, 3, 4, -1, -2 ], [ -3 ], [ -4 ]>,
  <bipartition: [ 1, 2, 3, 4, -1 ], [ -2 ], [ -3 ], [ -4 ]>,
  <bipartition: [ 1, 2, 3, 4, -2, -3, -4 ], [ -1 ]>,
  <bipartition: [ 1, 2, 3, 4, -2 ], [ -1, -4 ], [ -3 ]>,
  <bipartition: [ 1, 2, 3, 4, -2 ], [ -1 ], [ -3, -4 ]>,
  <bipartition: [ 1, 2, 3, 4, -3 ], [ -1, -2 ], [ -4 ]>,
  <bipartition: [ 1, 2, 3, 4 ], [ -1, -2, -3 ], [ -4 ]>,
  <bipartition: [ 1, 2, 3, 4, -3, -4 ], [ -1 ], [ -2 ]>,
  <bipartition: [ 1, 2, 3 ], [ 4, -1, -2, -3 ], [ -4 ]>,
  <bipartition: [ 1, 2, -1, -2 ], [ 3, 4, -3 ], [ -4 ]>,
  <bipartition: [ 1, -3 ], [ 2, 3, 4, -1, -2 ], [ -4 ]>,
  <bipartition: [ 1, -3, -4 ], [ 2, 3, 4, -2 ], [ -1 ]> ]]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="OneInverseOfSemigroupElement">
<ManSection>
  <Attr Name="OneInverseOfSemigroupElement" Arg="S, x"/>
  <Returns> One inverse of an element of a semigroup.</Returns>
  <Description>
    <C>OneInverseOfSemigroupElement</C> returns one inverse of the element
    <C>x</C> in the semigroup <A>S</A> and returns fail if this
    element has no inverse in <A>S</A>.
    <A>x</A> in the semigroup <A>S</A>.
  <Example><![CDATA[
gap> S := FullTransformationMonoid(4);
<full transformation monoid of degree 4>
gap> s := Transformation([2, 3, 1, 1]);
Transformation( [ 2, 3, 1, 1 ] )
gap> OneInverseOfSemigroupElement(S, s);
Transformation( [ 3, 1, 2, 2 ] )
gap> e := IdentityTransformation;
IdentityTransformation
gap> OneInverseOfSemigroupElement(S, e);
IdentityTransformation
gap> F := FreeSemigroup(1);
<free semigroup on the generators [ s1 ]>
gap> OneInverseOfSemigroupElement(F, F.1);
Error, the semigroup is not finite]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IndecomposableElements">
<ManSection>
  <Attr Name="IndecomposableElements" Arg="S"/>
  <Returns>A list of elements.</Returns>
  <Description>
    If <A>S</A> is a semigroup, then this attribute returns the set of elements
    of <A>S</A> that are not decomposable. A element of <A>S</A> is
    <E>decomposable</E> if it can be written as the product of two elements in
    <A>S</A>. An element of <A>S</A> is <E>indecomposable</E> if it is not
    decomposable. <P/>

    See also <Ref Prop="IsSurjectiveSemigroup" />. <P/>

    Note that any generating set for <A>S</A> contains each indecomposable
    element of <A>S</A>. Thus <C>IndecomposableElements(<A>S</A>)</C> is a
    subset of <C>GeneratorsOfSemigroup(<A>S</A>)</C>. <P/>

<Example><![CDATA[
gap> S := Semigroup([
> Transformation([1, 1, 2, 3]),
> Transformation([1, 1, 1, 2])]);
<transformation semigroup of degree 4 with 2 generators>
gap> x := IndecomposableElements(S);
[ Transformation( [ 1, 1, 2, 3 ] ) ]
gap> IsSubset(GeneratorsOfSemigroup(S), x);
true
gap> T := FullTransformationMonoid(10);
<full transformation monoid of degree 10>
gap> IndecomposableElements(T);
[  ]
gap> B := ZeroSemigroup(IsBipartitionSemigroup, 3);
<commutative non-regular bipartition semigroup of size 3, degree 4
 with 2 generators>
gap> IndecomposableElements(B);
[ <bipartition: [ 1, 2, 3, -1 ], [ 4, -2 ], [ -3 ], [ -4 ]>,
  <bipartition: [ 1, 2, 4, -1 ], [ 3, -2 ], [ -3 ], [ -4 ]> ]]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="NambooripadLeqRegularSemigroup">
<ManSection>
<Attr Name="NambooripadLeqRegularSemigroup" Arg="S"/>
  <Returns>
    A function.
  </Returns>
  <Description>
    <C>NambooripadLeqRegularSemigroup</C> returns a function that, when given
    two elements <C>x, y</C> of the regular semigroup <A>S</A>, returns
    <K>true</K> if <C>x</C> is less than or equal to <C>y</C> in the Nambooripad
    partial order on <A>S</A>. See also <Ref Func="NambooripadPartialOrder"/>.
<Example><![CDATA[
gap> S := BrauerMonoid(3);
<regular bipartition *-monoid of degree 3 with 3 generators>
gap> IsRegularSemigroup(S);
true
gap> Size(S);
15
gap> NambooripadPartialOrder(S);
[ [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ],
  [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
  [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
  [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ]
gap> NambooripadLeqRegularSemigroup(S)(Elements(S)[3], Elements(S)[9]);
false
gap> NambooripadLeqRegularSemigroup(S)(Elements(S)[2], Elements(S)[15]);
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="NambooripadPartialOrder">
<ManSection>
<Attr Name="NambooripadPartialOrder" Arg="S"/>
  <Returns>The Nambooripad partial order on a regular semigroup.</Returns>
  <Description>
    The <E>Nambooripad partial order</E> <M>\leq</M> on a regular semigroup
    <A>S</A> is defined by <C>s</C><M>\leq</M><C>t</C> if the principal right
    ideal of <C>S</C> generated by <C>s</C> is contained in the principal right
    ideal of <C>S</C> generated by <C>t</C> and there is an idempotent <C>e</C>
    in the &R;-class of <C>s</C> such that <C>s</C><M>=</M><C>et</C>. The
    Nambooripad partial order coincides with the natural partial order when
    considering inverse semigroups
    <Ref Attr="NaturalPartialOrder" BookName="ref" />.<P/>

    <C>NambooripadPartialOrder</C> returns the Nambooripad partial order on the
    regular semigroup <A>S</A> as a list of sets of positive integers where
    entry <C>i</C> in <C>NambooripadPartialOrder(<A>S</A>)</C> is the set of
    positions in <C>Elements(<A>S</A>)</C> of elements which are less than
    <C>Elements(<A>S</A>)[i]</C>. See also <Ref
      Func="NambooripadLeqRegularSemigroup"/>.

    <Example><![CDATA[
gap> S := BrauerMonoid(3);
<regular bipartition *-monoid of degree 3 with 3 generators>
gap> IsRegularSemigroup(S);
true
gap> Size(S);
15
gap> NambooripadPartialOrder(S);
[ [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ],
  [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
  [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
  [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ]
gap> NambooripadLeqRegularSemigroup(S)(Elements(S)[3], Elements(S)[9]);
false
gap> NambooripadLeqRegularSemigroup(S)(Elements(S)[2], Elements(S)[15]);
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="SmallerDegreeTransformationRepresentation">
<ManSection>
<Attr Name="SmallerDegreeTransformationRepresentation" Arg="S"/>
  <Returns>An isomorphism to a transformation semigroup.</Returns>
  <Description>
    This function attempts to find a small degree transformation representation
    of the semigroup <A>S</A>. The implementation attempts to find a right
    congruence of <A>S</A> that <A>S</A> acts on (the equivalence classes of)
    faithfully. <P/>

    If <A>S</A> is not a finitely presented semigroup, then the returned
    isomorphism is the composition of an isomorphism to a finitely presented
    semigroup and an isomorphism from that finitely presented semigroup to a
    transformation semigroup. <P/>

    The runtime of this function depends on the presentation for <A>S</A>
    that is either given explicitly or computed by the &SEMIGROUPS; package,
    but it is difficult to predict what properties of the presentation lead to
    a shorter runtime. This is unlikely to terminate in a reasonable amount of
    time for semigroups with more than approx. <C>10000</C> elements, but might
    also not terminate quickly for smaller semigroups depending on the
    presentation used.

    <Example><![CDATA[
gap> S := BrauerMonoid(3);
<regular bipartition *-monoid of degree 3 with 3 generators>
gap> IsomorphismTransformationSemigroup(S);
<regular bipartition *-monoid of size 15, degree 3 with 3 generators>
-> <transformation monoid of size 15, degree 15 with 3 generators>
gap> SmallerDegreeTransformationRepresentation(S);
CompositionMapping(
<fp semigroup with 4 generators and 20 relations of length 81> ->
<transformation monoid of degree 7 with 3 generators>,
<regular bipartition *-monoid of size 15, degree 3 with 3 generators>
-> <fp semigroup with 4 generators and 20 relations of length 81> )
gap> S := JonesMonoid(5);
<regular bipartition *-monoid of degree 5 with 4 generators>
gap> Size(S);
42
gap> SmallerDegreeTransformationRepresentation(S);
CompositionMapping(
<fp semigroup with 5 generators and 28 relations of length 120> ->
<transformation monoid of degree 10 with 4 generators>,
<regular bipartition *-monoid of size 42, degree 5 with 4 generators>
-> <fp semigroup with 5 generators and 28 relations of length 120> )
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="MinimalFaithfulTransformationDegree">
<ManSection>
<Attr Name="MinimalFaithfulTransformationDegree" Arg="S"/>
  <Returns>A positive integer.</Returns>
  <Description>
    This function returns the minimal degree of a faithful transformation
    representation of the semigroup <A>S</A>. This is currently only
    implemented for a very small number of types of semigroups. <P/>

    <!-- See also <Ref Attr="MinimalFaithfulTransformationRepresentation"/>. -->

    <Example><![CDATA[
gap> S := RightZeroSemigroup(10);
<transformation semigroup of degree 7 with 10 generators>
gap> MinimalFaithfulTransformationDegree(S);
7
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

# The following documentation is included but there are actually no
# implementations for this as of yet, and so we don't link this into the
# documentation.

<#GAPDoc Label="MinimalFaithfulTransformationRepresentation">
<ManSection>
<Attr Name="MinimalFaithfulTransformationRepresentation" Arg="S"/>
  <Returns>An isomorphism to a transformation semigroup.</Returns>
  <Description>
    This function returns an isomorphism to a transformation semigroup of
    minimal degree that is isomorphic to <A>S</A>. This is currently only
    implemented for a very small number of types of semigroups. <P/>

    See also <Ref Attr="MinimalFaithfulTransformationRepresentation"/>.

    <Example><![CDATA[
gap> S := RightZeroSemigroup(10);
gap> MinimalFaithfulTransformationRepresentation(S);
7
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>
