#############################################################################
##
#W  orbits.xml
#Y  Copyright (C) 2016-17                                    Jan De Beule
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

<#GAPDoc Label="DigraphGroup">
<ManSection>
  <Attr Name="DigraphGroup" Arg="digraph"/>
  <Returns>A permutation group.</Returns>
  <Description>
    If <A>digraph</A> is immutable and was created knowing a subgroup of
    its automorphism group, then this group is stored in the attribute
    <C>DigraphGroup</C>. If <A>digraph</A> is mutable, or was not created
    knowing a subgroup of its automorphism group, then <C>DigraphGroup</C>
    returns the entire automorphism group of <A>digraph</A>.    
    Note that if <A>digraph</A> is mutable, then the automorphism group is
    recomputed every time this function is called.
    <P/>

    Note that certain other constructor operations such as  <Ref
      Oper="CayleyDigraph"/>, <Ref Oper="BipartiteDoubleDigraph"/>, and <Ref
      Oper="DoubleDigraph"/>, may not require a group as one of the arguments,
    but use the standard constructor method using a group, and hence set the
    <C>DigraphGroup</C> attribute for the resulting digraph.

    <Example><![CDATA[
gap> n := 4;;
gap> adj := function(x, y)
>      return (((x - y) mod n) = 1) or (((x - y) mod n) = n - 1);
>    end;;
gap> group := CyclicGroup(IsPermGroup, n);
Group([ (1,2,3,4) ])
gap> D := Digraph(IsMutableDigraph, group, [1 .. n], \^, adj);
<mutable digraph with 4 vertices, 8 edges>
gap> HasDigraphGroup(D);
false
gap> DigraphGroup(D);
Group([ (2,4), (1,2)(3,4) ])
gap> AutomorphismGroup(D);
Group([ (2,4), (1,2)(3,4) ])
gap> D := Digraph(group, [1 .. n], \^, adj);
<immutable digraph with 4 vertices, 8 edges>
gap> HasDigraphGroup(D);
true
gap> DigraphGroup(D);
Group([ (1,2,3,4) ])
gap> D := DoubleDigraph(D);
<immutable digraph with 8 vertices, 32 edges>
gap> HasDigraphGroup(D);
true
gap> DigraphGroup(D);
Group([ (1,2,3,4)(5,6,7,8), (1,5)(2,6)(3,7)(4,8) ])
gap> AutomorphismGroup(D) =
> Group([(6, 8), (5, 7), (4, 6), (3, 5), (2, 4),
>        (1, 2)(3, 4)(5, 6)(7, 8)]);
true
gap> D := Digraph([[2, 3], [], []]);
<immutable digraph with 3 vertices, 2 edges>
gap> HasDigraphGroup(D);
false
gap> HasAutomorphismGroup(D);
false
gap> DigraphGroup(D);
Group([ (2,3) ])
gap> HasAutomorphismGroup(D);
true
gap> group := DihedralGroup(8);
<pc group of size 8 with 3 generators>
gap> D := CayleyDigraph(group);
<immutable digraph with 8 vertices, 24 edges>
gap> HasDigraphGroup(D);
true
gap> GeneratorsOfGroup(DigraphGroup(D));
[ (1,2)(3,5)(4,6)(7,8), (1,7,4,3)(2,5,6,8), (1,4)(2,6)(3,7)(5,8) ]]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphSchreierVector">
<ManSection>
  <Attr Name="DigraphSchreierVector" Arg="digraph"/>
  <Returns>
    An immutable list of integers.
  </Returns>
  <Description>
    <C>DigraphSchreierVector</C> returns the so-called <E>Schreier vector</E>
    of the action of the <Ref Attr="DigraphGroup"/> on the set of vertices of
    <A>digraph</A>. The Schreier vector is a list <C>sch</C> of integers with
    length <C>DigraphNrVertices(<A>digraph</A>)</C> where:
    <List>
      <Mark><C>sch[i] &lt; 0:</C></Mark>
      <Item>
        implies that <C>i</C> is an orbit representative and
        <C>DigraphOrbitReps(<A>digraph</A>)[-sch[i]] = i</C>.
      </Item>

      <Mark><C>sch[i] &gt; 0:</C></Mark>
      <Item>
        implies that <C>i / gens[sch[i]]</C>
        is one step closer to the root (or representative) of the tree, where
        <C>gens</C> is the generators of <C>DigraphGroup(<A>digraph</A>)</C>.
      </Item>
    </List>

    <Example><![CDATA[
gap> n := 4;;
gap> adj := function(x, y)
>      return (((x - y) mod n) = 1) or (((x - y) mod n) = n - 1);
>    end;;
gap> group := CyclicGroup(IsPermGroup, n);
Group([ (1,2,3,4) ])
gap> D := Digraph(IsMutableDigraph, group, [1 .. n], \^, adj);
<mutable digraph with 4 vertices, 8 edges>
gap> sch := DigraphSchreierVector(D);
[ -1, 2, 2, 1 ]
gap> D := CayleyDigraph(AlternatingGroup(4));
<immutable digraph with 12 vertices, 24 edges>
gap> sch := DigraphSchreierVector(D);
[ -1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1 ]
gap> DigraphOrbitReps(D);
[ 1 ]
gap> gens := GeneratorsOfGroup(DigraphGroup(D));
[ (1,7,5)(2,10,9)(3,4,11)(6,8,12), (1,3,2)(4,5,6)(7,9,8)(10,11,12) ]
gap> 10 / gens[sch[10]];
2
gap> 7 / gens[sch[7]];
1
gap> 5 / gens[sch[5]];
7]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphOrbitReps">
<ManSection>
  <Attr Name="DigraphOrbitReps" Arg="digraph"/>
  <Returns>
    An immutable list of integers.
  </Returns>
  <Description>
    <C>DigraphOrbitReps</C> returns a list of orbit representatives
    of the action of the <Ref Attr="DigraphGroup"/> on the set of vertices of
    <A>digraph</A>.

    <Example><![CDATA[
gap> D := CayleyDigraph(AlternatingGroup(4));
<immutable digraph with 12 vertices, 24 edges>
gap> DigraphOrbitReps(D);
[ 1 ]
gap> D := DigraphMutableCopy(D);
<mutable digraph with 12 vertices, 24 edges>
gap> DigraphOrbitReps(D);
[ 1 ]
gap> D := DigraphFromDigraph6String("&IGO??S?`?_@?a?CK?O");
<immutable digraph with 10 vertices, 14 edges>
gap> DigraphOrbitReps(D);
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
gap> DigraphOrbitReps(DigraphMutableCopy(D));
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphStabilizer">
<ManSection>
  <Oper Name="DigraphStabilizer" Arg="digraph, v"/>
  <Returns>
    A permutation group.
  </Returns>
  <Description>
    <C>DigraphStabilizer</C> returns the stabilizer of the vertex <A>v</A>
    under of the action of the <Ref Attr="DigraphGroup"/> on the set of
    vertices of <A>digraph</A>.

    <Example><![CDATA[
gap> D := DigraphFromDigraph6String("&GYHPQgWTIIPW");
<immutable digraph with 8 vertices, 24 edges>
gap> DigraphStabilizer(D, 8);
Group(())
gap> DigraphStabilizer(D, 2);
Group(())
gap> D := DigraphMutableCopy(D);
<mutable digraph with 8 vertices, 24 edges>
gap> DigraphStabilizer(D, 8);
Group(())
gap> DigraphStabilizer(D, 2);
Group(())
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphOrbits">
<ManSection>
  <Attr Name="DigraphOrbits" Arg="digraph"/>
  <Returns>
    An immutable list of lists of integers.
  </Returns>
  <Description>
    <C>DigraphOrbits</C> returns the orbits of the action of the
    <Ref Attr="DigraphGroup"/> on the set of vertices of <A>digraph</A>.

    <Example><![CDATA[
gap> G := Group([(2, 3)(7, 8, 9), (1, 2, 3)(4, 5, 6)(8, 9)]);;
gap> D := EdgeOrbitsDigraph(G, [1, 2]);
<immutable digraph with 9 vertices, 6 edges>
gap> DigraphOrbits(D);
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
gap> D := DigraphMutableCopy(D);
<mutable digraph with 9 vertices, 6 edges>
gap> DigraphOrbits(D);
[ [ 1, 2, 3 ], [ 4, 5, 6, 7, 8, 9 ] ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RepresentativeOutNeighbours">
<ManSection>
  <Attr Name="RepresentativeOutNeighbours" Arg="digraph"/>
  <Returns>An immutable list of lists.</Returns>
  <Description>
    This function returns the list <C>out</C> of <E>out-neighbours</E> of each
    representative of the orbits of the action of <Ref Attr="DigraphGroup"/> on
    the vertex set of the digraph <A>digraph</A>. <P/>

    More specifically, if <C>reps</C> is the list of orbit representatives,
    then a vertex <C>j</C> appears in <C>out[i]</C> each time
    there exists an edge with source <C>reps[i]</C> and range <C>j</C> in
    <A>digraph</A>.
    <P/>

    If <Ref Attr="DigraphGroup"/> is trivial, then <Ref Attr="OutNeighbours"/>
    is returned.

    <Example><![CDATA[
gap> D := Digraph([
>  [2, 1, 3, 4, 5], [3, 5], [2], [1, 2, 3, 5], [1, 2, 3, 4]]);
<immutable digraph with 5 vertices, 16 edges>
gap> DigraphGroup(D);
Group(())
gap> RepresentativeOutNeighbours(D);
[ [ 2, 1, 3, 4, 5 ], [ 3, 5 ], [ 2 ], [ 1, 2, 3, 5 ], [ 1, 2, 3, 4 ] ]
gap> D := Digraph(IsMutableDigraph, [
>  [2, 1, 3, 4, 5], [3, 5], [2], [1, 2, 3, 5], [1, 2, 3, 4]]);
<mutable digraph with 5 vertices, 16 edges>
gap> DigraphGroup(D);
Group(())
gap> RepresentativeOutNeighbours(D);
[ [ 2, 1, 3, 4, 5 ], [ 3, 5 ], [ 2 ], [ 1, 2, 3, 5 ], [ 1, 2, 3, 4 ] ]
gap> D := DigraphFromDigraph6String("&GYHPQgWTIIPW");
<immutable digraph with 8 vertices, 24 edges>
gap> G := DigraphGroup(D);;
gap> GeneratorsOfGroup(G);
[ (1,2)(3,4)(5,6)(7,8), (1,3,2,4)(5,7,6,8), (1,5)(2,6)(3,8)(4,7) ]
gap> Set(RepresentativeOutNeighbours(D), Set);
[ [ 2, 3, 5 ] ]]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>
