#############################################################################
##
#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 on 8 pts with 4 generators>
gap> Size(S);
233606]]></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 on 19 pts with 4 generators>
gap> Size(S);
9744
gap> T:=Idempotents(SymmetricInverseSemigroup(10));;
gap> S:=ClosureInverseSemigroup(S, T);
<inverse partial perm semigroup on 19 pts with 854 generators>
gap> S:=InverseSemigroup(SmallGeneratingSet(S));
<inverse partial perm semigroup on 19 pts 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 on 10 pts with 10 generators>
gap> S:=RandomInverseMonoid(10,10);   
<inverse partial perm monoid on 10 pts 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 on 5 pts with 5 generators>
gap> S:=RandomTransformationSemigroup(5,5);
<transformation semigroup on 5 pts 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 on 4 pts with 5 generators>
gap> S:=RandomPartialPermMonoid(5, 5);
<partial perm monoid on 5 pts 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 on 5 pts with 5 generators>
gap> RandomBipartitionSemigroup(5,5);
<bipartition semigroup on 5 pts with 5 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, on 3 pts with 2 generators>
gap> T:=SubsemigroupByProperty(FullTransformationSemigroup(4), func);
<transformation semigroup of size 3, on 4 pts with 3 generators>
gap> T:=SubsemigroupByProperty(FullTransformationSemigroup(5), func);
<transformation semigroup of size 4, on 5 pts 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>
