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

<#GAPDoc Label="IsomorphismSemigroup">
<ManSection>
  <Oper Name = "IsomorphismSemigroup" Arg = "filt, S"/>
  <Returns>An isomorphism of semigroups.</Returns>
  <Description>
    <C>IsomorphismSemigroup</C> can be used to find an isomorphism from a given
    semigroup to a semigroup of another type, provided such an isomorphism
    exists. 
    <P/>

    The first argument <A>filt</A> must be of the form <C>IsXSemigroup</C>, for
    example,
    <Ref Prop = "IsTransformationSemigroup" BookName = "ref"/>,
    <Ref Prop = "IsFpSemigroup" BookName = "ref"/>, and
    <Ref Filt = "IsPBRSemigroup"/> are some possible values for <A>filt</A>. 
    Note that <A>filt</A> should not be of the form <C>IsXMonoid</C>; see
    <Ref Oper = "IsomorphismMonoid"/>. 
    The second argument <A>S</A> should be a semigroup.
    <P/>

    <C>IsomorphismSemigroup</C> returns an isomorphism from <A>S</A> to a
    semigroup <A>T</A> of the type described by <A>filt</A>, if such an
    isomorphism exists. More precisely, if <C>T</C> is the range of the
    returned isomorphism, then <C><A>filt</A>(T)</C> will return <K>true</K>.
    For example, if <A>filt</A> is <C>IsTransformationSemigroup</C>, then the
    range of the returned isomorphism will be a transformation semigroup.
    <P/>

    An error is returned if there is no isomorphism from <A>S</A> to a
    semigroup satisfying <A>filt</A>. For example, there is no method for
    <C>IsomorphismSemigroup</C> when <A>filt</A> is, say, <Ref Prop =
      "IsReesMatrixSemigroup" BookName = "ref"/> and when <A>S</A> is a
    non-simple semigroup.  Similarly, there is no method when <A>filt</A> is
    <Ref Prop = "IsPartialPermSemigroup" BookName = "ref"/> and when <A>S</A> is
    a non-inverse semigroup. 
    <P/>

    In some cases, if no better method is installed, <C>IsomorphismSemigroup</C>
    returns an isomorphism found by composing an
    isomorphism from <A>S</A> to a transformation semigroup <C>T</C>, and an
    isomorphism from <C>T</C> to a semigroup of type <A>filt</A>.
    <P/>

    Note that if the argument <A>S</A> belongs to the category of monoids 
    <Ref Filt="IsMonoid" BookName="ref"/>, then <C>IsomorphismSemigroup</C>
    will often, but not always, return a monoid isomorphism. 

    <Example><![CDATA[
gap> S := Semigroup([
> Bipartition([
>   [1, 2], [3, 6, -2], [4, 5, -3, -4], [-1, -6], [-5]]),
> Bipartition([
>   [1, -4], [2, 3, 4, 5], [6], [-1, -6], [-2, -3], [-5]])]);
<bipartition semigroup of degree 6 with 2 generators>
gap> IsomorphismSemigroup(IsTransformationSemigroup, S);
MappingByFunction( <bipartition semigroup of size 11, degree 6 with 2 
 generators>, <transformation semigroup of size 11, degree 12 with 2 
 generators>, function( x ) ... end, function( x ) ... end )
gap> IsomorphismSemigroup(IsBooleanMatSemigroup, S);
MappingByFunction( <bipartition semigroup of size 11, degree 6 with 2 
 generators>, <semigroup of size 11, 12x12 boolean matrices with 2 
 generators>, function( x ) ... end, function( x ) ... end )
gap> IsomorphismSemigroup(IsFpSemigroup, S);
MappingByFunction( <bipartition semigroup of size 11, degree 6 with 2 
 generators>
 , <fp semigroup with 2 generators and 5 relations>, function( x ) ...\
 end, function( x ) ... end )
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> IsomorphismSemigroup(IsBipartitionSemigroup, S);
MappingByFunction( <inverse partial perm semigroup of rank 10 with 2 
 generators>, <inverse bipartition semigroup of degree 10 with 2 
 generators>, function( x ) ... end, <Operation "AsPartialPerm"> )
gap> S := SymmetricInverseMonoid(4);
<symmetric inverse monoid of degree 4>
gap> IsomorphismSemigroup(IsBlockBijectionSemigroup, S);
MappingByFunction( <symmetric inverse monoid of degree 4>, 
<inverse block bijection monoid of degree 5 with 3 generators>
 , function( x ) ... end, function( x ) ... end )
gap> Size(Range(last));
209
gap> S := Semigroup([
> PartialPerm([3, 1]), PartialPerm([1, 3, 4])]);;
gap> IsomorphismSemigroup(IsBlockBijectionSemigroup, S);
MappingByFunction( <partial perm semigroup of rank 3 with 2 
 generators>, <block bijection semigroup of degree 5 with 2 
 generators>, function( x ) ... end, function( x ) ... end )]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsSemigroup">
<ManSection>
  <Oper Name = "AsSemigroup" Arg = "filt, S"/>
  <Returns>A semigroup.</Returns>
  <Description>
    <C>AsSemigroup(<A>filt</A>, <A>S</A>)</C> is just shorthand for
    <C>Range(IsomorphismSemigroup(<A>filt</A>, <A>S</A>))</C>, when <A>S</A>
    is a semigroup; see <Ref Oper = "IsomorphismSemigroup"/> for more
    details.
    <P/>

    Note that if the argument <A>S</A> belongs to the category of monoids 
    <Ref Filt="IsMonoid" BookName="ref"/>, then <C>AsSemigroup</C> will often,
    but not always, return a monoid. A monoid is not returned if there is not a
    good monoid isomorphism from <A>S</A> to a monoid of the required
    type, but there is a good semigroup isomorphism.
    <P/>

    If it is not possible to convert the semigroup <A>S</A>
    to a semigroup of type <A>filt</A>, then an error is given.

    <Example><![CDATA[
gap> S := Semigroup([
> Bipartition([
>   [1, 2], [3, 6, -2], [4, 5, -3, -4], [-1, -6], [-5]]),
> Bipartition([
>   [1, -4], [2, 3, 4, 5], [6], [-1, -6], [-2, -3], [-5]])]);
<bipartition semigroup of degree 6 with 2 generators>
gap> AsSemigroup(IsTransformationSemigroup, S);
<transformation semigroup of size 11, degree 12 with 2 generators>
gap> S := Semigroup([
> Bipartition([
>   [1, 2], [3, 6, -2], [4, 5, -3, -4], [-1, -6], [-5]]),
> Bipartition([
>   [1, -4], [2, 3, 4, 5], [6], [-1, -6], [-2, -3], [-5]])]);
<bipartition semigroup of degree 6 with 2 generators>
gap> AsSemigroup(IsTransformationSemigroup, S);
<transformation semigroup of size 11, degree 12 with 2 generators>
gap> T := Semigroup(Transformation([2, 2, 3]),
>                   Transformation([3, 1, 3]));
<transformation semigroup of degree 3 with 2 generators>
gap> S := AsSemigroup(IsMatrixOverFiniteFieldSemigroup, GF(5), T);
<semigroup of 3x3 matrices over GF(5) with 2 generators>
gap> Size(S);
5]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsomorphismMonoid">
<ManSection>
  <Oper Name = "IsomorphismMonoid" Arg = "filt, S"/>
  <Returns>An isomorphism of monoids.</Returns>
  <Description>
    <C>IsomorphismMonoid</C> can be used to find an isomorphism from a given
    semigroup which is mathematically a monoid (but might not belong to the
    category of monoids in &GAP;) to a monoid, provided such an isomorphism
    exists. 
    <P/>

    The first argument <A>filt</A> must be of the form <C>IsXMonoid</C>, for
    example,
    <Ref Prop = "IsTransformationMonoid" BookName = "ref"/>,
    <Ref Prop = "IsFpMonoid" BookName = "ref"/>, and
    <Ref Filt = "IsBipartitionMonoid"/> are some possible values for <A>filt</A>. 
    Note that <A>filt</A> should not be of the form <C>IsXSemigroup</C>; see
    <Ref Oper = "IsomorphismSemigroup"/>. 
    The second argument <A>S</A> should be a semigroup which is mathematically
    a monoid but which may or may not belong to the category
    <Ref Filt="IsMonoid" BookName = "ref"/> of monoids in &GAP;,
    i.e. <A>S</A> must satisfy <Ref Prop="IsMonoidAsSemigroup"/>.
    <P/>

    <C>IsomorphismMonoid</C> returns a monoid isomorphism from <A>S</A> to a
    semigroup <A>T</A> of the type described by <A>filt</A>, if such an
    isomorphism exists. In this context, a <E>monoid isomorphism</E> is a
    semigroup isomorphism that maps the
    <Ref Meth = "MultiplicativeNeutralElement" BookName = "ref"/> of <A>S</A>
    to the <Ref Attr = "One" BookName = "ref"/> of <A>T</A>.
    If <C>T</C> is the range of the
    returned isomorphism, then <C><A>filt</A>(T)</C> will return <K>true</K>.
    For example, if <A>filt</A> is <C>IsTransformationMonoid</C>, then the
    range of the returned isomorphism will be a transformation monoid.
    <P/>

    An error is returned if there is no isomorphism from <A>S</A> to a monoid
    satisfying <A>filt</A>. For example, there is no method for
    <C>IsomorphismMonoid</C> when <A>filt</A> is, say,
    <Ref Prop = "IsReesZeroMatrixSemigroup" BookName = "ref"/> and when
    <A>S</A> is a not 0-simple.  Similarly, there is no method when <A>filt</A>
    is <Ref Prop = "IsPartialPermMonoid" BookName = "ref"/> and when
    <A>S</A> is a non-inverse monoid. 
    <P/>

    In some cases, if no better method is installed, <C>IsomorphismMonoid</C>
    returns an isomorphism found by composing an
    isomorphism from <A>S</A> to a transformation monoid <C>T</C>, and an
    isomorphism from <C>T</C> to a monoid of type <A>filt</A>.

    <Example><![CDATA[
gap> S := Semigroup(Transformation([1, 4, 6, 2, 5, 3, 7, 8, 9, 9]),
>                   Transformation([6, 3, 2, 7, 5, 1, 8, 8, 9, 9]));
<transformation semigroup of degree 10 with 2 generators>
gap> IsomorphismMonoid(IsTransformationMonoid, S);
MappingByFunction( <transformation semigroup of degree 10 with 2 
 generators>, <transformation monoid of degree 8 with 2 generators>
 , function( x ) ... end, function( x ) ... end )
gap> IsomorphismMonoid(IsBooleanMatMonoid, S);
MappingByFunction( <transformation semigroup of degree 10 with 2 
 generators>, <monoid of 8x8 boolean matrices with 2 generators>
 , function( x ) ... end, function( x ) ... end )
gap> IsomorphismMonoid(IsFpMonoid, S);
MappingByFunction( <transformation semigroup of degree 10 with 2 
 generators>
 , <fp monoid with 2 generators and 17 relations>, function( x ) ... e\
nd, function( x ) ... end )]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsMonoid">
<ManSection>
  <Oper Name = "AsMonoid" Arg = "[filt, ]S"/>
  <Returns>A monoid or <K>fail</K>.</Returns>
  <Description>
    <C>AsMonoid(<A>filt</A>, <A>S</A>)</C> is just shorthand for
    <C>Range(IsomorphismMonoid(<A>filt</A>, <A>S</A>))</C>, when <A>S</A>
    is a semigroup or monoid; see <Ref Oper = "IsomorphismMonoid"/> for more
    details.
    <P/>

    If the first argument <A>filt</A> is omitted and the semigroup <A>S</A>
    is mathematically a monoid which does not belong to the category of
    monoids in &GAP;, then <C>AsMonoid</C> returns a monoid (in the category
    of monoids) isomorphic to <A>S</A> and of the same type as <A>S</A>.
    If <A>S</A> is already in the category of monoids and the first argument
    <A>filt</A> is omitted, then <A>S</A> is returned. 
    <P/>

    If the first argument <A>filt</A> is omitted and the semigroup <A>S</A>
    is not a monoid, i.e. it does not satisfy <Ref
      Prop="IsMonoidAsSemigroup"/>, then <K>fail</K> is returned. 

    <Example><![CDATA[
gap> S := Semigroup(Transformation([1, 4, 6, 2, 5, 3, 7, 8, 9, 9]),
>                   Transformation([6, 3, 2, 7, 5, 1, 8, 8, 9, 9]));;
gap> AsMonoid(S);
<transformation monoid of degree 8 with 2 generators>
gap> AsSemigroup(IsBooleanMatSemigroup, S);
<semigroup of 10x10 boolean matrices with 2 generators>
gap> AsMonoid(IsBooleanMatMonoid, S);
<monoid of 8x8 boolean matrices with 2 generators>
gap> S := Monoid(Bipartition([[1, -1, -3], [2, 3], [-2]]),
>                Bipartition([[1, -1], [2, 3, -3], [-2]]));
<bipartition monoid of degree 3 with 2 generators>
gap> AsMonoid(IsTransformationMonoid, S);
<transformation monoid of size 3, degree 3 with 2 generators>
gap> AsMonoid(S);
<bipartition monoid of size 3, degree 3 with 2 generators>]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomSemigroup">
<ManSection>
  <Func Name = "RandomSemigroup" Arg = "arg..."/>
  <Func Name = "RandomMonoid" Arg = "arg..."/>
  <Func Name = "RandomInverseSemigroup" Arg = "arg..."/>
  <Func Name = "RandomInverseMonoid" Arg = "arg..."/>
  <Returns>A semigroup.</Returns>
  <Description>
    The operations described in this section can be used to generate
    semigroups, in some sense, at random. There is no guarantee given about
    the distribution of these semigroups, and this is only intended as a means
    of generating semigroups for testing and other similar purposes.
    <P/>

    Roughly speaking, the arguments of <C>RandomSemigroup</C> are a filter
    specifying the type of the semigroup to be returned, together with some
    further parameters that describe some attributes of the semigroup to be
    returned. For instance, we may want to specify the number of generators,
    and, say, the degree, or dimension, of the elements, where appropriate.
    The arguments of <C>RandomMonoid</C>, <C>RandomInverseSemigroup</C>, and
    <C>RandomInverseMonoid</C> are analogous.
    <P/>

    If no arguments are specified, then they are all chosen at random, for a
    truly random experience.
    <P/>
 
    The first argument, if present, should be a filter <A>filter</A>.  For
    <C>RandomSemigroup</C> and <C>RandomInverseSemigroup</C> the filter
    <A>filter</A> must be of the form <C>IsXSemigroup</C>. For example,
    <Ref Prop = "IsTransformationSemigroup" BookName = "ref"/>,
    <Ref Prop = "IsFpSemigroup" BookName = "ref"/>, and
    <Ref Filt = "IsPBRSemigroup"/> are some possible values for <A>filter</A>.
    For <C>RandomMonoid</C> and <C>RandomInverseMonoid</C> the argument
    <A>filter</A>  must be of the form <C>IsXMonoid</C>; such as <Ref Prop =
      "IsBipartitionMonoid"/> or <Ref Filt = "IsBooleanMatMonoid"/>.
    <P/>

    Suppose that the first argument <A>filter</A> is <Ref Prop="IsFpSemigroup"
      BookName = "ref"/>. Then the only other arguments that can be specified
    is (and this argument is also optional):
    <List>
      <Mark>number of generators</Mark>
      <Item>
        The second argument, if present, should be a positive integer <A>m</A>
        indicating the number of generators that the semigroup should have.
        If the second argument <A>m</A> is not specified, then a number is
        selected at random.
      </Item>
    </List>

    If <A>filter</A> is a filter such as <Ref
      Filt="IsTransformationSemigroup" BookName = "ref"/> or <Ref
      Filt="IsIntegerMatrixSemigroup"/>, <!-- or <Ref
      Filt="IsProjectiveMaxPlusMatrix"/>, -->
    then a further argument can be specified:
    <List>
      <Mark>degree / dimension</Mark>
      <Item>
        The third argument, if present, should be a positive integer <A>n</A>,
        which specifies the degree or dimension of the generators. For example,
        if the first argument <A>filter</A> is <C>IsTransformationSemigroup</C>,
        then the value of this argument is the degree of the transformations in
        the returned semigroup; or if <A>filter</A> is
        <C>IsMatrixOverFiniteFieldSemigroup</C>, then this argument is the
        dimension of the matrices in the returned semigroup.
      </Item>
    </List>

    If <A>filter</A> is <Ref Filt="IsTropicalMaxPlusMatrixSemigroup"/>, for
    example,  then a fourth argument can be given (or not!):
    <List>
      <Mark>threshold</Mark>
      <Item>
        The fourth argument, if present, should be a positive integer <A>t</A>,
        which specifies the threshold of the semiring over which the matrices
        in the returned semigroup are defined. 
      </Item>
    </List>
 
    You get the idea, the error messages are self-explanatory, and
    <C>RandomSemigroup</C> works for most of the type of semigroups defined in
    &GAP;.<P/>

    <C>RandomMonoid</C> is similar to <C>RandomSemigroup</C> except it returns
    a monoid. Likewise, <C>RandomInverseSemigroup</C> and
    <C>RandomInverseMonoid</C> return inverse semigroups and monoids, respectively.

    <Log><![CDATA[
gap> RandomSemigroup();
<semigroup of 10x10 max-plus matrices with 12 generators>
gap> RandomMonoid(IsTransformationMonoid);
<transformation monoid of degree 9 with 7 generators>
gap> RandomMonoid(IsPartialPermMonoid, 2);
<partial perm monoid of rank 17 with 2 generators>
gap> RandomMonoid(IsPartialPermMonoid, 2, 3);
<partial perm monoid of rank 3 with 2 generators>
gap> RandomInverseSemigroup(IsTropicalMinPlusMatrixSemigroup);
<semigroup of 6x6 tropical min-plus matrices with 14 generators>
gap> RandomInverseSemigroup(IsTropicalMinPlusMatrixSemigroup, 1);
<semigroup of 6x6 tropical min-plus matrices with 14 generators>
gap> RandomSemigroup(IsTropicalMinPlusMatrixSemigroup, 2);
<semigroup of 11x11 tropical min-plus matrices with 2 generators>
gap> RandomSemigroup(IsTropicalMinPlusMatrixSemigroup, 2, 1);
<semigroup of 1x1 tropical min-plus matrices with 2 generators>
gap> RandomSemigroup(IsTropicalMinPlusMatrixSemigroup, 2, 1, 3);
gap> last.1;
Matrix(IsTropicalMinPlusMatrix, [[infinity]], 3)
gap> RandomSemigroup(IsNTPMatrixSemigroup, 2, 1, 3, 4);
<semigroup of 1x1 ntp matrices with 2 generators>
gap> last.1;
Matrix(IsNTPMatrix, [[2]], 3, 4)
gap> RandomSemigroup(IsReesMatrixSemigroup, 2, 2);
<Rees matrix semigroup 2x2 over
  <permutation group of size 659 with 1 generator>>
gap> RandomSemigroup(IsReesZeroMatrixSemigroup, 2, 2, Group((1, 2), (3, 4)));
<Rees 0-matrix semigroup 2x2 over Group([ (1,2), (3,4) ])>
gap> RandomInverseMonoid(IsMatrixOverFiniteFieldMonoid, 2, 2);
<monoid of 3x3 matrices over GF(421^4) with 3 generators>
gap> RandomInverseMonoid(IsMatrixOverFiniteFieldMonoid, 2, 2, GF(7));
<monoid of 3x3 matrices over GF(7) with 2 generators>
gap> RandomSemigroup(IsBipartitionSemigroup, 5, 5);
<bipartition semigroup of degree 5 with 5 generators>
gap> RandomMonoid(IsBipartitionMonoid, 5, 5);
<bipartition monoid of degree 5 with 5 generators>
gap> RandomSemigroup(IsBooleanMatSemigroup);
<semigroup of 3x3 boolean matrices with 18 generators>
gap> RandomMonoid(IsBooleanMatMonoid);
<monoid of 11x11 boolean matrices with 19 generators>]]></Log> 
  </Description>
</ManSection>
<#/GAPDoc>
  <Oper Name = "RandomMonoid" Arg = "arg..."/>
  <Oper Name = "RandomInverseSemigroup" Arg = "arg..."/>
  <Oper Name = "RandomInverseMonoid" Arg = "arg..."/>
