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

<#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="IsGreensDLeq">
<ManSection>
  <Attr Name="IsGreensDLeq" Arg="S"/>
  <Returns>A function.</Returns>
  <Description>
    <C>IsGreensDLeq(<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(DClassReps(S));
[ Transformation( [ 1, 3, 4, 1, 3 ] ), 
  Transformation( [ 2, 4, 1, 5, 5 ] ), 
  Transformation( [ 1, 4, 1, 1, 4 ] ), 
  Transformation( [ 1, 1, 1, 1, 1 ] ) ]
gap> Sort(reps, IsGreensDLeq(S));
gap> reps;
[ Transformation( [ 2, 4, 1, 5, 5 ] ), 
  Transformation( [ 1, 3, 4, 1, 3 ] ), 
  Transformation( [ 1, 4, 1, 1, 4 ] ), 
  Transformation( [ 1, 1, 1, 1, 1 ] ) ]
gap> IsGreensLessThanOrEqual(DClass(S, reps[2]), DClass(S, reps[1]));
true
gap> S := DualSymmetricInverseMonoid(4);;
gap> IsGreensDLeq(S)(S.1, S.3);                      
true
gap> IsGreensDLeq(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 bipartition 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="StructureDescriptionSchutzenbergerGroups">
  <ManSection>
    <Attr Name="StructureDescriptionSchutzenbergerGroups" Arg="S"/>
    <Returns>Distinct structure descriptions of the Schutzenberger groups of a
      semigroup.</Returns>
    <Description>
      <C>StructureDescriptionSchutzenbergerGroups</C> returns the distinct
      values of <Ref Attr="StructureDescription" BookName="ref"/> when it is
      applied to the Schutzenberger groups of the &R;-classes of the semigroup
      <A>S</A>.
      <Example><![CDATA[
gap> S := Semigroup( PartialPerm( [ 1, 2, 3 ], [ 2, 5, 4 ] ), 
>  PartialPerm( [ 1, 2, 3 ], [ 4, 1, 2 ] ), 
>  PartialPerm( [ 1, 2, 3 ], [ 5, 2, 3 ] ), 
>  PartialPerm( [ 1, 2, 4, 5 ], [ 2, 1, 4, 3 ] ), 
>  PartialPerm( [ 1, 2, 5 ], [ 2, 3, 5 ] ), 
>  PartialPerm( [ 1, 2, 3, 5 ], [ 2, 3, 5, 4 ] ), 
>  PartialPerm( [ 1, 2, 3, 5 ], [ 4, 2, 5, 1 ] ), 
>  PartialPerm( [ 1, 2, 3, 5 ], [ 5, 2, 4, 3 ] ), 
>  PartialPerm( [ 1, 2, 5 ], [ 5, 4, 3 ] ) );;
gap> StructureDescriptionSchutzenbergerGroups(S);            
[ "1", "C2", "S3" ]
gap> S := Monoid( 
> Bipartition([[ 1, 2, 5, -1, -2 ], [ 3, 4, -3, -5 ], [ -4 ]]), 
> Bipartition([[ 1, 2, -2 ], [ 3, -1 ], [ 4 ], [ 5 ], [ -3, -4 ], [ -5 ]]),
> Bipartition([[ 1 ], [ 2, 3, -5 ], [ 4, -3 ], [ 5, -2 ], [ -1, -4 ]]));
<bipartition monoid of degree 5 with 3 generators>
gap> StructureDescriptionSchutzenbergerGroups(S);
[ "1", "C2" ]]]></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="MaximalDClasses">
  <ManSection>
    <Attr Name="MaximalDClasses" Arg="S"/>
    <Returns>The maximal &D;-classes of a semigroup.</Returns>
    <Description>
      <C>MaximalDClasses</C> returns the maximal &D;-classes with respect to
      the partial order of &D;-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"/>
  <Returns>A Rees matrix semigroup.</Returns>
  <Description> 
    <C>PrincipalFactor(<A>D</A>)</C> is just shorthand for
    <C>Range(InjectionPrincipalFactor(<A>D</A>))</C>, where <A>D</A> is a
    &D;-class of semigroup; see
    <Ref Oper="InjectionPrincipalFactor"/> 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> PrincipalFactor(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
      Func="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(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(G));;
gap> Append(mat, [1..1000]*0);
gap> mat := List([1..138], x-> List([1..57], x-> Random(mat)));;
gap> R := ReesZeroMatrixSemigroup(G, 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 := RandomBipartitionSemigroup(100,4);
<bipartition semigroup of degree 4 with 96 generators>
gap> Length(SmallGeneratingSet(S));       
13]]></Log>
    </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 degree 6 with 4 generators>
gap> MultiplicativeZero(S);
fail
gap> S := DualSymmetricInverseMonoid(6);
<inverse bipartition 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);
<Green's D-class: Transformation( [ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ] )>
gap> ForAll(GreensDClasses(S), x-> IsGreensLessThanOrEqual(D, x));
true
gap> MinimalIdeal(POI(10));
<partial perm group of rank 10>
gap> MinimalIdeal(BrauerMonoid(6));
<simple bipartition semigroup ideal of degree 6 with 1 generator>]]></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( [ 1, 2, 2, 5, 5, 1 ] )
gap> MinimalDClass(S);
<Green's D-class: Transformation( [ 1, 2, 2, 5, 5, 1 ] )>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsomorphismPermGroup">
<ManSection>
  <Oper 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.

<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> Range(IsomorphismPermGroup(S)); 
Group([ (5,6,8), (2,3,8,4) ])
gap> StructureDescription(Range(IsomorphismPermGroup(S)));
"S6"
gap> S := Range(IsomorphismPartialPermSemigroup(SymmetricGroup(4)));
<inverse partial perm semigroup of rank 4 with 2 generators>
gap> IsomorphismPermGroup(S);
MappingByFunction( <partial perm group of rank 4 with 2 generators>
, Group([ (1,2,3,4), (1,
2) ]), <Attribute "AsPermutation">, function( x ) ... end )
gap> G := GroupOfUnits(PartitionMonoid(4));
<bipartition group of degree 4 with 2 generators>
gap> StructureDescription(G);
"S4"
gap> iso := IsomorphismPermGroup(G);  
MappingByFunction( <bipartition group of degree 4 with 2 generators>
, S4, <Attribute "AsPermutation">, function( x ) ... end )
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.</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 Oper="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 Attr="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 bipartition monoid of degree 5 with 3 generators>
gap> IdempotentGeneratedSubsemigroup(S);
<inverse bipartition 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="IsomorphismReesMatrixSemigroup" Arg="D"/>
  <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 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> returns an error.<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> InjectionPrincipalFactor(d);;
    gap> rms := Range(last);
    <Rees 0-matrix semigroup 3x3 over Group(())>
    gap> MatrixOfReesZeroMatrixSemigroup(rms);
    [ [ (), 0, 0 ], [ 0, (), 0 ], [ 0, 0, () ] ]
    gap> Size(rms);
    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 := DClasses(S)[3];
    <Green's D-class: <bipartition: [ 1, 5, -2, -4 ], [ 2, 3, 4, -1, -5 ]
       , [ -3 ]>>
    gap> inj := InjectionPrincipalFactor(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( f ) ... end, function( x ) ... end )]]></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(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 := RandomBipartitionSemigroup(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="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>
