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

<#GAPDoc Label="IsGreensClassNC">
  <ManSection>
    <Prop Name="IsGreensClassNC" Arg="class"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A Green's class <A>class</A> of a semigroup <C>S</C> satisfies
      <C>IsGreensClassNC</C> if it was not known to &GAP; that the
      representative of <A>class</A> was an element of <C>S</C> at the point
      that <A>class</A> was created.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="MultiplicativeNeutralElement">
  <ManSection>
    <Meth Name = "MultiplicativeNeutralElement" Arg = "H" Label = "for an H-class"/>
    <Returns>A semigroup element or <K>fail</K>.</Returns>
    <Description>
      If the &H;-class <A>H</A> of a semigroup <C>S</C> is a subgroup of
      <C>S</C>, then <C>MultiplicativeNeutralElement</C> returns the identity of
      <A>H</A>. If <A>H</A> is not a subgroup of <C>S</C>, then <K>fail</K> is
      returned.
      <Example><![CDATA[
gap> S := Semigroup([PartialPerm([1, 5, 2]),
>  PartialPerm([2, 0, 4]), PartialPerm([4, 1, 5]),
>  PartialPerm([1, 0, 3, 0, 4]), PartialPerm([1, 2, 0, 3, 5]),
>  PartialPerm([1, 3, 2, 0, 5]), PartialPerm([5, 0, 0, 4, 3])]);;
gap> H := HClass(S, PartialPerm([1, 2]));;
gap> MultiplicativeNeutralElement(H);
<identity partial perm on [ 1, 2 ]>
gap> H := HClass(S, PartialPerm([1, 4]));;
gap> MultiplicativeNeutralElement(H);
fail]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="\&lt;">
  <ManSection><Heading>Less than for Green's classes</Heading>
    <Meth Name = "\&lt;" Arg = 'left-expr, right-expr' Label = "for Green's classes"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      The Green's class <A>left-expr</A> is less than or equal to
      <A>right-expr</A> if they belong to the same
      semigroup and the representative of <A>left-expr</A> is less than the
      representative of <A>right-expr</A> under <C>&lt;</C>; see also
      <Ref Attr="Representative" BookName="ref"/>.
      <P/>

      Please note that this is not the usual order on the Green's classes of a
      semigroup as defined in <Ref Sect="Green's Relations" BookName="ref"/>.
      See also <Ref Oper="IsGreensLessThanOrEqual" BookName="ref"/>.

      <Example><![CDATA[
gap> S := FullTransformationSemigroup(4);;
gap> A := GreensRClassOfElement(S, Transformation([2, 1, 3, 1]));
<Green's R-class: Transformation( [ 2, 1, 3, 1 ] )>
gap> B := GreensRClassOfElement(S, Transformation([1, 2, 3, 4]));
<Green's R-class: IdentityTransformation>
gap> A < B;
false
gap> B < A;
true
gap> IsGreensLessThanOrEqual(A, B);
true
gap> IsGreensLessThanOrEqual(B, A);
false
gap> S := SymmetricInverseSemigroup(4);;
gap> A := GreensJClassOfElement(S, PartialPerm([1, 3, 4]));;
gap> B := GreensJClassOfElement(S, PartialPerm([3, 1]));;
gap> A < B;
true
gap> B < A;
false
gap> IsGreensLessThanOrEqual(A, B);
false
gap> IsGreensLessThanOrEqual(B, A);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="XClassOfYClass">
  <ManSection><Heading>XClassOfYClass</Heading>
    <Meth Name = "DClassOfHClass" Arg = "class"/>
    <Meth Name = "DClassOfLClass" Arg = "class"/>
    <Meth Name = "DClassOfRClass" Arg = "class"/>
    <Meth Name = "LClassOfHClass" Arg = "class"/>
    <Meth Name = "RClassOfHClass" Arg = "class"/>
    <Returns>A Green's class.</Returns>
    <Description>
     <C>XClassOfYClass</C> returns the <C>X</C>-class containing the
     <C>Y</C>-class <A>class</A> where <C>X</C> and <C>Y</C> should be replaced
     by an appropriate choice of <C>D, H, L,</C> and <C>R</C>.<P/>

      Note that if it is not known to &GAP; whether or not the representative
      of <A>class</A> is an element of the semigroup containing <A>class</A>,
      then no attempt is made to check this.<P/>

      The same result can be produced using:
      <Log>First(GreensXClasses(S), x -> Representative(x) in class);</Log>
      but this might be substantially slower. Note that <C>XClassOfYClass</C>
      is also likely to be faster than
      <Log>GreensXClassOfElement(S, Representative(class));</Log>
      <P/>

      <C>DClass</C> can also be used as a synonym for <C>DClassOfHClass</C>,
      <C>DClassOfLClass</C>, and <C>DClassOfRClass</C>;
      <C>LClass</C> as a synonym for <C>LClassOfHClass</C>; and
      <C>RClass</C> as a synonym for <C>RClassOfHClass</C>.

      See also <Ref Oper = "GreensDClassOfElement" BookName = "ref"/>
      and <Ref Oper = "GreensDClassOfElementNC"/>.
      <Example><![CDATA[
gap> S := Semigroup(Transformation([1, 3, 2]),
>                   Transformation([2, 1, 3]),
>                   Transformation([3, 2, 1]),
>                   Transformation([1, 3, 1]));;
gap> R := GreensRClassOfElement(S, Transformation([3, 2, 1]));
<Green's R-class: Transformation( [ 3, 2, 1 ] )>
gap> DClassOfRClass(R);
<Green's D-class: Transformation( [ 3, 2, 1 ] )>
gap> IsGreensDClass(DClassOfRClass(R));
true
gap> S := InverseSemigroup(
> PartialPerm([2, 6, 7, 0, 0, 9, 0, 1, 0, 5]),
> PartialPerm([3, 8, 1, 9, 0, 4, 10, 5, 0, 6]));
<inverse partial perm semigroup of rank 10 with 2 generators>
gap> x := S.1;
[3,7][8,1,2,6,9][10,5]
gap> H := HClass(S, x);
<Green's H-class: [3,7][8,1,2,6,9][10,5]>
gap> R := RClassOfHClass(H);
<Green's R-class: [3,7][8,1,2,6,9][10,5]>
gap> L := LClass(H);;
gap> L = LClass(S, PartialPerm([1, 2, 0, 0, 5, 6, 7, 0, 9]));
true
gap> DClass(R) = DClass(L);
true
gap> DClass(H) = DClass(L);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="GreensXClasses">
  <ManSection Label="GreensXClasses"><Heading>GreensXClasses</Heading>
    <Meth Name = "GreensDClasses" Arg = "obj"/>
    <Meth Name = "DClasses" Arg = "obj"/>
    <Meth Name = "GreensHClasses" Arg = "obj"/>
    <Meth Name = "HClasses" Arg = "obj"/>
    <Meth Name = "GreensJClasses" Arg = "obj"/>
    <Meth Name = "JClasses" Arg = "obj"/>
    <Meth Name = "GreensLClasses" Arg = "obj"/>
    <Meth Name = "LClasses" Arg = "obj"/>
    <Meth Name = "GreensRClasses" Arg = "obj"/>
    <Meth Name = "RClasses" Arg = "obj"/>
    <Returns>A list of Green's classes.
    </Returns>
    <Description>
      These functions produce essentially the same output as the &GAP; library
      functions with the same names; see <Ref Meth = "GreensDClasses"
        BookName = "ref"/>. The main difference is that these functions can be
      applied to a wider class of objects:
      <List>
      <Mark><C>GreensDClasses</C> and <C>DClasses</C></Mark>
      <Item>
        <A>X</A> should be a semigroup.
      </Item>

      <Mark><C>GreensHClasses</C> and <C>HClasses</C></Mark>
      <Item>
        <A>X</A> can be a semigroup, &R;-class, &L;-class, or &D;-class.
      </Item>

      <Mark><C>GreensLClasses</C> and <C>LClasses</C></Mark>
      <Item>
        <A>X</A> can be a semigroup or &D;-class.
      </Item>

      <Mark><C>GreensRClasses</C> and <C>RClasses</C></Mark>
      <Item>
        <A>X</A> can be a semigroup or &D;-class.
      </Item>
      </List>

      Note that <C>GreensXClasses</C> and <C>XClasses</C> are synonyms and have
      identical output. The shorter command is provided for the sake of
      convenience.<P/>

      See also <Ref Attr = "DClassReps"/>, <Ref Oper = "IteratorOfDClassReps"/>,
      <Ref Oper = "IteratorOfDClasses"/>, and <Ref Attr = "NrDClasses"/>.
      <Example><![CDATA[
gap> S := Semigroup(Transformation([3, 4, 4, 4]),
>                   Transformation([4, 3, 1, 2]));;
gap> GreensDClasses(S);
[ <Green's D-class: Transformation( [ 3, 4, 4, 4 ] )>,
  <Green's D-class: Transformation( [ 4, 3, 1, 2 ] )>,
  <Green's D-class: Transformation( [ 4, 4, 4, 4 ] )> ]
gap> GreensRClasses(S);
[ <Green's R-class: Transformation( [ 3, 4, 4, 4 ] )>,
  <Green's R-class: Transformation( [ 4, 3, 1, 2 ] )>,
  <Green's R-class: Transformation( [ 4, 4, 4, 4 ] )>,
  <Green's R-class: Transformation( [ 4, 4, 3, 4 ] )>,
  <Green's R-class: Transformation( [ 4, 3, 4, 4 ] )>,
  <Green's R-class: Transformation( [ 4, 4, 4, 3 ] )> ]
gap> D := GreensDClasses(S)[1];
<Green's D-class: Transformation( [ 3, 4, 4, 4 ] )>
gap> GreensLClasses(D);
[ <Green's L-class: Transformation( [ 3, 4, 4, 4 ] )>,
  <Green's L-class: Transformation( [ 1, 2, 2, 2 ] )> ]
gap> GreensRClasses(D);
[ <Green's R-class: Transformation( [ 3, 4, 4, 4 ] )>,
  <Green's R-class: Transformation( [ 4, 4, 3, 4 ] )>,
  <Green's R-class: Transformation( [ 4, 3, 4, 4 ] )>,
  <Green's R-class: Transformation( [ 4, 4, 4, 3 ] )> ]
gap> R := GreensRClasses(D)[1];
<Green's R-class: Transformation( [ 3, 4, 4, 4 ] )>
gap> GreensHClasses(R);
[ <Green's H-class: Transformation( [ 3, 4, 4, 4 ] )>,
  <Green's H-class: Transformation( [ 1, 2, 2, 2 ] )> ]
gap> S := InverseSemigroup([
> PartialPerm([2, 4, 1]), PartialPerm([3, 0, 4, 1])]);;
gap> GreensDClasses(S);
[ <Green's D-class: <identity partial perm on [ 1, 2, 4 ]>>,
  <Green's D-class: <identity partial perm on [ 1, 3, 4 ]>>,
  <Green's D-class: <identity partial perm on [ 1, 3 ]>>,
  <Green's D-class: <identity partial perm on [ 4 ]>>,
  <Green's D-class: <empty partial perm>> ]
gap> GreensLClasses(S);
[ <Green's L-class: <identity partial perm on [ 1, 2, 4 ]>>,
  <Green's L-class: [4,2,1,3]>,
  <Green's L-class: <identity partial perm on [ 1, 3, 4 ]>>,
  <Green's L-class: <identity partial perm on [ 1, 3 ]>>,
  <Green's L-class: [3,1,2]>, <Green's L-class: [1,4][3,2]>,
  <Green's L-class: [1,3,4]>, <Green's L-class: [3,1,4]>,
  <Green's L-class: [1,2](3)>,
  <Green's L-class: <identity partial perm on [ 4 ]>>,
  <Green's L-class: [4,1]>, <Green's L-class: [4,3]>,
  <Green's L-class: [4,2]>, <Green's L-class: <empty partial perm>> ]
gap> D := GreensDClasses(S)[3];
<Green's D-class: <identity partial perm on [ 1, 3 ]>>
gap> GreensLClasses(D);
[ <Green's L-class: <identity partial perm on [ 1, 3 ]>>,
  <Green's L-class: [3,1,2]>, <Green's L-class: [1,4][3,2]>,
  <Green's L-class: [1,3,4]>, <Green's L-class: [3,1,4]>,
  <Green's L-class: [1,2](3)> ]
gap> GreensRClasses(D);
[ <Green's R-class: <identity partial perm on [ 1, 3 ]>>,
  <Green's R-class: [2,1,3]>, <Green's R-class: [2,3][4,1]>,
  <Green's R-class: [4,3,1]>, <Green's R-class: [4,1,3]>,
  <Green's R-class: [2,1](3)> ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="GreensXClassOfElement">
  <ManSection><Heading>GreensXClassOfElement</Heading>
    <Oper Name = "GreensDClassOfElement" Arg = "X, f"/>
    <Oper Name = "DClass" Arg = "X, f"/>
    <Oper Name = "GreensHClassOfElement" Arg = "X, f"/>
    <Oper Name = "GreensHClassOfElement" Arg = "R, i, j"
      Label = "for a Rees matrix semigroup"/>
    <Oper Name = "HClass" Arg = "X, f"/>
    <Oper Name = "HClass" Arg = "R, i, j" Label = "for a Rees matrix semigroup"/>
    <Oper Name = "GreensLClassOfElement" Arg = "X, f"/>
    <Oper Name = "LClass" Arg = "X, f"/>
    <Oper Name = "GreensRClassOfElement" Arg = "X, f"/>
    <Oper Name = "RClass" Arg = "X, f"/>
    <Returns>A Green's class.</Returns>
    <Description>
      These functions produce essentially the same output as the &GAP; library
      functions with the same names; see <Ref Oper = "GreensDClassOfElement"
      BookName = "ref"/>.  The main difference is that these functions can be
      applied to a wider class of objects:
      <List>
      <Mark><C>GreensDClassOfElement</C> and <C>DClass</C></Mark>
      <Item>
        <A>X</A> must be a semigroup.
      </Item>

      <Mark><C>GreensHClassOfElement</C> and <C>HClass</C></Mark>
      <Item>
        <A>X</A> can be a semigroup, &R;-class, &L;-class, or &D;-class.
      </Item>
      <Item>
        If <A>R</A> is a <A>IxJ</A> Rees matrix semigroup or a Rees 0-matrix
        semigroup, and <A>i</A> and <A>j</A> are integers of the corresponding
        index sets, then <C>GreensHClassOfElement</C> returns the &H;-class in
        row <A>i</A> and column <A>j</A>.
      </Item>

      <Mark><C>GreensLClassOfElement</C> and <C>LClass</C></Mark>
      <Item>
        <A>X</A> can be a semigroup or &D;-class.
      </Item>

      <Mark><C>GreensRClassOfElement</C> and <C>RClass</C></Mark>
      <Item>
        <A>X</A> can be a semigroup or &D;-class.
      </Item>
      </List>

      Note that <C>GreensXClassOfElement</C> and <C>XClass</C> are synonyms and
      have identical output. The shorter command is provided for the sake of
      convenience.<P/>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="GreensXClassOfElementNC">
  <ManSection><Heading>GreensXClassOfElementNC</Heading>
    <Oper Name = "GreensDClassOfElementNC" Arg = "X, f"/>
    <Oper Name = "DClassNC" Arg = "X, f"/>
    <Oper Name = "GreensHClassOfElementNC" Arg = "X, f"/>
    <Oper Name = "HClassNC" Arg = "X, f"/>
    <Oper Name = "GreensLClassOfElementNC" Arg = "X, f"/>
    <Oper Name = "LClassNC" Arg = "X, f"/>
    <Oper Name = "GreensRClassOfElementNC" Arg = "X, f"/>
    <Oper Name = "RClassNC" Arg = "X, f"/>
    <Returns>A Green's class.</Returns>
    <Description>
      These functions are essentially the same as <Ref
      Oper = "GreensDClassOfElement"/>  except that no effort is made to verify
      if <A>f</A> is an element of <A>X</A>.  More precisely,
      <C>GreensXClassOfElementNC</C> and <C>XClassNC</C> first check if
      <A>f</A> has already been shown to be an element of <A>X</A>.  If it is
      not known to &GAP; if <A>f</A> is an element of <A>X</A>, then no further
      attempt to verify this is made. <P/>

      Note that <C>GreensXClassOfElementNC</C> and <C>XClassNC</C> are synonyms
      and have identical output. The shorter command is provided for the sake
      of convenience. <P/>

      It can be quicker to compute the class of an element using
      <C>GreensRClassOfElementNC</C>, say, than using
      <C>GreensRClassOfElement</C>
      if it is known <E>a priori</E> that <A>f</A>
      is an element of <A>X</A>. On the other
      hand, if <A>f</A> is not an element of <A>X</A>, then the results of this
      computation are unpredictable.<P/>

      For example, if <Log>x := Transformation([15, 18, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]);</Log>
      in the semigroup <A>X</A> of order-preserving mappings on 20 points, then
      <Log>GreensRClassOfElementNC(X, x);</Log>
      returns an answer relatively quickly, whereas
      <Log>GreensRClassOfElement(X, x)</Log>
      can take a significant amount of time to return a value.<P/>

      See also <Ref Oper="GreensRClassOfElement" BookName="ref"/> and <Ref
      Meth="RClassOfHClass"/>.

      <Example><![CDATA[
gap> S := RandomSemigroup(IsTransformationSemigroup, 2, 1000);;
gap> x := [1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1];;
gap> x := EvaluateWord(Generators(S), x);;
gap> R := GreensRClassOfElementNC(S, x);;
gap> Size(R);
1
gap> L := GreensLClassOfElementNC(S, x);;
gap> Size(L);
1
gap> x := PartialPerm([2, 3, 4, 5, 0, 0, 6, 8, 10, 11]);;
gap> L := LClass(POI(11), x);
<Green's L-class: [1,2,3,4,5][7,6][9,10,11](8)>
gap> Size(L);
165]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="XClassReps">
  <ManSection><Heading>XClassReps</Heading>
    <Attr Name = "DClassReps" Arg = "obj"/>
    <Attr Name = "HClassReps" Arg = "obj"/>
    <Attr Name = "LClassReps" Arg = "obj"/>
    <Attr Name = "RClassReps" Arg = "obj"/>
    <Returns>A list of representatives.</Returns>
    <Description>
      <C>XClassReps</C> returns a list of the representatives of the Green's
      classes of <A>obj</A>, which can be a semigroup, &D;-, &L;-, or &R;-class
      where appropriate.<P/>

      The same output can be obtained by calling, for example:

      <Log>List(GreensXClasses(obj), Representative);</Log>

      Note that if the Green's classes themselves are not required, then
      <C>XClassReps</C> will return an answer more quickly than the above,
      since the Green's class objects are not created.<P/>

      See also
      <Ref Meth = "GreensDClasses"/>,
      <Ref Oper = "IteratorOfDClassReps"/>,
      <Ref Oper = "IteratorOfDClasses"/>,  and
      <Ref Attr = "NrDClasses"/>.
      <Example><![CDATA[
gap> S := Semigroup(Transformation([3, 4, 4, 4]),
>                   Transformation([4, 3, 1, 2]));;
gap> DClassReps(S);
[ Transformation( [ 3, 4, 4, 4 ] ), Transformation( [ 4, 3, 1, 2 ] ),
  Transformation( [ 4, 4, 4, 4 ] ) ]
gap> LClassReps(S);
[ Transformation( [ 3, 4, 4, 4 ] ), Transformation( [ 1, 2, 2, 2 ] ),
  Transformation( [ 4, 3, 1, 2 ] ), Transformation( [ 4, 4, 4, 4 ] ),
  Transformation( [ 2, 2, 2, 2 ] ), Transformation( [ 3, 3, 3, 3 ] ),
  Transformation( [ 1, 1, 1, 1 ] ) ]
gap> D := GreensDClasses(S)[1];
<Green's D-class: Transformation( [ 3, 4, 4, 4 ] )>
gap> LClassReps(D);
[ Transformation( [ 3, 4, 4, 4 ] ), Transformation( [ 1, 2, 2, 2 ] ) ]
gap> RClassReps(D);
[ Transformation( [ 3, 4, 4, 4 ] ), Transformation( [ 4, 4, 3, 4 ] ),
  Transformation( [ 4, 3, 4, 4 ] ), Transformation( [ 4, 4, 4, 3 ] ) ]
gap> R := GreensRClasses(D)[1];;
gap> HClassReps(R);
[ Transformation( [ 3, 4, 4, 4 ] ), Transformation( [ 1, 2, 2, 2 ] ) ]
gap> S := SymmetricInverseSemigroup(6);;
gap> e := InverseSemigroup(Idempotents(S));;
gap> M := MunnSemigroup(e);;
gap> L := LClassNC(M, PartialPerm([51, 63], [51, 47]));;
gap> HClassReps(L);
[ <identity partial perm on [ 47, 51 ]>, [27,47](51), [50,47](51),
  [64,47](51), [63,47](51), [59,47](51) ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="GroupHClass">
  <ManSection>
    <Attr Name = "GroupHClass" Arg = "class"/>
    <Returns>
      A group &H;-class of the &D;-class <A>class</A> if it is regular and
      <K>fail</K> if it is not.
    </Returns>
    <Description>
      <C>GroupHClass</C> is a synonym for
      <Ref Attr = "GroupHClassOfGreensDClass" BookName = "ref"/>. <P/>

      See also
      <Ref Prop = "IsGroupHClass" BookName = "ref"/>,
      <Ref Prop = "IsRegularDClass" BookName = "ref"/>,
      <Ref Prop = "IsRegularGreensClass"/>,
      and <Ref Prop = "IsRegularSemigroup"/>.

      <Example><![CDATA[
gap> S := Semigroup(Transformation([2, 6, 7, 2, 6, 1, 1, 5]),
>                   Transformation([3, 8, 1, 4, 5, 6, 7, 1]));;
gap> IsRegularSemigroup(S);
false
gap> iter := IteratorOfDClasses(S);;
gap> repeat D := NextIterator(iter); until IsRegularDClass(D);
gap> D;
<Green's D-class: Transformation( [ 6, 1, 1, 6, 1, 2, 2, 6 ] )>
gap> NrIdempotents(D);
12
gap> NrRClasses(D);
8
gap> NrLClasses(D);
4
gap> GroupHClass(D);
<Green's H-class: Transformation( [ 1, 2, 2, 1, 2, 6, 6, 1 ] )>
gap> GroupHClassOfGreensDClass(D);
<Green's H-class: Transformation( [ 1, 2, 2, 1, 2, 6, 6, 1 ] )>
gap> StructureDescription(GroupHClass(D));
"S3"
gap> repeat D := NextIterator(iter); until not IsRegularDClass(D);
gap> D;
<Green's D-class: Transformation( [ 7, 5, 2, 2, 6, 1, 1, 2 ] )>
gap> IsRegularDClass(D);
false
gap> GroupHClass(D);
fail
gap> S := InverseSemigroup(
> PartialPerm([2, 1, 6, 0, 3]), PartialPerm([3, 5, 2, 0, 0, 6]));;
gap> x := PartialPerm([1 .. 3], [6, 3, 1]);;
gap> First(DClasses(S), x -> not IsTrivial(GroupHClass(x)));
<Green's D-class: <identity partial perm on [ 1, 2 ]>>
gap> StructureDescription(GroupHClass(last));
"C2"]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="Idempotents">
  <ManSection>
  <Attr Name = "Idempotents" Arg = "obj[, n]"/>
  <Returns>A list of idempotents.</Returns>
  <Description>
  The argument <A>obj</A> should be a semigroup, &D;-class, &H;-class,
  &L;-class, or &R;-class.<P/>

  If the optional second argument <A>n</A> is present and <A>obj</A> is a
  semigroup, then a list of the idempotents in <A>obj</A> of rank <A>n</A> is
  returned. If you are only interested in the idempotents of a given rank, then
  the second version of the function will probably be faster. However, if the
  optional second argument is present, then nothing is stored in <A>obj</A> and
  so every time the function is called the computation must be repeated.
  <P/>

  This functions produce essentially the same output as the &GAP; library
  function with the same name; see <Ref Attr = "Idempotents" BookName =
    "ref"/>.  The main difference is that this function can be applied to a
  wider class of objects as described above.<P/>

  See also <Ref Prop = "IsRegularDClass" BookName = "ref"/>,
  <Ref Prop = "IsRegularGreensClass"/>
  <Ref Prop = "IsGroupHClass" BookName = "ref"/>,
  <Ref Attr = "NrIdempotents"/>, and
  <Ref Attr = "GroupHClass"/>.

  <Example><![CDATA[
gap> S := Semigroup(Transformation([2, 3, 4, 1]),
>                   Transformation([3, 3, 1, 1]));;
gap> Idempotents(S, 1);
[  ]
gap> AsSet(Idempotents(S, 2));
[ Transformation( [ 1, 1, 3, 3 ] ), Transformation( [ 1, 3, 3, 1 ] ),
  Transformation( [ 2, 2, 4, 4 ] ), Transformation( [ 4, 2, 2, 4 ] ) ]
gap> AsSet(Idempotents(S));
[ Transformation( [ 1, 1, 3, 3 ] ), IdentityTransformation,
  Transformation( [ 1, 3, 3, 1 ] ), Transformation( [ 2, 2, 4, 4 ] ),
  Transformation( [ 4, 2, 2, 4 ] ) ]
gap> x := Transformation([2, 2, 4, 4]);;
gap> R := GreensRClassOfElement(S, x);;
gap> Idempotents(R);
[ Transformation( [ 1, 1, 3, 3 ] ), Transformation( [ 2, 2, 4, 4 ] ) ]
gap> x := Transformation([4, 2, 2, 4]);;
gap> L := GreensLClassOfElement(S, x);;
gap> AsSet(Idempotents(L));
[ Transformation( [ 2, 2, 4, 4 ] ), Transformation( [ 4, 2, 2, 4 ] ) ]
gap> D := DClassOfLClass(L);;
gap> AsSet(Idempotents(D));
[ Transformation( [ 1, 1, 3, 3 ] ), Transformation( [ 1, 3, 3, 1 ] ),
  Transformation( [ 2, 2, 4, 4 ] ), Transformation( [ 4, 2, 2, 4 ] ) ]
gap> L := GreensLClassOfElement(S, Transformation([3, 1, 1, 3]));;
gap> AsSet(Idempotents(L));
[ Transformation( [ 1, 1, 3, 3 ] ), Transformation( [ 1, 3, 3, 1 ] ) ]
gap> H := GroupHClass(D);
<Green's H-class: Transformation( [ 1, 1, 3, 3 ] )>
gap> Idempotents(H);
[ Transformation( [ 1, 1, 3, 3 ] ) ]
gap> S := InverseSemigroup(
> PartialPerm([10, 6, 3, 4, 9, 0, 1]),
> PartialPerm([6, 10, 7, 4, 8, 2, 9, 1]));;
gap> Idempotents(S, 1);
[ <identity partial perm on [ 4 ]> ]
gap> Idempotents(S, 0);
[  ]]]></Example>
  </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsRegularGreensClass">
  <ManSection>
    <Prop Name="IsRegularGreensClass" Arg="class"/>
    <Returns>
      <K>true</K> or <K>false</K>.
    </Returns>
    <Description>
      This function returns <K>true</K> if <A>class</A> is a regular Green's
      class and <K>false</K> if it is not.
      See also <Ref Prop = "IsRegularDClass" BookName = "ref"/>,
      <Ref Prop = "IsGroupHClass" BookName = "ref"/>,
      <Ref Attr = "GroupHClassOfGreensDClass" BookName = "ref"/>,
      <Ref Attr = "GroupHClass"/>, <Ref Attr = "NrIdempotents"/>,
      <Ref Attr = "Idempotents"/>, and
      <Ref Oper = "IsRegularSemigroupElement" BookName = "ref"/>.
      <P/>

      The function <C>IsRegularDClass</C> produces the same output as the
      &GAP; library functions with the same name; see
      <Ref Oper="IsRegularDClass" BookName="ref"/>.

      <Example><![CDATA[
gap> S := Monoid(Transformation([10, 8, 7, 4, 1, 4, 10, 10, 7, 2]),
>                Transformation([5, 2, 5, 5, 9, 10, 8, 3, 8, 10]));;
gap> f := Transformation([1, 1, 10, 8, 8, 8, 1, 1, 10, 8]);;
gap> R := RClass(S, f);;
gap> IsRegularGreensClass(R);
true
gap> S := Monoid(Transformation([2, 3, 4, 5, 1, 8, 7, 6, 2, 7]),
>                Transformation([3, 8, 7, 4, 1, 4, 3, 3, 7, 2]));;
gap> f := Transformation([3, 8, 7, 4, 1, 4, 3, 3, 7, 2]);;
gap> R := RClass(S, f);;
gap> IsRegularGreensClass(R);
false
gap> NrIdempotents(R);
0
gap> S := Semigroup(Transformation([2, 1, 3, 1]),
>                   Transformation([3, 1, 2, 1]),
>                   Transformation([4, 2, 3, 3]));;
gap> f := Transformation([4, 2, 3, 3]);;
gap> L := GreensLClassOfElement(S, f);;
gap> IsRegularGreensClass(L);
false
gap> R := GreensRClassOfElement(S, f);;
gap> IsRegularGreensClass(R);
false
gap> g := Transformation([4, 4, 4, 4]);;
gap> IsRegularSemigroupElement(S, g);
true
gap> IsRegularGreensClass(LClass(S, g));
true
gap> IsRegularGreensClass(RClass(S, g));
true
gap> IsRegularDClass(DClass(S, g));
true
gap> DClass(S, g) = RClass(S, g);
false]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IteratorOfXClassReps">
  <ManSection><Heading>IteratorOfXClassReps</Heading>
  <Oper Name = "IteratorOfDClassReps" Arg = "S"/>
  <Oper Name = "IteratorOfHClassReps" Arg = "S"/>
  <Oper Name = "IteratorOfLClassReps" Arg = "S"/>
  <Returns>
  An iterator.
  </Returns>
  <Description>
  Returns an iterator of the representatives of the Green's classes contained
  in the semigroup <A>S</A>.  See <Ref Sect = "Iterators" BookName = "ref"/> for
  more information on iterators.<P/>

  See also <Ref Meth = "GreensRClasses" BookName = "ref"/>, <Ref
  Meth = "GreensRClasses"/>, and <Ref Oper = "IteratorOfRClasses"/>.<P/>

  </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IteratorOfXClasses">
  <ManSection><Heading>IteratorOfXClasses</Heading>
  <Oper Name = "IteratorOfDClasses" Arg = "S"/>
  <Oper Name = "IteratorOfRClasses" Arg = "S"/>
  <Returns>
  An iterator.
  </Returns>

  <Description>
    Returns an iterator of the Green's classes in the semigroup <A>S</A>.
    See <Ref Sect = "Iterators" BookName = "ref"/> for more information on
    iterators.<P/>

    This function is useful if you are, for example, looking for an &R;-class
    of a semigroup with a particular property but do not necessarily want to
    compute all of the &R;-classes.<P/>

    See also <Ref Meth = "GreensRClasses"/>,
    <Ref Meth = "GreensRClasses" BookName = "ref"/>, and
    <Ref Attr = "NrRClasses"/>. <P/>

    The transformation semigroup in the example below has 25147892 elements but
    it only takes a fraction of a second to find a non-trivial &R;-class. The
    inverse semigroup of partial permutations in the example below has size
    158122047816 but it only takes a fraction of a second to find an &R;-class
    with more than 1000 elements.

  <Example><![CDATA[
gap> gens := [Transformation([2, 4, 1, 5, 4, 4, 7, 3, 8, 1]),
>             Transformation([3, 2, 8, 8, 4, 4, 8, 6, 5, 7]),
>             Transformation([4, 10, 6, 6, 1, 2, 4, 10, 9, 7]),
>             Transformation([6, 2, 2, 4, 9, 9, 5, 10, 1, 8]),
>             Transformation([6, 4, 1, 6, 6, 8, 9, 6, 2, 2]),
>             Transformation([6, 8, 1, 10, 6, 4, 9, 1, 9, 4]),
>             Transformation([8, 6, 2, 3, 3, 4, 8, 6, 2, 9]),
>             Transformation([9, 1, 2, 8, 1, 5, 9, 9, 9, 5]),
>             Transformation([9, 3, 1, 5, 10, 3, 4, 6, 10, 2]),
>             Transformation([10, 7, 3, 7, 1, 9, 8, 8, 4, 10])];;
gap> S := Semigroup(gens);;
gap> iter := IteratorOfRClasses(S);
<iterator>
gap> for R in iter do
>   if Size(R) > 1 then
>     break;
>   fi;
> od;
gap> R;
<Green's R-class: Transformation( [ 6, 4, 1, 6, 6, 8, 9, 6, 2, 2 ] )>
gap> Size(R);
21600
gap> S := InverseSemigroup(
>  PartialPerm([1, 2, 3, 4, 5, 6, 7, 10, 11, 19, 20],
>              [19, 4, 11, 15, 3, 20, 1, 14, 8, 13, 17]),
>  PartialPerm([1, 2, 3, 4, 6, 7, 8, 14, 15, 16, 17],
>              [15, 14, 20, 19, 4, 5, 1, 13, 11, 10, 3]),
>  PartialPerm([1, 2, 4, 6, 7, 8, 9, 10, 14, 15, 18],
>              [7, 2, 17, 10, 1, 19, 9, 3, 11, 16, 18]),
>  PartialPerm([1, 2, 3, 4, 5, 7, 8, 9, 11, 12, 13, 16],
>              [8, 3, 18, 1, 4, 13, 12, 7, 19, 20, 2, 11]),
>  PartialPerm([1, 2, 3, 4, 5, 6, 7, 9, 11, 15, 16, 17, 20],
>              [7, 17, 13, 4, 6, 9, 18, 10, 11, 19, 5, 2, 8]),
>  PartialPerm([1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 18],
>              [10, 20, 11, 7, 13, 8, 4, 9, 2, 18, 17, 6, 15]),
>  PartialPerm([1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 14, 17, 18],
>              [10, 20, 18, 1, 14, 16, 9, 5, 15, 4, 8, 12, 19, 11]),
>  PartialPerm([1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 15, 16, 19, 20],
>              [13, 6, 1, 2, 11, 7, 16, 18, 9, 10, 4, 14, 15, 5, 17]),
>  PartialPerm([1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 20],
>              [5, 3, 12, 9, 20, 15, 8, 16, 13, 1, 17, 11, 14, 10, 2]),
>  PartialPerm([1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 17, 18, 19, 20],
>              [8, 3, 9, 20, 2, 12, 14, 15, 4, 18, 13, 1, 17, 19, 5]));;
gap> iter := IteratorOfRClasses(S);
<iterator>
gap> repeat
>   R := NextIterator(iter);
> until Size(R) > 1000;
gap> R;
<Green's R-class: [8,19,14][11,4][13,15,5][17,20]>
gap> Size(R);
10020240]]></Example>
  </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="NrXClasses">
  <ManSection><Heading>NrXClasses</Heading>
  <Attr Name = "NrDClasses" Arg = "obj"/>
  <Attr Name = "NrHClasses" Arg = "obj"/>
  <Attr Name = "NrLClasses" Arg = "obj"/>
  <Attr Name = "NrRClasses" Arg = "obj"/>
  <Returns>
    A positive integer.
  </Returns>
  <Description>
  <C>NrXClasses</C> returns the number of Green's classes in <A>obj</A> where
  <A>obj</A> can be a semigroup, &D;-, &L;-, or &R;-class where appropriate.
  If the actual Green's classes are not required, then it is  more efficient to
  use <Log>NrHClasses(obj)</Log> than <Log>Length(HClasses(obj))</Log> since the
  Green's classes themselves are not created when <C>NrXClasses</C> is called.
  <P/>

  See also <Ref Meth = "GreensRClasses"/>,
  <Ref Meth = "GreensRClasses" BookName = "ref"/>,
  <Ref Oper = "IteratorOfRClasses"/>, and

  <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> x := Transformation([2, 5, 4, 7, 4, 3, 6, 3]);;
gap> R := RClass(S, x);
<Green's R-class: Transformation( [ 2, 5, 4, 7, 4, 3, 6, 3 ] )>
gap> NrHClasses(R);
12
gap> D := DClass(R);
<Green's D-class: Transformation( [ 2, 5, 4, 7, 4, 3, 6, 3 ] )>
gap> NrHClasses(D);
72
gap> L := LClass(S, x);
<Green's L-class: Transformation( [ 2, 5, 4, 7, 4, 3, 6, 3 ] )>
gap> NrHClasses(L);
6
gap> NrHClasses(S);
1555
gap> S := Semigroup(Transformation([4, 6, 5, 2, 1, 3]),
>                   Transformation([6, 3, 2, 5, 4, 1]),
>                   Transformation([1, 2, 4, 3, 5, 6]),
>                   Transformation([3, 5, 6, 1, 2, 3]),
>                   Transformation([5, 3, 6, 6, 6, 2]),
>                   Transformation([2, 3, 2, 6, 4, 6]),
>                   Transformation([2, 1, 2, 2, 2, 4]),
>                   Transformation([4, 4, 1, 2, 1, 2]));;
gap> NrRClasses(S);
150
gap> Size(S);
6342
gap> x := Transformation([1, 3, 3, 1, 3, 5]);;
gap> D := DClass(S, x);
<Green's D-class: Transformation( [ 1, 3, 3, 1, 3, 5 ] )>
gap> NrRClasses(D);
87
gap> S := SymmetricInverseSemigroup(10);;
gap> NrDClasses(S); NrRClasses(S); NrHClasses(S); NrLClasses(S);
11
1024
184756
1024
gap> S := POPI(10);;
gap> NrDClasses(S);
11
gap> NrRClasses(S);
1024]]></Example>
  </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="NrIdempotents">
<ManSection>
  <Attr Name = "NrIdempotents" Arg = "obj"/>
  <Returns>
   A positive integer.
  </Returns>
  <Description>
   This function returns the number of idempotents in <A>obj</A> where
   <A>obj</A> can be a semigroup, &D;-, &L;-, &H;-, or &R;-class. If the
   actual idempotents are not required, then it is more efficient to use
   <C>NrIdempotents(obj)</C> than <C>Length(Idempotents(obj))</C> since
   the idempotents themselves are not created when <C>NrIdempotents</C> is
   called.<P/>

  See also <Ref Attr = "Idempotents" BookName = "ref"/> and
  <Ref Attr = "Idempotents"/>,
  <Ref Prop = "IsRegularDClass" BookName = "ref"/>,
  <Ref Prop = "IsRegularGreensClass"/>
  <Ref Prop = "IsGroupHClass" BookName = "ref"/>, and
  <Ref Attr = "GroupHClass"/>.

  <Example><![CDATA[
gap> S := Semigroup(Transformation([2, 3, 4, 1]),
>                   Transformation([3, 3, 1, 1]));;
gap> NrIdempotents(S);
5
gap> f := Transformation([2, 2, 4, 4]);;
gap> R := GreensRClassOfElement(S, f);;
gap> NrIdempotents(R);
2
gap> f := Transformation([4, 2, 2, 4]);;
gap> L := GreensLClassOfElement(S, f);;
gap> NrIdempotents(L);
2
gap> D := DClassOfLClass(L);;
gap> NrIdempotents(D);
4
gap> L := GreensLClassOfElement(S, Transformation([3, 1, 1, 3]));;
gap> NrIdempotents(L);
2
gap> H := GroupHClass(D);;
gap> NrIdempotents(H);
1
gap> S := InverseSemigroup(
> PartialPerm([1, 2, 3, 5, 7, 9, 10],
>              [6, 7, 2, 9, 1, 5, 3]),
> PartialPerm([1, 2, 3, 5, 6, 7, 9, 10],
>             [8, 1, 9, 4, 10, 5, 6, 7]));;
gap> NrIdempotents(S);
236
gap> f := PartialPerm([2, 3, 7, 9, 10],
>                     [7, 2, 1, 5, 3]);;
gap> D := DClassNC(S, f);;
gap> NrIdempotents(D);
13]]></Example>
  </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="NrRegularDClasses">
<ManSection>
  <Attr Name = "NrRegularDClasses" Arg = "S"/>
  <Attr Name = "RegularDClasses" Arg = "S"/>
  <Returns>
    A positive integer, or a list.
  </Returns>
  <Description>
    <C>NrRegularDClasses</C> returns the number of regular &D;-classes of the
    semigroup <A>S</A>.<P/>

    <C>RegularDClasses</C> returns a list of the regular &D;-classes of the
    semigroup <A>S</A>. <P/>

    See also <Ref Prop = "IsRegularGreensClass"/> and
    <Ref Func = "IsRegularDClass" BookName = "ref"/>.

    <Example><![CDATA[
gap> S := Semigroup(Transformation([1, 3, 4, 1, 3, 5]),
>                   Transformation([5, 1, 6, 1, 6, 3]));;
gap> NrRegularDClasses(S);
3
gap> NrDClasses(S);
7
gap> AsSet(RegularDClasses(S));
[ <Green's D-class: Transformation( [ 1, 4, 1, 1, 4, 3 ] )>,
  <Green's D-class: Transformation( [ 1, 1, 1, 1, 1 ] )>,
  <Green's D-class: Transformation( [ 1, 1, 1, 1, 1, 1 ] )> ]]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="PartialOrderOfXClasses">
  <ManSection>
  <Heading>PartialOrderOfXClasses</Heading>
  <Attr Name = "PartialOrderOfDClasses" Arg = "S"/>
  <Attr Name = "PartialOrderOfLClasses" Arg = "S"/>
  <Attr Name = "PartialOrderOfRClasses" Arg = "S"/>
  <Returns>
    A digraph.
  </Returns>
  <Description>
    Let <C>X</C> be one of Green's &D;-, &L;-, or &R;-relations. Then
    <C>PartialOrderOfXClasses</C> returns a digraph <C>D</C> where
    <C>OutNeighbours(D)[i]</C> contains every <C>j</C> such that
    <C>GreensXClasses(S)[j]</C> is immediately less than
    <C>GreensXClasses(S)[i]</C> in the partial order of <C>X</C>-classes of
    <A>S</A>. The reflexive transitive closure of the digraph <C>D</C> is the
    partial order of <C>X</C>-classes of <A>S</A> (in the sense of the
      &DIGRAPHS; package).
    <P/>

    The partial order on the <C>X</C>-classes is defined as follows.
    <List>
      <Mark>Green's &D;-relation:</Mark>
      <Item>
        <M>x\leq y</M> if and only if <M>S ^ 1xS ^ 1</M> is a subset of
        <M>S ^ 1yS ^ 1</M>.
      </Item>
      <Mark>Green's &L;-relation:</Mark>
      <Item>
        <M>x\leq y</M> if and only if <M>S ^ 1x</M> is a subset of
        <M>S ^ 1y</M>.
      </Item>
      <Mark>Green's &R;-relation:</Mark>
      <Item>
        <M>x\leq y</M> if and only if <M>xS ^ 1</M> is a subset of
        <M>yS ^ 1</M>.
      </Item>
    </List>

    See also <Ref Meth = "GreensDClasses"/>,
    <Ref Meth = "GreensDClasses" BookName = "ref"/>,
    <Ref Oper = "IsGreensLessThanOrEqual" BookName = "ref"/>,
    and <Ref Oper="\&lt;" Label="for Green's classes"/>.
  <Example><![CDATA[
gap> S := Semigroup(Transformation([2, 4, 1, 2]),
>                   Transformation([3, 3, 4, 1]));;
gap> PartialOrderOfDClasses(S);
<immutable digraph with 4 vertices, 3 edges>
gap> IsGreensLessThanOrEqual(GreensDClasses(S)[1],
>                            GreensDClasses(S)[2]);
false
gap> IsGreensLessThanOrEqual(GreensDClasses(S)[2],
>                            GreensDClasses(S)[1]);
false
gap> IsGreensLessThanOrEqual(GreensDClasses(S)[3],
>                            GreensDClasses(S)[1]);
true
gap> S := InverseSemigroup(
> PartialPerm([1, 2, 3], [1, 3, 4]),
> PartialPerm([1, 3, 5], [5, 1, 3]));;
gap> Size(S);
58
gap> PartialOrderOfDClasses(S);
<immutable digraph with 5 vertices, 4 edges>
gap> IsGreensLessThanOrEqual(GreensDClasses(S)[1],
>                            GreensDClasses(S)[2]);
false
gap> IsGreensLessThanOrEqual(GreensDClasses(S)[5],
>                            GreensDClasses(S)[2]);
true
gap> IsGreensLessThanOrEqual(GreensDClasses(S)[3],
>                            GreensDClasses(S)[4]);
false
gap> IsGreensLessThanOrEqual(GreensDClasses(S)[4],
>                            GreensDClasses(S)[3]);
true]]></Example>
  </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SchutzenbergerGroup">
<ManSection>
  <Attr Name = "SchutzenbergerGroup" Arg = "class"/>
  <Returns>
    A group.
  </Returns>
  <Description>
  <C>SchutzenbergerGroup</C> returns the generalized Schutzenberger group
  (defined below) of the &R;-, &D;-, &L;-, or &H;-class <A>class</A>.  <P/>

  If <C>f</C> is an element of a semigroup of transformations or partial
  permutations and <C>im(f)</C> denotes the image of <C>f</C>, then the
  <E>generalized Schutzenberger group</E> of <C>im(f)</C> is the permutation
  group
  <Alt Not = "Text">
  <Display>
    \{\:g|_{\textrm{im}(f)}\::\:\textrm{im}(f*g)=\textrm{im}(f)\:\}.
  </Display>
  </Alt>
  <Alt Only="Text">
  { g|_im(f) : im(f*g)=im(f) }.
</Alt><P/>
  The generalized Schutzenberger group of the kernel <C>ker(f)</C> of a
  transformation <C>f</C> or the domain <C>dom(f)</C> of a
  partial permutation <C>f</C> is defined analogously.
  <P/>

  The generalized Schutzenberger group of a Green's class is then defined as
  follows.
  <List>
    <Mark>&R;-class</Mark>
    <Item>
      The generalized Schutzenberger group of the image or range of the
      representative of the &R;-class.
    </Item>
    <Mark>&L;-class</Mark>
    <Item>
      The generalized Schutzenberger group of the kernel or domain of the
      representative of the &L;-class.
    </Item>
    <Mark>&H;-class</Mark>
    <Item>
      The intersection of the generalized Schutzenberger groups of the
      &R;- and &L;-class containing the &H;-class.
    </Item>
    <Mark>&D;-class</Mark>
    <Item>
      The intersection of the generalized Schutzenberger groups of the
      &R;- and &L;-class containing the representative of the &D;-class.
    </Item>
  </List>

  The output of this attribute is difficult to describe for other types of
  semigroup.  However, a general description is given in
  <Cite Key = "Mitchell2019aa"/>.

  <Example><![CDATA[
gap> S := Semigroup(Transformation([4, 4, 3, 5, 3]),
>                   Transformation([5, 1, 1, 4, 1]),
>                   Transformation([5, 5, 4, 4, 5]));;
gap> f := Transformation([5, 5, 4, 4, 5]);;
gap> SchutzenbergerGroup(RClass(S, f));
Group([ (4,5) ])
gap> S := InverseSemigroup(
> PartialPerm([1, 2, 3, 7],
>             [9, 2, 4, 8]),
> PartialPerm([1, 2, 6, 7, 8, 9, 10],
>             [6, 8, 4, 5, 9, 1, 3]),
> PartialPerm([1, 2, 3, 5, 6, 7, 8, 9],
>             [7, 4, 1, 6, 9, 5, 2, 3]));;
gap> List(DClasses(S), SchutzenbergerGroup);
[ Group(()), Group(()), Group(()), Group(()), Group([ (4,9) ]),
  Group(()), Group(()), Group([ (5,8,6), (5,8) ]), Group(()),
  Group(()), Group(()), Group(()), Group(()), Group(()),
  Group([ (1,7,5,6,9,3) ]), Group([ (1,6)(3,5) ]), Group(()),
  Group(()), Group(()), Group(()), Group(()), Group(()), Group(()) ]]]></Example>
  </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="GreensMultiplier">
<ManSection>
  <Oper Name = "LeftGreensMultiplier" Arg = "S, a, b"/>
  <Oper Name = "RightGreensMultiplier" Arg = "S, a, b"/>
  <Returns>
    An element.
  </Returns>
  <Description>
  If <A>S</A> is a semigroup, and <A>a</A> and <A>b</A> are
  &L;-related elements of <A>S</A>, then <C>LeftGreensMultiplier</C>
  returns an element <C>s</C> such that <C>s * <A>a</A> = <A>b</A></C>. The
  element <C>s</C> is of the same type as the elements of <A>S</A> but may
  or may not be an element of <A>S</A>. In particular, if <A>S</A> is not a
  monoid and <C><A>a</A> = <A>b</A></C>, then
  <C>One(GeneratorsOfSemigroup(S))</C> or an adjoined identity may be returned. Even if <C><A>a</A> &lt;>
  <A>b</A></C>, then it is not guaranteed that the returned element <C>s</C>
  will belong to <A>S</A>. It is guaranteed that the left action of <C>s</C> on
  the elements of the &L;-class of <A>a</A> is the same as the left action of
  an element of <A>S</A> with the identity adjoined.<P/>

  <C>LeftGreensMultiplier</C> gives an error if <A>a</A> and <A>b</A> are not
  &L;-related elements of <A>S</A>.<P/>

  The operation <C>RightGreensMultiplier</C> is defined analogously.

  <Example><![CDATA[
gap> S := Semigroup(Transformation([4, 4, 3, 5, 3]),
>                   Transformation([5, 1, 1, 4, 1]),
>                   Transformation([5, 5, 4, 4, 5]));;
gap> a := Transformation([5, 5, 4, 4, 5]);;
gap> LeftGreensMultiplier(S, a, a);
Transformation( [ 1, 1, 3, 3, 1 ] )
gap> RightGreensMultiplier(S, a, a);
Transformation( [ 5, 5, 5, 4, 5 ] )
gap> b := Transformation([5, 4, 4, 5, 4]);
Transformation( [ 5, 4, 4, 5, 4 ] )
gap> s := LeftGreensMultiplier(S, a, b);
Transformation( [ 1, 3, 3, 1, 3 ] )
gap> s * a;
Transformation( [ 5, 4, 4, 5, 4 ] )
gap> b := Transformation([4, 4, 5, 5, 4]);
Transformation( [ 4, 4, 5, 5, 4 ] )
gap> s := RightGreensMultiplier(S, a, b);
Transformation( [ 4, 4, 4, 5, 4 ] )
gap> a * s = b;
true]]></Example>
  </Description>
  </ManSection>
<#/GAPDoc>
