#############################################################################
##
#W  froidure-pin.xml
#Y  Copyright (C) 2017-2022                                 Michael Young
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

<#GAPDoc Label="CanUseFroidurePin">
  <ManSection>
    <Prop Name = "CanUseFroidurePin" Arg = "obj"/>
    <Prop Name = "CanUseGapFroidurePin" Arg = "obj"/>
    <Prop Name = "CanUseLibsemigroupsFroidurePin" Arg = "obj"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      Every semigroup satisfying <C>CanUseFroidurePin</C> is a valid input
      for the Froidure-Pin algorithm; see Section <Ref Subsect="FroidurePin"/>
      for more details.<P/>

      Basic operations for semigroups satisfying <C>CanUseFroidurePin</C> are:
      <Ref Attr="AsListCanonical"/>, 
      <Ref Attr="EnumeratorCanonical"/>, 
      <Ref Oper="IteratorCanonical"/>,
      <Ref Oper="PositionCanonical"/>,
      <Ref Oper="Enumerate"/>, and
      <Ref Oper="IsEnumerated"/>.
      <!-- TODO(later) more! -->

      <Example><![CDATA[
gap> S := Semigroup(Transformation([1, 3, 2]));;
gap> CanUseFroidurePin(S);
true
gap> S := FreeSemigroup(3);;
gap> CanUseFroidurePin(S);
false
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsListCanonical">
  <ManSection>
    <Attr Name="AsListCanonical" Arg="S"/> 
    <Attr Name="EnumeratorCanonical" Arg="S"/>
    <Oper Name="IteratorCanonical" Arg="S"/>
    <Returns>A list, enumerator, or iterator.</Returns>
    <Description>
      When the argument <A>S</A> is a semigroup satisfying 
      <Ref Prop="CanUseFroidurePin"/>, <C>AsListCanonical</C>
      returns a list of the elements of <A>S</A> in the order they are
      enumerated by the Froidure-Pin Algorithm. This is the same as the order
      used to index the elements of <A>S</A> in <Ref
        Attr="RightCayleyDigraph"/> and <Ref
        Attr="LeftCayleyDigraph"/>. <P/>

      <C>EnumeratorCanonical</C> and <C>IteratorCanonical</C> return an
      enumerator and an iterator where the elements are
      ordered in the same way as <C>AsListCanonical</C>. Using
      <C>EnumeratorCanonical</C> or <C>IteratorCanonical</C> will often use
      less memory than <C>AsListCanonical</C>, but may have slightly worse
      performance if the elements of the semigroup are looped over repeatedly.
      <C>EnumeratorCanonical</C> returns the same list as
      <C>AsListCanonical</C> if <C>AsListCanonical</C> has ever been called for
      <A>S</A>.<P/>

      If <A>S</A> is an acting semigroup, then the value returned by
      <C>AsList</C> may not equal the value returned by <C>AsListCanonical</C>.
      <C>AsListCanonical</C> exists so that there is a method for obtaining the
      elements of <A>S</A> in the particular order used by 
      <Ref Attr="RightCayleyDigraph"/> and 
      <Ref Attr="LeftCayleyDigraph"/>.<P/>

      See also <Ref Oper="PositionCanonical"/>.

      <Example><![CDATA[
gap> S := Semigroup(Transformation([1, 3, 2]));;
gap> AsListCanonical(S);
[ Transformation( [ 1, 3, 2 ] ), IdentityTransformation ]
gap> IteratorCanonical(S);
<iterator>
gap> EnumeratorCanonical(S);
[ Transformation( [ 1, 3, 2 ] ), IdentityTransformation ]
gap> S := Monoid([Matrix(IsBooleanMat, [[1, 0, 0],
>                                       [0, 1, 0],
>                                       [0, 1, 0]])]);
<commutative monoid of 3x3 boolean matrices with 1 generator>
gap> it := IteratorCanonical(S);
<iterator>
gap> NextIterator(it);
Matrix(IsBooleanMat, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
gap> en := EnumeratorCanonical(S);
<enumerator of <commutative monoid of size 2, 3x3 boolean matrices 
 with 1 generator>>
gap> en[1];
Matrix(IsBooleanMat, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
gap> Position(en, en[1]);
1
gap> Length(en);
2]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="Enumerate">
  <ManSection>
    <Oper Name="Enumerate" Arg="S[, limit]"/> 
    <Returns>A semigroup (the argument).</Returns>
    <Description>
      If <A>S</A> is a semigroup with representation 
      <Ref Prop="CanUseFroidurePin"/> and <A>limit</A> is a positive
      integer, then this operation can be used to enumerate at least
      <A>limit</A> elements of <A>S</A>, or <C>Size(<A>S</A>)</C> elements if
      this is less than <A>limit</A>, using the Froidure-Pin Algorithm. <P/>

      If the optional second argument <A>limit</A> is not given, then the
      semigroup is enumerated until all of its elements have been found. <P/>

      <Example><![CDATA[
gap> S := FullTransformationMonoid(7);
<full transformation monoid of degree 7>
gap> Enumerate(S, 1000);
<full transformation monoid of degree 7>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsEnumerated">
  <ManSection>
    <Oper Name="IsEnumerated" Arg="S"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      If <A>S</A> is a semigroup with representation
      <Ref Prop="CanUseFroidurePin"/>, then this operation returns
      <K>true</K> if the Froidure-Pin Algorithm has been run to completion
      (i.e. all of the elements of <A>S</A> have been found) and <K>false</K>
      if <A>S</A> has not been fully enumerated.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="PositionCanonical">
  <ManSection>
    <Oper Name="PositionCanonical" Arg="S, x"/>
    <Returns>A positive integer or <K>fail</K>.</Returns>
    <Description>
      When the argument <A>S</A> is a semigroup satisfying
      <Ref Prop="CanUseFroidurePin"/> and <A>x</A> is an element of
      <A>S</A>, <C>PositionCanonical</C>
      returns the position of <A>x</A> in <C>AsListCanonical(<A>S</A>)</C> or
      equivalently the position of <A>x</A> in
      <C>EnumeratorCanonical(<A>S</A>)</C>.<P/>

      See also <Ref Attr="AsListCanonical"/> and
      <Ref Attr="EnumeratorCanonical"/>.
      <Example><![CDATA[
gap> S := FullTropicalMaxPlusMonoid(2, 3);
<monoid of 2x2 tropical max-plus matrices with 13 generators>
gap> x := Matrix(IsTropicalMaxPlusMatrix, [[1, 3], [2, 1]], 3);
Matrix(IsTropicalMaxPlusMatrix, [[1, 3], [2, 1]], 3)
gap> PositionCanonical(S, x);
234
gap> EnumeratorCanonical(S)[234] = x;
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RightCayleyDigraph">
  <ManSection>
    <Attr Name="RightCayleyDigraph" Arg="S"/>
    <Attr Name="LeftCayleyDigraph" Arg="S"/>
    <Returns>A digraph.</Returns>
    <Description>
      When the argument <A>S</A> is a semigroup satisfying
      <Ref Prop="CanUseFroidurePin"/>,
      <C>RightCayleyDigraph</C> returns the right
      Cayley graph of <A>S</A>, as a <Ref Oper="Digraph" BookName="digraphs"/>
      <C>digraph</C> where vertex <C>OutNeighbours(digraph)[i][j]</C> is
      <C>PositionCanonical(<A>S</A>, AsListCanonical(<A>S</A>)[i] *
        GeneratorsOfSemigroup(<A>S</A>)[j])</C>.
      The digraph returned by <C>LeftCayleyDigraph</C> is defined analogously.<P/>

      The digraph returned by this attribute belongs to the category
      <Ref Filt="IsCayleyDigraph" BookName="digraphs"/>, the semigroup <A>S</A>
      and the generators used to create the digraph can be recovered from the
      digraph using  <Ref Attr="SemigroupOfCayleyDigraph" BookName="digraphs"/>
      and <Ref Attr="GeneratorsOfCayleyDigraph" BookName="digraphs"/>.

      <Example><![CDATA[
gap> S := FullTransformationMonoid(2);
<full transformation monoid of degree 2>
gap> RightCayleyDigraph(S);
<immutable multidigraph with 4 vertices, 12 edges>
gap> LeftCayleyDigraph(S);
<immutable multidigraph with 4 vertices, 12 edges>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>
