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

# TODO actually use this in the manual
<#GAPDoc Label="InverseMonoidByGenerators">
  <ManSection>
    <Oper Name="InverseMonoidByGenerators" Arg="coll[, opts]"/>
    <Oper Name="InverseSemigroupByGenerators"  Arg="coll[, opts]"/>
    <Returns>An inverse monoid or semigroup.</Returns>
    <Description>
      If <A>coll</A> is a partial permutation collection, then
      <C>InverseMonoidByGenerators</C> and 
      <C>InverseSemigroupByGenerators</C>
      return the inverse monoid and semigroup generated by <A>coll</A>,
      respectively. <P/>

      If present, the optional second argument <A>opts</A> should be a record
      containing the values of the options for the semigroup being created, as
      described in Section <Ref Sect="opts"/>.<P/> 
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="Generators">
  <ManSection>
    <Attr Name="Generators" Arg="S"/>
    <Returns>A list of generators.</Returns>
    <Description>
      <C>Generators</C> returns a generating set that can be used to define the
      semigroup <A>S</A>.  The generators of a monoid or inverse semigroup
      <A>S</A>, say, can be defined in several ways, for example, including or
      excluding the identity element, including or not the inverses of the
      generators.  <C>Generators</C> uses the definition that returns the least
      number of generators. If no generating set for <A>S</A> is known, then
      <C>GeneratorsOfSemigroup</C> is used by default.<P/>
     
      <List>
        <Mark>for a group</Mark> 
        <Item><C>Generators(<A>S</A>)</C> is a synonym for 
          <Ref Attr="GeneratorsOfGroup" BookName="ref"/>.
        </Item>
        <Mark>for an ideal of semigroup</Mark> 
        <Item><C>Generators(<A>S</A>)</C> is a synonym for 
          <Ref Attr="GeneratorsOfSemigroupIdeal"/>.
        </Item>
        <Mark>for a semigroup</Mark>
        <Item><C>Generators(<A>S</A>)</C> is a synonym for 
          <Ref Attr="GeneratorsOfSemigroup" BookName="ref"/>.
        </Item>
        <Mark>for a monoid</Mark>
        <Item><C>Generators(<A>S</A>)</C> is a synonym for 
          <Ref Attr="GeneratorsOfMonoid" BookName="ref"/>.
        </Item>
        <Mark>for an inverse semigroup</Mark>
        <Item><C>Generators(<A>S</A>)</C> is a synonym for 
          <Ref Attr="GeneratorsOfInverseSemigroup" BookName="ref"/>.
        </Item>
        <Mark>for an inverse monoid</Mark>
        <Item><C>Generators(<A>S</A>)</C> is a synonym for 
          <Ref Attr="GeneratorsOfInverseMonoid" BookName="ref"/>.
        </Item>
      </List>
<Example>
gap> M:=Monoid(Transformation( [ 1, 4, 6, 2, 5, 3, 7, 8, 9, 9 ] ),
> Transformation( [ 6, 3, 2, 7, 5, 1, 8, 8, 9, 9 ] ) );;
gap> GeneratorsOfSemigroup(M);
[ IdentityTransformation, 
  Transformation( [ 1, 4, 6, 2, 5, 3, 7, 8, 9, 9 ] ), 
  Transformation( [ 6, 3, 2, 7, 5, 1, 8, 8, 9, 9 ] ) ]
gap> GeneratorsOfMonoid(M);
[ Transformation( [ 1, 4, 6, 2, 5, 3, 7, 8, 9, 9 ] ), 
  Transformation( [ 6, 3, 2, 7, 5, 1, 8, 8, 9, 9 ] ) ]
gap> Generators(M);
[ Transformation( [ 1, 4, 6, 2, 5, 3, 7, 8, 9, 9 ] ), 
  Transformation( [ 6, 3, 2, 7, 5, 1, 8, 8, 9, 9 ] ) ]
gap> S:=Semigroup(Generators(M));;
gap> Generators(S);
[ Transformation( [ 1, 4, 6, 2, 5, 3, 7, 8, 9, 9 ] ), 
  Transformation( [ 6, 3, 2, 7, 5, 1, 8, 8, 9, 9 ] ) ]
gap> GeneratorsOfSemigroup(S);
[ Transformation( [ 1, 4, 6, 2, 5, 3, 7, 8, 9, 9 ] ), 
  Transformation( [ 6, 3, 2, 7, 5, 1, 8, 8, 9, 9 ] ) ]</Example>
   </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="ClosureSemigroup">
  <ManSection>
    <Oper Name="ClosureSemigroup" Arg="S, coll [, opts]"/>
    <Returns>A semigroup or monoid.</Returns>
    <Description>
      This function returns the semigroup or monoid generated by the
      semigroup <A>S</A> and the collection of elements 
      <A>coll</A> after removing duplicates and elements
      from <A>coll</A> that are already in <A>S</A>. In most cases, the new
      semigroup knows at least as much information about its structure as was
      already known about that of <A>S</A>. <P/>

      If present, the optional third argument <A>opts</A> should be a record
      containing the values of the options for the semigroup being created as
      described in Section <Ref Sect="opts"/>.<P/>
      <Example><![CDATA[
gap> gens:=[ Transformation( [ 2, 6, 7, 2, 6, 1, 1, 5 ] ), 
>  Transformation( [ 3, 8, 1, 4, 5, 6, 7, 1 ] ), 
>  Transformation( [ 4, 3, 2, 7, 7, 6, 6, 5 ] ), 
>  Transformation( [ 7, 1, 7, 4, 2, 5, 6, 3 ] ) ];;
gap> S:=Monoid(gens[1]);;
gap> for i in [2..4] do S:=ClosureSemigroup(S, gens[i]); od;
gap> S;
<transformation monoid of degree 8 with 4 generators>
gap> Size(S);
233606
gap> gens:=
> [ NewMatrixOverFiniteField(IsPlistMatrixOverFiniteFieldRep,GF(25),2,
>    [ [ Z(5^2), Z(5^2)^13 ], [ 0*Z(5), Z(5^2)^14 ] ]), 
>  NewMatrixOverFiniteField(IsPlistMatrixOverFiniteFieldRep,GF(25),2,
>    [ [ Z(5^2)^21, Z(5)^0 ], [ Z(5)^0, 0*Z(5) ] ]), 
>  NewMatrixOverFiniteField(IsPlistMatrixOverFiniteFieldRep,GF(25),2,
>    [ [ Z(5^2)^23, Z(5^2)^5 ], [ Z(5^2)^20, Z(5^2)^20 ] ]) ];;
gap> S := Semigroup(gens[1]);
<semigroup of 2x2 matrices over GF(5^2) with 1 generator>
gap> Size(S);
24
gap> S := ClosureSemigroup(S, gens[2]);
<semigroup of 2x2 matrices over GF(5^2) with 2 generators>
gap> Size(S);
124800
gap> S := ClosureSemigroup(S, gens[3]);
<semigroup of 2x2 matrices over GF(5^2) with 3 generators>
gap> Size(S);
374400]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="ClosureInverseSemigroup">
   <ManSection>
    <Oper Name="ClosureInverseSemigroup"  Arg="S, coll [, opts]"/>
    <Returns>An inverse semigroup or monoid.</Returns>
    <Description>
      This function returns the inverse semigroup or monoid generated by the
      inverse semigroup <A>S</A> and the collection of elements <A>coll</A>
      after first removing duplicates and elements in <A>coll</A>
      that are already in <A>S</A>. In most cases, the new semigroup knows at
      least as much information about its structure as was already known about
      that of <A>S</A>. <P/>

      If present, the optional third argument <A>opts</A> should be a record
      containing the values of the options for the inverse semigroup being
      created; these options are described in Section <Ref Sect="opts"/>. <P/>

      <Example><![CDATA[
gap> S:=InverseMonoid(
> PartialPerm( [ 1, 2, 3, 5, 6, 7, 8 ], [ 5, 9, 10, 6, 3, 8, 4 ] ),
> PartialPerm( [ 1, 2, 4, 7, 8, 9 ], [ 10, 7, 8, 5, 9, 1 ] ) );;
gap> f:=PartialPerm(
> [ 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 18, 19, 20 ],
> [ 5, 1, 7, 3, 10, 2, 12, 14, 11, 16, 6, 9, 15 ]);;
gap> S:=ClosureInverseSemigroup(S, f);
<inverse partial perm semigroup of rank 19 with 4 generators>
gap> Size(S);
9744
gap> T:=Idempotents(SymmetricInverseSemigroup(10));;
gap> S:=ClosureInverseSemigroup(S, T);
<inverse partial perm semigroup of rank 19 with 854 generators>
gap> S:=InverseSemigroup(SmallGeneratingSet(S));
<inverse partial perm semigroup of rank 19 with 14 generators>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomInverseMonoid">
  <ManSection>
    <Oper Name="RandomInverseMonoid" Arg="m, n"/>
    <Oper Name="RandomInverseSemigroup"  Arg="m, n"/>
    <Returns>An inverse monoid or semigroup.</Returns>
    <Description>
      Returns  a  random  inverse  monoid  or semigroup of partial
      permutations with degree at most <A>n</A> with <A>m</A> generators.
      <Example><![CDATA[
gap> S := RandomInverseSemigroup(10, 10);                                
<inverse partial perm semigroup of rank 10 with 10 generators>
gap> S := RandomInverseMonoid(10, 10);   
<inverse partial perm monoid of rank 10 with 10 generators>
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomTransformationMonoid">
  <ManSection>
    <Oper Name="RandomTransformationMonoid" Arg="m, n"/>
    <Oper Name="RandomTransformationSemigroup" Arg="m, n"/>
    <Returns>A transformation semigroup or monoid.</Returns>
    <Description>
      Returns a random transformation monoid or semigroup of at most degree
      <A>n</A> with <A>m</A> generators.
      <Example><![CDATA[
gap> S := RandomTransformationMonoid(5, 5);
<transformation monoid of degree 5 with 5 generators>
gap> S := RandomTransformationSemigroup(5, 5);
<transformation semigroup of degree 5 with 5 generators>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomPartialPermMonoid">
  <ManSection>
    <Oper Name="RandomPartialPermMonoid" Arg="m, n"/>
    <Oper Name="RandomPartialPermSemigroup" Arg="m, n"/>
    <Returns>A partial perm semigroup or monoid.</Returns>
    <Description>
      Returns a random partial perm monoid or semigroup of degree at most
      <A>n</A> with <A>m</A> generators.
      <Log><![CDATA[
gap> S:=RandomPartialPermSemigroup(5, 5);
<partial perm semigroup of rank 4 with 5 generators>
gap> S:=RandomPartialPermMonoid(5, 5);
<partial perm monoid of degree 5 with 5 generators>]]></Log>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomBinaryRelationMonoid">
  <ManSection>
    <Oper Name="RandomBinaryRelationMonoid" Arg="m, n"/>
    <Oper Name="RandomBinaryRelationSemigroup" Arg="m, n"/>
    <Returns>A semigroup or monoid of binary relations.</Returns>
    <Description>
      Returns a random monoid or semigroup of binary relations on <A>n</A>
      points with <A>m</A> generators.
      <Example><![CDATA[
gap> RandomBinaryRelationSemigroup(5,5);
<semigroup with 5 generators>
gap> RandomBinaryRelationMonoid(5,5);   
<monoid with 5 generators>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomBipartitionMonoid">
  <ManSection>
    <Oper Name="RandomBipartitionSemigroup" Arg="m, n"/>
    <Oper Name="RandomBipartitionMonoid" Arg="m, n"/>
    <Returns>A bipartition semigroup or monoid.</Returns>
    <Description>
      Returns a random monoid or semigroup of bipartition on <A>n</A>
      points with <A>m</A> generators.
      <Example><![CDATA[
gap> RandomBipartitionMonoid(5, 5);
<bipartition monoid of degree 5 with 5 generators>
gap> RandomBipartitionSemigroup(5, 5);
<bipartition semigroup of degree 5 with 5 generators>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomMatrixMonoid">
  <ManSection>
    <Oper Name="RandomMatrixSemigroup" Arg="R, m, n, [,ranks]"/>
    <Oper Name="RandomMatrixMonoid" Arg="R, m, n, [,ranks]"/>
    <Returns>A matrix semigroup or monoid.</Returns>
    <Description>
      Returns a random semigroup or monoid of <A>n</A>-by-<A>n</A> matrices
      over the ring <A>R</A> with <A>m</A> generators. <P/>
      
      The optional fourth argument <A>ranks</A> is expected to be a list of
      permissible ranks for the generators. 
      For any generator the rank is chosen uniformly randomly from the list of
      permissible ranks.  This allows for creating more interesting random
      matrix semigroups and monoids.  Without the <A>ranks</A> argument there
      is a very high probability that the semigroups returned by this function
      are full matrix monoids over the base ring.
      <Example><![CDATA[
gap> RandomMatrixSemigroup(GF(25),5,5);
<semigroup of 5x5 matrices over GF(5^2) with 5 generators>
gap> RandomMatrixSemigroup(GF(4),2,5,[1,2]);
<semigroup of 5x5 matrices over GF(2^2) with 2 generators>
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="InverseSubsemigroupByProperty">
  <ManSection>
    <Oper Name="InverseSubsemigroupByProperty" Arg="S, func"/>
    <Returns>An inverse semigroup.</Returns>
    <Description>
    <C>InverseSubsemigroupByProperty</C> returns the inverse subsemigroup of the
    inverse semigroup <A>S</A> generated by those elements of <A>S</A>
    fulfilling <A>func</A> (which should be a function returning <K>true</K> or
    <K>false</K>).<P/>

    If no elements of <A>S</A> fulfil <A>func</A>, then <K>fail</K> is
    returned.<P/> 
    
    If the optional third argument <A>limit</A> is present and a positive
    integer, then once the subsemigroup has at least <A>limit</A> elements the
    computation stops.
    <Example><![CDATA[
gap> IsIsometry:=function(f)
> local n, i, j, k, l;
>  n:=RankOfPartialPerm(f);
>  for i in [1..n-1] do
>    k:=DomainOfPartialPerm(f)[i];
>    for j in [i+1..n] do
>      l:=DomainOfPartialPerm(f)[j];
>      if not AbsInt(k^f-l^f)=AbsInt(k-l) then
>        return false;
>      fi;
>    od;
>  od;
>  return true;
> end;;
gap> S:=InverseSubsemigroupByProperty(SymmetricInverseSemigroup(5),
> IsIsometry);;
gap> Size(S);
142]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SubsemigroupByProperty">
<ManSection>
  <Oper Name="SubsemigroupByProperty" Arg="S, func" 
    Label="for a semigroup and function"/>
  <Oper Name="SubsemigroupByProperty" Arg="S, func, limit" 
  Label="for a semigroup, function, and limit on the size of the subsemigroup"/>
  <Returns>A semigroup.</Returns>
  <Description>
    <C>SubsemigroupByProperty</C> returns the subsemigroup of the semigroup
    <A>S</A> generated by those elements of <A>S</A> fulfilling <A>func</A>
    (which should be a function returning <K>true</K> or <K>false</K>).<P/>

    If no elements of <A>S</A> fulfil <A>func</A>, then <K>fail</K> is
    returned.<P/> 

    If the optional third argument <A>limit</A> is present and a positive
    integer, then once the subsemigroup has at least <A>limit</A> elements the
    computation stops.
    <Example><![CDATA[
gap> func := function(f) return 1 ^ f <> 1 and
> ForAll([1..DegreeOfTransformation(f)], y-> y = 1 or y ^ f = y); end;
function( f ) ... end
gap> T := SubsemigroupByProperty(FullTransformationSemigroup(3), func);
<transformation semigroup of size 2, degree 3 with 2 generators>
gap> T := SubsemigroupByProperty(FullTransformationSemigroup(4), func);
<transformation semigroup of size 3, degree 4 with 3 generators>
gap> T := SubsemigroupByProperty(FullTransformationSemigroup(5), func);
<transformation semigroup of size 4, degree 5 with 4 generators>]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="Random">
  <ManSection>
    <Meth Name="Random" Arg="S" Label="for a semigroup"/>
    <Returns>A random element.</Returns>
    <Description>
      This function returns a random element of the semigroup <A>S</A>.
      If the elements of <A>S</A> have been calculated, then one of these
      is chosen randomly.

      Otherwise, if the data  structure for <A>S</A> is known,
      then a random element of a randomly chosen &R;-class is returned. 
      
      If the data structure for <A>S</A> has not been calculated, then a short
      product (at most <C>2*Length(GeneratorsOfSemigroup(<A>S</A>))</C>) of
      generators is returned. 
       
    </Description> 
  </ManSection>
<#/GAPDoc>
