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

<#GAPDoc Label="EnumeratePosition">
  <ManSection>
    <Func Name = "EnumeratePosition" Arg = "o, val[, onlynew]"/>
    <Returns>
      A positive integer or <K>fail</K>.
    </Returns>
    <Description>
      This function returns the position of the value <A>val</A> in the orbit
      <A>o</A>. If <A>o</A> is closed, then this is equivalent to doing
      <C>Position(<A>o</A>, <A>val</A>)</C>. However, if <A>o</A> is open, then
      the orbit is enumerated until <A>val</A> is found, in which case the
      position of <A>val</A> is returned, or the enumeration ends, in which
      case <K>fail</K> is returned.  <P/>

      If the optional argument <A>onlynew</A> is present, it should be
      <K>true</K> or <K>false</K>. If <A>onlynew</A> is <K>true</K>, then
      <A>val</A> will only be checked against new points in <A>o</A>. Otherwise,
      every point in the <A>o</A>, not only the new ones, is considered.
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="LookForInOrb">
  <ManSection>
    <Func Name = "LookForInOrb" Arg = "o, func, start"/>
    <Returns>
      <K>false</K> or a positive integer.
    </Returns>
    <Description>
      The arguments of this function should be an orbit <A>o</A>, a function
      <A>func</A> which gets the orbit object and a point in the orbit as
      arguments, and a positive integer <A>start</A>. The function <A>func</A>
      will be called for every point in <A>o</A> starting from <A>start</A>
      (inclusive) and the orbit will be enumerated until <A>func</A> returns
      <K>true</K> or the enumeration ends. In the former case, the position of
      the first point in <A>o</A> for which <A>func</A> returns <K>true</K> is
      returned, and in the latter <K>false</K> is returned.
<Example><![CDATA[
gap> o := Orb(SymmetricGroup(100), 1, OnPoints);
<open Int-orbit, 1 points>
gap> func := function(o, x) return x = 42; end;
function( o, x ) ... end
gap> LookForInOrb(o, func, 1);
42
gap> o;
<open Int-orbit, 42 points>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="EvaluateWord">
  <ManSection>
    <Oper Name = "EvaluateWord" Arg = "gens, w"/>
    <Returns>A semigroup element.</Returns>
    <Description>
      The argument <A>gens</A> should be a collection of generators of a
      semigroup and the argument <A>w</A> should be a list of positive integers
      less than or equal to the length of <A>gens</A>.  This operation evaluates
      the word <A>w</A> in the generators <A>gens</A>. More precisely,
      <C>EvaluateWord(<A>gens</A>, <A>w</A>)</C> returns the equivalent of:
      <Log>Product(List(w, i -> gens[i]));</Log>
      see also <Ref Oper = "Factorization"/>.<P/>
      <List>
        <Mark>for elements of a semigroup</Mark>
        <Item>
          When <A>gens</A> is a list of elements of a semigroup and <A>w</A> is
          a list of positive integers less than or equal to the length of
          <A>gens</A>, this operation returns the product
          <C>gens[w[1]] * gens[w[2]] * .. . * gens[w[n]]</C> when the length of
          <A>w</A> is <C>n</C>.
        </Item>

        <Mark>for elements of an inverse semigroup</Mark>
        <Item>
          When <A>gens</A> is a list of elements with a semigroup inverse and
          <A>w</A> is a list of non-zero integers whose absolute value does not
          exceed the length of <A>gens</A>, this operation returns the product
          <C>gens[AbsInt(w[1])] ^ SignInt(w[1]) * .. . * gens[AbsInt(w[n])] ^
            SignInt(w[n])</C> where <C>n</C> is the length of <A>w</A>.
        </Item>
      </List>

      Note that <C>EvaluateWord(<A>gens</A>, [])</C> returns
      <C>One(<A>gens</A>)</C> if <A>gens</A> belongs to the category
      <Ref Filt = "IsMultiplicativeElementWithOne" BookName = "ref"/>.
<Example><![CDATA[
gap> gens := [
> Transformation([2, 4, 4, 6, 8, 8, 6, 6]),
> Transformation([2, 7, 4, 1, 4, 6, 5, 2]),
> Transformation([3, 6, 2, 4, 2, 2, 2, 8]),
> Transformation([4, 3, 6, 4, 2, 1, 2, 6]),
> Transformation([4, 5, 1, 3, 8, 5, 8, 2])];;
gap> S := Semigroup(gens);;
gap> x := Transformation([1, 4, 6, 1, 7, 2, 7, 6]);;
gap> word := Factorization(S, x);
[ 4, 2 ]
gap> EvaluateWord(gens, word);
Transformation( [ 1, 4, 6, 1, 7, 2, 7, 6 ] )
gap> S := SymmetricInverseMonoid(10);;
gap> x := PartialPerm([2, 6, 7, 0, 0, 9, 0, 1, 0, 5]);
[3,7][8,1,2,6,9][10,5]
gap> word := Factorization(S, x);
[ -2, -2, -2, -2, -3, -2, -2, -2, -2, -2, 5, 2, 5, 5, 2, 5, 2, 2, 2,
  2, -3, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 2 ]
gap> EvaluateWord(GeneratorsOfSemigroup(S), word);
[3,7][8,1,2,6,9][10,5]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="OrbSCC">
  <ManSection>
    <Func Name = "OrbSCC" Arg = "o"/>
    <Returns>
      The strongly connected components of an orbit.
    </Returns>
    <Description>
      If <A>o</A> is an orbit created by the <Package>Orb</Package> package
      with the option <C>orbitgraph=true</C>, then <C>OrbSCC</C> returns a set
      of lists of positions in <A>o</A> corresponding to its strongly connected
      components. <P/>

      See also <Ref Func = "OrbSCCLookup"/>.

<Example><![CDATA[
gap> S := FullTransformationSemigroup(4);;
gap> o := LambdaOrb(S);
<open orbit, 1 points with Schreier tree with log>
gap> OrbSCC(o);
[ [ 1 ], [ 2 ], [ 3, 4, 5, 6 ], [ 8, 10, 7, 9, 11, 12 ],
  [ 13, 14, 15, 16 ] ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="OrbSCCLookup">
  <ManSection>
    <Func Name = "OrbSCCLookup" Arg = "o"/>
    <Returns>
      A lookup table for the strongly connected components of an orbit.
    </Returns>
    <Description>
      If <A>o</A> is an orbit created by the <Package>Orb</Package> package
      with the option <C>orbitgraph=true</C>, then <C>OrbSCCLookup</C> returns
      a lookup table for its strongly connected components. More precisely,
      <C>OrbSCCLookup(o)[i]</C> equals the index of the strongly connected
      component containing <C>o[i]</C>.  <P/>

      See also <Ref Func = "OrbSCC"/>.

<Example><![CDATA[
gap> S := FullTransformationSemigroup(4);;
gap> o := LambdaOrb(S);;
gap> OrbSCC(o);
[ [ 1 ], [ 2 ], [ 3, 4, 5, 6 ], [ 8, 10, 7, 9, 11, 12 ],
  [ 13, 14, 15, 16 ] ]
gap> OrbSCCLookup(o);
[ 1, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5 ]
gap> OrbSCCLookup(o)[1]; OrbSCCLookup(o)[4]; OrbSCCLookup(o)[7];
1
3
4]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="ReverseSchreierTreeOfSCC">
  <ManSection>
    <Func Name = "ReverseSchreierTreeOfSCC" Arg = "o, i"/>
    <Returns>
      The reverse Schreier tree corresponding to the <A>i</A>th strongly
      connected component of an orbit.
    </Returns>
    <Description>
      If <A>o</A> is an orbit created by the <Package>Orb</Package> package with
      the option <C>orbitgraph = true</C> and action <C>act</C>, and <A>i</A> is a
      positive integer, then <C>ReverseSchreierTreeOfSCC(<A>o</A>, <A>i</A>)</C>
      returns a pair <C>[gen, pos]</C> of lists with <C>Length(o)</C> entries
      such that <Log>act(o[j], o!.gens[gen[j]]) = o[pos[j]].</Log> The pair <C>[
        gen, pos]</C> corresponds to a tree with root <C>OrbSCC(o)[i][1]</C> and a
      path from every element of <C>OrbSCC(o)[i]</C> to the root. <P/>

      See also <Ref Func = "OrbSCC"/>,
      <Ref Func = "TraceSchreierTreeOfSCCBack"/>,
      <Ref Func = "SchreierTreeOfSCC"/>, and
      <Ref Func = "TraceSchreierTreeOfSCCForward"/>.
<Example><![CDATA[
gap> S := Semigroup(Transformation([2, 2, 1, 4, 4]),
>                   Transformation([3, 3, 3, 4, 5]),
>                   Transformation([5, 1, 4, 5, 5]));;
gap> o := Orb(S, [1 .. 4], OnSets, rec(orbitgraph := true,
> schreier := true));;
gap> OrbSCC(o);
[ [ 1 ], [ 2 ], [ 3, 7, 5, 6, 11 ], [ 4 ], [ 8 ], [ 9 ], [ 10, 12 ] ]
gap> ReverseSchreierTreeOfSCC(o, 3);
[ [ ,, fail,, 2, 1, 2,,,, 1 ], [ ,, fail,, 3, 5, 3,,,, 7 ] ]
gap> ReverseSchreierTreeOfSCC(o, 7);
[ [ ,,,,,,,,, fail,, 3 ], [ ,,,,,,,,, fail,, 10 ] ]
gap> OnSets(o[11], Generators(S)[1]);
[ 1, 4 ]
gap> Position(o, last);
7]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SchreierTreeOfSCC">
  <ManSection>
    <Func Name = "SchreierTreeOfSCC" Arg = "o, i"/>
    <Returns>
      The Schreier tree corresponding to the <A>i</A>th strongly
      connected component of an orbit.
    </Returns>

    <Description>
    If <A>o</A> is an orbit created by the <Package>Orb</Package> package with
    the option <C>orbitgraph = true</C> and action <C>act</C>, and <A>i</A> is a
    positive integer, then <C>SchreierTreeOfSCC(<A>o</A>, <A>i</A>)</C> returns
    a pair <C>[gen, pos]</C> of lists with <C>Length(o)</C> entries such that
    <Log>act(o[pos[j]], o!.gens[gen[j]]) = o[j].</Log> The pair <C>[gen, pos
]</C> corresponds to a tree with root <C>OrbSCC(o)[i][1]</C> and a path
    from the root to every element of <C>OrbSCC(o)[i]</C>. <P/>

    See also <Ref Func = "OrbSCC"/>, <Ref Func = "TraceSchreierTreeOfSCCBack"/>,
    <Ref Func = "ReverseSchreierTreeOfSCC"/>, and
    <Ref Func = "TraceSchreierTreeOfSCCForward"/>.
<Example><![CDATA[
gap> S := Semigroup([Transformation([2, 2, 1, 4, 4]),
>                    Transformation([3, 3, 3, 4, 5]),
>                    Transformation([5, 1, 4, 5, 5])]);;
gap> o := Orb(S, [1 .. 4], OnSets, rec(orbitgraph := true,
> schreier := true));;
gap> OrbSCC(o);
[ [ 1 ], [ 2 ], [ 3, 7, 5, 6, 11 ], [ 4 ], [ 8 ], [ 9 ], [ 10, 12 ] ]
gap> SchreierTreeOfSCC(o, 3);
[ [ ,, fail,, 1, 3, 1,,,, 2 ], [ ,, fail,, 7, 5, 3,,,, 6 ] ]
gap> SchreierTreeOfSCC(o, 7);
[ [ ,,,,,,,,, fail,, 1 ], [ ,,,,,,,,, fail,, 10 ] ]
gap> OnSets(o[6], Generators(S)[2]);
[ 3, 5 ]
gap> Position(o, last);
11]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="TraceSchreierTreeOfSCCBack"/>
  <ManSection>
    <Oper Name = "TraceSchreierTreeOfSCCBack" Arg = "orb, m, nr"/>
    <Returns>A word in the generators.</Returns>
    <Description>
    <A>orb</A>  must  be  an  orbit  object  with  a Schreier tree and orbit
    graph, that is, the options <C>schreier</C> and <C>orbitgraph</C> must have
    been set to <K>true</K> during the creation of the orbit, <A>m</A> must be
    the number of a strongly connected component of <A>orb</A>, and <C>nr</C>
    must be the number of a point in  the  <A>m</A>th strongly connect
    component of <A>orb</A>. <P/>

    This operation traces the result of <Ref
    Func = "ReverseSchreierTreeOfSCC"/> and with arguments <A>orb</A> and
    <A>m</A> and returns a word in the generators that maps the point with
    number <A>nr</A> to the first point in the <A>m</A>th strongly connected
    component of <A>orb</A>.  Here, a word is a list of integers, where
    positive integers are numbers of  generators.

    See also <Ref Func = "OrbSCC"/>,
    <Ref Func = "ReverseSchreierTreeOfSCC"/>,
    <Ref Func = "SchreierTreeOfSCC"/>, and
    <Ref Func = "TraceSchreierTreeOfSCCForward"/>.
    <Example><![CDATA[
gap> S := Semigroup([
>  Transformation([1, 3, 4, 1]),
>  Transformation([2, 4, 1, 2]),
>  Transformation([3, 1, 1, 3]),
>  Transformation([3, 3, 4, 1])]);;
gap> o := Orb(S, [1 .. 4], OnSets, rec(orbitgraph := true,
> schreier := true));;
gap> OrbSCC(o);
[ [ 1 ], [ 2 ], [ 3 ], [ 4, 5, 6, 7, 8 ], [ 9, 10, 11, 12 ] ]
gap> ReverseSchreierTreeOfSCC(o, 4);
[ [ ,,, fail, 4, 1, 1, 3 ], [ ,,, fail, 4, 4, 4, 4 ] ]
gap> TraceSchreierTreeOfSCCBack(o, 4, 7);
[ 1 ]
gap> TraceSchreierTreeOfSCCBack(o, 4, 8);
[ 3 ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="TraceSchreierTreeOfSCCForward"/>
  <ManSection>
    <Oper Name = "TraceSchreierTreeOfSCCForward" Arg = "orb, m, nr"/>
    <Returns>
      A word in the generators.
    </Returns>
    <Description>
      <A>orb</A>  must  be  an  orbit  object  with  a Schreier tree and orbit
      graph, that is, the options <C>schreier</C> and <C>orbitgraph</C> must
      have been set to <K>true</K> during the creation of the orbit, <A>m</A>
      must be the number of a strongly connected component of <A>orb</A>, and
      <C>nr</C> must be the number of a point in  the  <A>m</A>th strongly
      connect component of <A>orb</A>. <P/>

      This operation traces the result of <Ref Func = "SchreierTreeOfSCC"/> and
      with arguments <A>orb</A> and <A>m</A> and returns a word in the
      generators that maps the first point in the <A>m</A>th strongly connected
      component of <A>orb</A> to the point with number <A>nr</A>.  Here, a word
      is a list of integers, where positive integers are numbers of generators.

    See also <Ref Func = "OrbSCC"/>,
    <Ref Func = "ReverseSchreierTreeOfSCC"/>,
    <Ref Func = "SchreierTreeOfSCC"/>, and
    <Ref Func = "TraceSchreierTreeOfSCCBack"/>.
    <Example><![CDATA[
gap> S := Semigroup([Transformation([1, 3, 4, 1]),
>                    Transformation([2, 4, 1, 2]),
>                    Transformation([3, 1, 1, 3]),
>                    Transformation([3, 3, 4, 1])]);;
gap> o := Orb(S, [1 .. 4], OnSets, rec(orbitgraph := true,
> schreier := true));;
gap> OrbSCC(o);
[ [ 1 ], [ 2 ], [ 3 ], [ 4, 5, 6, 7, 8 ], [ 9, 10, 11, 12 ] ]
gap> SchreierTreeOfSCC(o, 4);
[ [ ,,, fail, 1, 2, 2, 4 ], [ ,,, fail, 4, 4, 6, 4 ] ]
gap> TraceSchreierTreeOfSCCForward(o, 4, 8);
[ 4 ]
gap> TraceSchreierTreeOfSCCForward(o, 4, 7);
[ 2, 2 ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>
