#############################################################################
##
#W  constructions.xml
#Y  Copyright (C) 2015                                   James D. Mitchell
##                                                          Wilf A. Wilson
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

<#GAPDoc Label="TrivialSemigroup">
  <ManSection>
    <Func Name="TrivialSemigroup" Arg="[filt, ][deg]"/>
    <Returns>
      A trivial semigroup.
    </Returns>
      <Description>
        A <B>trivial</B> semigroup is a semigroup with precisely one element.
        This function returns a trivial semigroup in the representation given
        by the filter <A>filter</A>, and (if possible) with the degree of the
        representation given by the non-negative integer <A>deg</A>.
        <P/>

        The optional argument <A>filt</A> may be one of the following:

        <List>
          <Item><C>IsTransformationSemigroup</C>
            (the default, if <A>filt</A> is not specified),</Item>
          <Item><C>IsPartialPermSemigroup</C>,</Item>
          <Item><C>IsBipartitionSemigroup</C>,</Item>
          <Item><C>IsBlockBijectionSemigroup</C>,</Item>
          <Item><C>IsPBRSemigroup</C>,</Item>
          <Item><C>IsBooleanMatSemigroup</C>.</Item>
        </List>

        If the optional argument <A>deg</A> is not specified, then the smallest
        possible degree will be used.
        <P/>
        <Example><![CDATA[
gap> S := TrivialSemigroup();
<trivial transformation group of degree 0 with 1 generator>
gap> Size(S);
1
gap> S := TrivialSemigroup(3);
<trivial transformation group of degree 3 with 1 generator>
gap> S := TrivialSemigroup(IsBipartitionSemigroup, 2);
<trivial block bijection group of degree 2 with 1 generator>
gap> Elements(S);
[ <block bijection: [ 1, 2, -1, -2 ]> ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="MonogenicSemigroup">
  <ManSection>
    <Func Name="MonogenicSemigroup" Arg="[filt, ]m, r"/>
    <Returns>
      A monogenic semigroup with index <A>m</A> and period <A>r</A>.
    </Returns>
      <Description>
        If <A>m</A> and <A>r</A> are positive integers,
        then this function returns a monogenic semigroup
        <C>S</C> with index <A>m</A> and period <A>r</A>
        in the representation given by the filter <A>filt</A>.
        <P/>

        The optional argument <A>filt</A> may be one of the following:

        <List>
          <Item><C>IsTransformationSemigroup</C>
            (the default, if <A>filt</A> is not specified),</Item>
          <Item><C>IsPartialPermSemigroup</C>,</Item>
          <Item><C>IsBipartitionSemigroup</C>,</Item>
          <Item><C>IsBlockBijectionSemigroup</C>,</Item>
          <Item><C>IsPBRSemigroup</C>,</Item>
          <Item><C>IsBooleanMatSemigroup</C>.</Item>
        </List>

        The semigroup <C>S</C> is generated by a single element, <M>f</M>.
        <C>S</C> consists of the elements
        <M>f, f ^ {2}, \ldots, f ^ {m}, \ldots, f ^ {m + r - 1}</M>.
        The minimal ideal of <C>S</C> consists of the elements
        <M>f ^ {m}, \ldots, f ^ {m + r - 1}</M>
        and is isomorphic to the cyclic group of order <M>r</M>.
        <P/>

        See <Ref Prop="IsMonogenicSemigroup"/> for more information
        about monogenic semigroups.

        <Example><![CDATA[
gap> S := MonogenicSemigroup(5, 3);
<commutative non-regular transformation semigroup of size 7, degree 8
 with 1 generator>
gap> IsMonogenicSemigroup(S);
true
gap> I := MinimalIdeal(S);;
gap> IsGroupAsSemigroup(I);
true
gap> StructureDescription(I);
"C3"
gap> S := MonogenicSemigroup(IsBlockBijectionSemigroup, 9, 1);
<commutative non-regular block bijection semigroup of size 9,
 degree 10 with 1 generator>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RectangularBand">
  <ManSection>
    <Func Name="RectangularBand" Arg="[filt, ]m, n"/>
    <Returns>
      An <A>m</A> by <A>n</A> rectangular band.
    </Returns>
      <Description>
        If <A>m</A> and <A>n</A> are positive integers,
        then this function returns a semigroup isomorphic to an <A>m</A>
        by <A>n</A> rectangular band, in the representation given by
        the filter <A>filt</A>. <P/>

        The optional argument <A>filt</A> may be one of the following:
        <List>
          <Item><C>IsTransformationSemigroup</C>
            (the default, if <A>filt</A> is not specified),</Item>
          <Item><C>IsBipartitionSemigroup</C>,</Item>
          <Item><C>IsPBRSemigroup</C>,</Item>
          <Item><C>IsBooleanMatSemigroup</C>,</Item>
          <Item><C>IsReesMatrixSemigroup</C>.</Item>
        </List>

        See <Ref Prop="IsRectangularBand"/> for more information about
        rectangular bands.

        <Example><![CDATA[
gap> T := RectangularBand(5, 6);
<regular transformation semigroup of size 30, degree 10 with 6
 generators>
gap> IsRectangularBand(T);
true
gap> S := RectangularBand(IsReesMatrixSemigroup, 4, 8);
<Rees matrix semigroup 4x8 over Group(())>
gap> IsRectangularBand(S);
true
gap> IsCompletelySimpleSemigroup(S) and IsHTrivial(S);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="FreeSemilattice">
  <ManSection>
    <Func Name="FreeSemilattice" Arg="[filt, ] n"/>
    <Returns>
      A free semilattice with <A>n</A> generators.
    </Returns>
    <Description>
      If <A>n</A> is a positive integer, then this function returns a free
      semilattice with <A>n</A> generators in the representation given by the
      filter <A>filt</A>.

      The optional argument <A>filt</A> may be one of the following:
      <List>
        <Item><C>IsTransformationSemigroup</C>
          (the default, if <A>filt</A> is not specified),</Item>
        <Item><C>IsTransformationMonoid</C>,</Item>
        <Item><C>IsPartialPermSemigroup</C>,</Item>
        <Item><C>IsPartialPermMonoid</C>,</Item>
        <Item><C>IsFpSemigroup</C>,</Item>
        <Item><C>IsFpMonoid</C>,</Item>
        <Item><C>IsBipartitionSemigroup</C>,</Item>
        <Item><C>IsBipartitionMonoid</C>,</Item>
        <Item><C>IsPBRSemigroup</C>,</Item>
        <Item><C>IsPBRMonoid</C>,</Item>
        <Item><C>IsBooleanMatSemigroup</C>,</Item>
        <Item><C>IsBooleanMatMonoid</C>,</Item>
        <Item><C>IsNTPMatrixSemigroup</C>,</Item>
        <Item><C>IsNTPMatrixMonoid</C>,</Item>
        <Item><C>IsMaxPlusMatrixSemigroup</C>,</Item>
        <Item><C>IsMaxPlusMatrixMonoid</C>,</Item>
        <Item><C>IsMinPlusMatrixSemigroup</C>,</Item>
        <Item><C>IsMinPlusMatrixMonoid</C>,</Item>
        <Item><C>IsTropicalMaxPlusMatrixSemigroup</C>,</Item>
        <Item><C>IsTropicalMaxPlusMatrixMonoid</C>,</Item>
        <Item><C>IsTropicalMinPlusMatrixSemigroup</C>,</Item>
        <Item><C>IsTropicalMinPlusMatrixMonoid</C>,</Item>
        <Item><C>IsProjectiveMaxPlusMatrixSemigroup</C>,</Item>
        <Item><C>IsProjectiveMaxPlusMatrixMonoid</C>,</Item>
        <Item><C>IsIntegerMatrixSemigroup.</C></Item>
        <Item><C>IsIntegerMatrixMonoid.</C></Item>
      </List>

      <Example><![CDATA[
gap> S := FreeSemilattice(IsTransformationSemigroup, 5);
<inverse transformation semigroup of size 31, degree 6 with 5 
 generators>
gap> T := FreeSemilattice(IsPartialPermSemigroup, 3);
<inverse partial perm semigroup of size 7, rank 3 with 3 generators>
gap> U := FreeSemilattice(IsBooleanMatSemigroup, 4);
<inverse semigroup of size 15, 5x5 boolean matrices with 4 generators>
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="ZeroSemigroup">
  <ManSection>
    <Func Name="ZeroSemigroup" Arg="[filt, ]n"/>
    <Returns>
      A zero semigroup of order <A>n</A>.
    </Returns>
      <Description>
        If <A>n</A> is a positive integer, then this function returns a zero
        semigroup of order <A>n</A> in the representation given by the filter
        <A>filt</A>. <P/>

        The optional argument <A>filt</A> may be one of the following:

        <List>
          <Item><C>IsTransformationSemigroup</C>
            (the default, if <A>filt</A> is not specified),</Item>
          <Item><C>IsPartialPermSemigroup</C>,</Item>
          <Item><C>IsBipartitionSemigroup</C>,</Item>
          <Item><C>IsBlockBijectionSemigroup</C>,</Item>
          <Item><C>IsPBRSemigroup</C>,</Item>
          <Item><C>IsBooleanMatSemigroup</C>,</Item>
          <Item><C>IsReesZeroMatrixSemigroup</C>
            (provided that <C><A>n</A> &gt; 1</C>).</Item>
        </List>

        See <Ref Prop="IsZeroSemigroup"/> for more information about zero
        semigroups.

        <Example><![CDATA[
gap> S := ZeroSemigroup(5);
<commutative non-regular transformation semigroup of size 5, degree 5
 with 4 generators>
gap> IsZeroSemigroup(S);
true
gap> S := ZeroSemigroup(IsPartialPermSemigroup, 15);
<commutative non-regular partial perm semigroup of size 15, rank 14
 with 14 generators>
gap> Size(S);
15
gap> z := MultiplicativeZero(S);
<empty partial perm>
gap> IsZeroSemigroup(S);
true
gap> ForAll(S, x -> ForAll(S, y -> x * y = z));
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="BrandtSemigroup">
  <ManSection>
    <Func Name="BrandtSemigroup" Arg="[[filt, ]G, ]n"/>
    <Returns>
      An <A>n</A> by <A>n</A> Brandt semigroup over the group <A>G</A>.
    </Returns>
      <Description>
        If <A>n</A> is a positive integer, then this function returns an
        <A>n</A> by <A>n</A> Brandt semigroup over the group <A>G</A>
        in the representation given by the filter <A>filt</A>. <P/>

        The optional argument <A>filt</A> can be any of the following:
        <List>
          <Item><C>IsPartialPermSemigroup</C>
            (the default, if <A>filt</A> is not specified),</Item>
          <Item><C>IsReesZeroMatrixSemigroup</C>,</Item>
          <Item><C>IsTransformationSemigroup</C>,</Item>
          <Item><C>IsBipartitionSemigroup</C>,</Item>
          <Item><C>IsPBRSemigroup</C>,</Item>
          <Item><C>IsBooleanMatSemigroup</C>,</Item>
          <Item><C>IsNTPMatrixSemigroup</C>,</Item>
          <Item><C>IsMaxPlusMatrixSemigroup</C>,</Item>
          <Item><C>IsMinPlusMatrixSemigroup</C>,</Item>
          <Item><C>IsTropicalMaxPlusMatrixSemigroup</C>,</Item>
          <Item><C>IsTropicalMinPlusMatrixSemigroup</C>,</Item>
          <Item><C>IsProjectiveMaxPlusMatrixSemigroup</C>,</Item>
          <Item><C>IsIntegerMatrixSemigroup.</C></Item>
        </List>

        The optional argument <A>G</A> defaults to a trivial permutation group.
        If present <A>G</A> must be a permutation group, unless <A>filt</A> is
        <C>IsReesZeroMatrixSemigroup</C> when <A>G</A> may be any type of
        finite group.
        <P/>

        See <Ref Prop="IsBrandtSemigroup"/> for more information about Brandt
        semigroups.

        <Example><![CDATA[
gap> S := BrandtSemigroup(5);
<0-simple inverse partial perm semigroup of rank 5 with 4 generators>
gap> IsBrandtSemigroup(S);
true
gap> S := BrandtSemigroup(IsTransformationSemigroup, 15);
<0-simple transformation semigroup of degree 16 with 28 generators>
gap> Size(S);
226
gap> MultiplicativeZero(S);
Transformation( [ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16 ] )
gap> S := BrandtSemigroup(Group((1, 2)), 3);
<0-simple inverse partial perm semigroup of rank 6 with 3 generators>
gap> S := BrandtSemigroup(IsTransformationSemigroup, Group((1, 2)), 3);
<0-simple transformation semigroup of degree 7 with 5 generators>
gap> S := BrandtSemigroup(IsReesZeroMatrixSemigroup,
>                         DihedralGroup(4),
>                         2);
<Rees 0-matrix semigroup 2x2 over <pc group of size 4 with
 2 generators>>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="LeftZeroSemigroup">
  <ManSection>
    <Func Name="LeftZeroSemigroup" Arg="[filt, ]n"/>
    <Func Name="RightZeroSemigroup" Arg="[filt, ]n"/>
    <Returns>
      A left zero (or right zero) semigroup of order <A>n</A>.
    </Returns>
    <Description>
        If <A>n</A> is a positive integer, then this function returns a left
        zero (or right zero, as appropriate) semigroup of order <A>n</A> in the
        representation given by the filter <A>filt</A>.
        If <A>filt</A> is not specified then the default representation is
        <C>IsTransformationSemigroup</C>. <P/>

        The function <C>LeftZeroSemigroup([<A>filt</A>,] <A>n</A>)</C> simply
        calls <C>RectangularBand([<A>filt</A>,] <A>n</A>, 1)</C> and
        the function <C>RightZeroSemigroup([<A>filt</A>,] <A>n</A>)</C> simply
        calls <C>RectangularBand([<A>filt</A>,] 1, <A>n</A>)</C>. <P/>

        For more information about <C>RectangularBand</C>, including its
        permitted values of <A>filt</A>, see <Ref Func="RectangularBand"/>.

        See <Ref Prop="IsLeftZeroSemigroup"/> and <Ref
          Prop="IsRightZeroSemigroup"/> for more information about left zero
        and right zero semigroups.

        <Example><![CDATA[
gap> S := LeftZeroSemigroup(20);
<transformation semigroup of degree 6 with 20 generators>
gap> IsLeftZeroSemigroup(S);
true
gap> ForAll(Tuples(S, 2), p -> p[1] * p[2] = p[1]);
true
gap> S := RightZeroSemigroup(IsBipartitionSemigroup, 5);
<regular bipartition semigroup of size 5, degree 3 with 5 generators>
gap> IsRightZeroSemigroup(S);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="StrongSemilatticeOfSemigroups">
  <ManSection>
    <Oper Name="StrongSemilatticeOfSemigroups" Arg="D, L, H"/>
    <Returns>
      A strong semilattice of semigroups.
    </Returns>
    <Description>
      If <A>D</A> is a digraph, <A>L</A> is a list of semigroups, and <A>H</A>
      is a list of lists of maps, then this function returns a corresponding
      <C>IsStrongSemilatticeOfSemigroups</C> object. The format
      of the arguments is not required to be exactly analogous to Howie's
      description above, but consistency amongst the arguments is required:
      <List>
        <Item>
          <A>D</A> must be a digraph whose
          <Ref Oper="DigraphReflexiveTransitiveClosure" BookName="Digraphs"/>
          is a meet-semilattice. For
          example, <C>Digraph([2, 3], [4], [4], []])</C> is valid and produces
          a semilattice where the meet of <C>2</C> and <C>3</C> is <C>1</C>.
          See <Ref Prop="IsMeetSemilatticeDigraph" BookName="Digraphs"/>.
        </Item>
        <Item>
          <A>L</A> must contain as many semigroups as there are vertices in
          <A>D</A>.
        </Item>
        <Item>
          <A>H</A> must be a list with as many elements as there are vertices
          in <A>D</A>. Each element of <A>H</A> must itself be a (possibly
          empty) list with as many entries as the corresponding vertex of
          <A>D</A> has out-edges. The entries of each sublist must be the
          corresponding homomorphisms: for example, if <A>D</A> is entered as
          above, then <C>H[1][2]</C> must be the homomorphism <M>f_31</M>, i.e.
          <C>H[1][2]</C> is an <C>IsMapping</C> object whose domain is a
          superset of <C>L[3]</C> and whose range is a subset of <C>L[1]</C>.
        </Item>
      </List>
      Note that in the example above, the edge <M>1 \rightarrow 4</M> is not
      entered as part of the argument <A>D</A>, but it is still an edge in the
      reflexive transitive closure of <A>D</A>. When creating the object, &GAP;
      creates the homomorphism <M>f_{41}</M> by composing the mappings along
      paths that lead from 4 to 1, and checks that composing along all possible
      paths produces the same result.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsStrongSemilatticeOfSemigroups">
  <ManSection>
    <Filt Name="IsStrongSemilatticeOfSemigroups" Arg="obj"/>
    <Returns>
      <K>true</K> or <K>false</K>.
    </Returns>
    <Description>
      Every Strong Semilattice of Semigroups in &GAP; belongs to the category
      <C>IsStrongSemilatticeOfSemigroups</C>. Basic operations in this category
      allow the user to recover the three essential elements of an SSS object:
      <Ref Attr="SemilatticeOfStrongSemilatticeOfSemigroups"/>,
      <Ref Attr="SemigroupsOfStrongSemilatticeOfSemigroups"/>, and
      <Ref Attr="HomomorphismsOfStrongSemilatticeOfSemigroups"/>.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SemilatticeOfStrongSemilatticeOfSemigroups">
  <ManSection>
    <Attr Name="SemilatticeOfStrongSemilatticeOfSemigroups" Arg="SSS"/>
    <Returns>
      A meet-semilattice digraph.
    </Returns>
    <Description>
      If <A>SSS</A> is a strong semilattice of semigroups, this function
      returns the underlying semilattice structure as a digraph.
      Note that this may not be equal to the digraph passed as input
      when <A>SSS</A> was created: rather, it is the reflexive transitive
      closure of the input digraph.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="UnderlyingSemilatticeOfSemigroups">
  <ManSection>
    <Oper Name="UnderlyingSemilatticeOfSemigroups" Arg="el"/>
    <Returns>
      A strong semilattice of semigroups.
    </Returns>
    <Description>
      If <A>el</A> is an element of a strong semilattice of semigroups (i.e.
      is in the category <Ref Filt="IsSSSE"/>), then this operation returns
      the strong semilattice of semigroups object that <A>el</A> belongs to.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SemigroupsOfStrongSemilatticeOfSemigroups">
  <ManSection>
    <Attr Name="SemigroupsOfStrongSemilatticeOfSemigroups" Arg="SSS"/>
    <Returns>
      A list of semigroups.
    </Returns>
    <Description>
      If <A>SSS</A> is a strong semilattice of semigroups, this function
      returns the list of semigroups that make up <A>SSS</A>. The position of
      a semigroup in the list corresponds to the node of the semilattice where
      that semigroup lies.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="HomomorphismsOfStrongSemilatticeOfSemigroups">
  <ManSection>
    <Attr Name="HomomorphismsOfStrongSemilatticeOfSemigroups" Arg="SSS"/>
    <Returns>
      A list of lists of mappings.
    </Returns>
    <Description>
      If <A>SSS</A> is a strong semilattice of <M>n</M> semigroups, this
      function returns an <M>n \times n</M> list where the <M>(i, j)</M>th
      entry of the list is the homomorphism <M>f_{ji}</M>, provided
      <M>i \leq j</M> in the semilattice. If this last condition is not true,
      then the entry is <K>fail</K>.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsSSSE">
  <ManSection>
    <Filt Name="IsSSSE" Arg="obj"/>
    <Returns>
      <K>true</K> or <K>false</K>.
    </Returns>
    <Description>
      All elements of an SSS belong in the category <C>IsSSSE</C> (for "Strong
      Semilattice of Semigroups Element").
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SSSE">
  <ManSection>
    <Oper Name="SSSE" Arg="SSS, n, x"/>
    <Returns>
      An element of a strong semilattice of semigroups.
    </Returns>
    <Description>
      If <A>n</A> is a vertex of the underlying semilattice of the strong
      semilattice of semigroups <A>SSS</A>, and if <A>x</A> is an
      element of the <A>n</A>th semigroup of <A>SSS</A>, then this function
      returns the element of <A>SSS</A> which lies in semigroup number <A>n</A>
      and which corresponds to the element <A>x</A> in that semigroup.
      <P/>
      This function returns an <Ref Filt="IsSSSE"/> object. SSSEs from the
      same strong semilattice of semigroups can be compared and multiplied.
      <Example><![CDATA[
gap> D := Digraph([[2, 3], [4], [4], []]);;
gap> S4 := FullTransformationMonoid(2);;
gap> S3 := FullTransformationMonoid(3);;
gap> pairs := [[Transformation([1, 2]), Transformation([2, 1])]];;
gap> cong := SemigroupCongruence(S4, pairs);;
gap> S2 := S4 / cong;;
gap> S1 := TrivialSemigroup();;
gap> L := [S1, S2, S3, S4];;
gap> idfn := t -> IdentityTransformation;;
gap> f21 := SemigroupHomomorphismByFunction(S2, S1, idfn);;
gap> f31 := SemigroupHomomorphismByFunction(S3, S1, idfn);;
gap> f42 := HomomorphismQuotientSemigroup(cong);;
gap> f43 := SemigroupHomomorphismByFunction(S4, S3, IdFunc);;
gap> H := [[f21, f31], [f42], [f43], []];;
gap> SSS := StrongSemilatticeOfSemigroups(D, L, H);
<strong semilattice of 4 semigroups>
gap> Size(SSS);
34
gap> x := SSSE(SSS, 3, Elements(S3)[10]);
SSSE(3, Transformation( [ 2, 1, 1 ] ))
gap> y := SSSE(SSS, 4, Elements(S4)[1]);
SSSE(4, Transformation( [ 1, 1 ] ))
gap> x * y;
SSSE(3, Transformation( [ 1, 1, 1 ] ))]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>
