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

<#GAPDoc Label="DigraphsUseNauty">
<ManSection>
  <Func Name="DigraphsUseNauty" Arg=""/>
  <Func Name="DigraphsUseBliss" Arg=""/>
  <Returns>Nothing.</Returns>
  <Description>
    These functions can be used to specify whether &NAUTY; or &BLISS; should be
    used by default by &Digraphs;. If &NautyTracesInterface; is not available,
    then these functions do nothing. Otherwise, by calling
    <C>DigraphsUseNauty</C> subsequent computations will default to using
    &NAUTY; rather than &BLISS;, where possible.
    <P/>

    You can call these functions at any point in a &GAP; session, as many
    times as you like, it is guaranteed that existing digraphs remain
    valid, and that comparison of existing digraphs and newly created digraphs
    via
    <Ref Oper="IsIsomorphicDigraph" Label="for digraphs"/>,
    <Ref Oper="IsIsomorphicDigraph"
      Label="for digraphs and homogeneous lists"/>,
    <Ref Oper="IsomorphismDigraphs" Label="for digraphs"/>, and
    <Ref Oper="IsomorphismDigraphs"
      Label="for digraphs and homogeneous lists"/> are also valid.<P/>

    It is also possible to compute the automorphism group of a specific digraph
    using both &NAUTY; and &BLISS; using <Ref Attr="NautyAutomorphismGroup"/>
    and <Ref Attr="BlissAutomorphismGroup" Label="for a digraph"/>, respectively.
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="BlissAutomorphismGroup">
<ManSection>
  <Attr Name="BlissAutomorphismGroup" Arg="digraph" Label="for a digraph"/>
  <Oper Name="BlissAutomorphismGroup" Arg="digraph, vertex_colours" 
    Label="for a digraph and homogeneous list"/>
  <Oper Name="BlissAutomorphismGroup" Arg="digraph, vertex_colours, edge_colours" 
    Label="for a digraph, homogeneous list, and list"/>
  <Returns>A permutation group.</Returns>
  <Description>
    If <A>digraph</A> is a digraph, then this attribute contains the group of
    automorphisms of <A>digraph</A> as calculated using &BLISS; by Tommi Junttila
    and Petteri Kaski. <P/>

    The attribute <Ref Attr="AutomorphismGroup" Label="for a digraph"/> and
    operation <Ref Oper="AutomorphismGroup" 
      Label="for a digraph and a homogeneous list"/> returns
    the value of either <C>BlissAutomorphismGroup</C> or <Ref
      Attr="NautyAutomorphismGroup"/>. These groups are, of course, equal but
    their generating sets may differ. <P/>
    The attribute <Ref Attr="AutomorphismGroup" 
      Label="for a digraph, homogeneous list, and list"/> returns the value of
    <C>BlissAutomorphismGroup</C> as it is not implemented for &NAUTY; The 
    requirements for the optional arguments <A>vertex_colours</A> and 
    <A>edge_colours</A> are documented in <Ref Attr="AutomorphismGroup" 
      Label="for a digraph, homogeneous list, and list"/>.

    See also <Ref Func="DigraphsUseBliss"/>, and <Ref Func="DigraphsUseNauty"/>.
    <P/>

    &MUTABLE_RECOMPUTED_ATTR;

    <Example><![CDATA[
gap> G := BlissAutomorphismGroup(JohnsonDigraph(5, 2));;
gap> IsSymmetricGroup(G);
true
gap> Size(G);
120]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="NautyAutomorphismGroup">
<ManSection>
  <Attr Name="NautyAutomorphismGroup" Arg="digraph[, vert_colours]"/>
  <Returns>A permutation group.</Returns>
  <Description>
    If <A>digraph</A> is a digraph, then this attribute contains the group of
    automorphisms of <A>digraph</A> as calculated using &NAUTY; by
    Brendan Mckay and Adolfo Piperno via &NautyTracesInterface;.

    <!-- FIXME be more explicit about what the second arg is -->

    The attribute <Ref Attr="AutomorphismGroup" Label="for a digraph"/> and
    operation <Ref Oper="AutomorphismGroup" 
      Label="for a digraph and a homogeneous list"/> returns
    the value of either <C>NautyAutomorphismGroup</C> or  <Ref
      Attr="BlissAutomorphismGroup" Label="for a digraph"/>.
    These groups are, of course, equal but their generating sets may differ.<P/>

    See also <Ref Func="DigraphsUseBliss"/>, and <Ref Func="DigraphsUseNauty"/>.
    <P/>

    &MUTABLE_RECOMPUTED_ATTR;

    <Log><![CDATA[
gap> NautyAutomorphismGroup(JohnsonDigraph(5, 2));
Group([ (3,4)(6,7)(8,9), (2,3)(5,6)(9,10), (2,5)(3,6)(4,7),
 (1,2)(6,8)(7,9) ])]]></Log>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AutomorphismGroupDigraph">
<ManSection>
  <Attr Name="AutomorphismGroup" Label="for a digraph" Arg="digraph"/>
  <Returns>A permutation group.</Returns>
  <Description>
    If <A>digraph</A> is a digraph, then this attribute contains the group of
    automorphisms of <A>digraph</A>.  An <E>automorphism</E> of <A>digraph</A>
    is an isomorphism from <A>digraph</A> to itself. See <Ref
      Oper="IsomorphismDigraphs" Label="for digraphs" /> for more information
    about isomorphisms of digraphs. <P/>

    If <A>digraph</A> is not a multidigraph then the automorphism group is
    returned as a group of permutations on the set of vertices of
    <A>digraph</A>. <P/>

    If <A>digraph</A> is a multidigraph then the automorphism group is returned
    as the direct product of a group of permutations on the set of vertices of
    <A>digraph</A> with a group of permutations on the set of edges of
    <A>digraph</A>. These groups can be accessed using <Ref Oper="Projection"
      Label="for a domain and a positive integer" BookName="ref"/> on the
    returned group.<P/>

    By default, the automorphism group is found using &BLISS; by Tommi Junttila
    and Petteri Kaski. If &NautyTracesInterface; is available, then &NAUTY; by
    Brendan Mckay and Adolfo Piperno can be used instead; see
    <Ref Attr="BlissAutomorphismGroup" Label="for a digraph"/>, 
    <Ref Attr="NautyAutomorphismGroup"/>, <Ref Func="DigraphsUseBliss"/>,
    and <Ref Func="DigraphsUseNauty"/>.
    <P/>

    &MUTABLE_RECOMPUTED_ATTR;

    <Example><![CDATA[
gap> johnson := DigraphFromGraph6String("E}lw");
<immutable symmetric digraph with 6 vertices, 24 edges>
gap> G := AutomorphismGroup(johnson);
Group([ (3,4), (2,3)(4,5), (1,2)(5,6) ])
gap> cycle := CycleDigraph(9);
<immutable cycle digraph with 9 vertices>
gap> G := AutomorphismGroup(cycle);
Group([ (1,2,3,4,5,6,7,8,9) ])
gap> IsCyclic(G) and Size(G) = 9;
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AutomorphismGroupDigraphColours">
<ManSection>
  <Oper Name="AutomorphismGroup" Label="for a digraph and a homogeneous list"
    Arg="digraph, vert_colours"/>
  <Returns>A permutation group.</Returns>
  <Description>

    This operation computes the automorphism group of a vertex-coloured digraph.
    A vertex-coloured digraph can be specified by its underlying digraph
    <A>digraph</A> and its colouring <A>vert_colours</A>. Let <C>n</C> be the
    number of vertices of <A>digraph</A>. The colouring <A>vert_colours</A> may
    have one of the following two forms:

    <List>
      <Item>
        a list of <C>n</C> integers, where <A>vert_colours</A><C>[i]</C> is the
        colour of vertex <C>i</C>, using the colours <C>[1 .. m]</C> for some
        <C>m &lt;= n</C>; or
      </Item>
      <Item>
        a list of non-empty disjoint lists whose union is
        <C>DigraphVertices(<A>digraph</A>)</C>, such that
        <A>vert_colours</A><C>[i]</C> is the list of all vertices with colour
        <C>i</C>.
      </Item>
    </List>

    The <E>automorphism group</E> of a coloured digraph <A>digraph</A> with
    colouring <A>vert_colours</A> is the group consisting of its automorphisms; an
    <E>automorphism</E> of <A>digraph</A> is an isomorphism of coloured
    digraphs from <A>digraph</A> to itself.  This group is equal to the
    subgroup of <C>AutomorphismGroup(<A>digraph</A>)</C> consisting of those
    automorphisms that preserve the colouring specified by <A>vert_colours</A>. See
    <Ref Attr="AutomorphismGroup" Label="for a digraph" />, and see <Ref
      Oper="IsomorphismDigraphs" Label="for digraphs and homogeneous lists" />
    for more information about isomorphisms of coloured digraphs. <P/>

    If <A>digraph</A> is not a multidigraph then the automorphism group is
    returned as a group of permutations on the set of vertices of
    <A>digraph</A>. <P/>

    If <A>digraph</A> is a multidigraph then the automorphism group is returned
    as the direct product of a group of permutations on the set of vertices of
    <A>digraph</A> with a group of permutations on the set of edges of
    <A>digraph</A>. These groups can be accessed using <Ref Oper="Projection"
      Label="for a domain and a positive integer" BookName="ref"/> on the
    returned group.<P/>

    By default, the automorphism group is found using &BLISS; by Tommi Junttila
    and Petteri Kaski. If &NautyTracesInterface; is available, then &NAUTY; by
    Brendan Mckay and Adolfo Piperno can be used instead; see
    <Ref Attr="BlissAutomorphismGroup"
      Label="for a digraph and homogeneous list"/>,
    <Ref Attr="NautyAutomorphismGroup"/>, <Ref Func="DigraphsUseBliss"/>,
    and <Ref Func="DigraphsUseNauty"/>.

  <Example><![CDATA[
gap> cycle := CycleDigraph(9);
<immutable cycle digraph with 9 vertices>
gap> G := AutomorphismGroup(cycle);;
gap> IsCyclic(G) and Size(G) = 9;
true
gap> colours := [[1, 4, 7], [2, 5, 8], [3, 6, 9]];;
gap> H := AutomorphismGroup(cycle, colours);;
gap> Size(H);
3
gap> H = AutomorphismGroup(cycle, [1, 2, 3, 1, 2, 3, 1, 2, 3]);
true
gap> H = SubgroupByProperty(G, p -> OnTuplesSets(colours, p) = colours);
true
gap> IsTrivial(AutomorphismGroup(cycle, [1, 1, 2, 2, 2, 2, 2, 2, 2]));
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="AutomorphismGroupDigraphEdgeColours">
<ManSection>
  <Oper Name="AutomorphismGroup"
    Label="for a digraph, homogeneous list, and list"
    Arg="digraph, vert_colours, edge_colours"/>
  <Returns>A permutation group.</Returns>
  <Description>

    This operation computes the automorphism group of a vertex- and/or
    edge-coloured digraph.
    A coloured digraph can be specified by its underlying digraph
    <A>digraph</A> and colourings <A>vert_colours</A>, <A>edge_colours</A>.
    Let <C>n</C> be the number of vertices of <A>digraph</A>. The colourings
    must have the following forms:

    <List>
      <Item>
        <A>vert_colours</A> must be <K>fail</K> or a list of <C>n</C> integers,
        where <A>vert_colours</A><C>[i]</C> is the colour of vertex <C>i</C>,
        using the colours <C>[1 .. m]</C> for some <C>m &lt;= n</C>;
      </Item>
      <Item>
        <A>edge_colours</A> must be <K>fail</K> or a list of <C>n</C> lists of
        integers of the same shape as <C>OutNeighbours(digraph)</C>, where
        <A>edge_colours</A><C>[i][j]</C> is the colour of the edge
        <C>OutNeighbours(digraph)[i][j]</C>, using the colours <C>[1 .. k]</C>
        for some <C>k &lt;= n</C>;
      </Item>
    </List>

    Giving <A>vert_colours</A> [<A>edge_colours</A>] as <C>fail</C> is
    equivalent to setting all vertices [edges] to be the same colour. <P/>

    Unlike <Ref Attr="AutomorphismGroup" Label="for a digraph"/>, it is
    possible to obtain the automorphism group of an edge-coloured multidigraph
    (see <Ref Prop="IsMultiDigraph" />) when no two edges share the same
    source, range, and colour.

    The <E>automorphism group</E> of a vertex/edge-coloured digraph
    <A>digraph</A> with colouring <A>c</A> is the group consisting of its
    vertex/edge-colour preserving automorphisms; an
    <E>automorphism</E> of <A>digraph</A> is an isomorphism of vertex/edge-coloured
    digraphs from <A>digraph</A> to itself.  This group is equal to the
    subgroup of <C>AutomorphismGroup(<A>digraph</A>)</C> consisting of those
    automorphisms that preserve the colouring specified by <A>colours</A>. See
    <Ref Attr="AutomorphismGroup" Label="for a digraph" />, and see <Ref
      Oper="IsomorphismDigraphs" Label="for digraphs and homogeneous lists" />
    for more information about isomorphisms of coloured digraphs. <P/>

    If <A>digraph</A> is not a multidigraph then the automorphism group is
    returned as a group of permutations on the set of vertices of
    <A>digraph</A>. <P/>

    If <A>digraph</A> is a multidigraph then the automorphism group is returned
    as the direct product of a group of permutations on the set of vertices of
    <A>digraph</A> with a group of permutations on the set of edges of
    <A>digraph</A>. These groups can be accessed using <Ref Oper="Projection"
      Label="for a domain and a positive integer" BookName="ref"/> on the
    returned group.<P/>

    By default, the automorphism group is found using &BLISS; by Tommi Junttila
    and Petteri Kaski. If &NautyTracesInterface; is available, then &NAUTY; by
    Brendan Mckay and Adolfo Piperno can be used instead; see
     <Ref Attr="BlissAutomorphismGroup"
       Label="for a digraph, homogeneous list, and list"/>,
     <Ref Attr="NautyAutomorphismGroup"/>, <Ref Func="DigraphsUseBliss"/>, and
     <Ref Func="DigraphsUseNauty"/>.

  <Example><![CDATA[
gap> cycle := CycleDigraph(12);
<immutable cycle digraph with 12 vertices>
gap> vert_colours := List([1 .. 12], x -> x mod 3 + 1);;
gap> edge_colours := List([1 .. 12], x -> [x mod 2 + 1]);;
gap> Size(AutomorphismGroup(cycle));
12
gap> Size(AutomorphismGroup(cycle, vert_colours));
4
gap> Size(AutomorphismGroup(cycle, fail, edge_colours));
6
gap> Size(AutomorphismGroup(cycle, vert_colours, edge_colours));
2
gap> IsTrivial(AutomorphismGroup(cycle,
> vert_colours, List([1 .. 12], x -> [x mod 4 + 1])));
true
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="BlissCanonicalLabelling">
<ManSection>
  <Attr Name="BlissCanonicalLabelling" Label="for a digraph" Arg="digraph"/>
  <Attr Name="NautyCanonicalLabelling" Label="for a digraph" Arg="digraph"/>
  <Returns>A permutation, or a list of two permutations.</Returns>
  <Description>
    A function <M>\rho</M> that maps a digraph to a digraph is a <E>canonical
      representative map</E> if the following two conditions hold for all
    digraphs <M>G</M> and <M>H</M>: <P/>

    <List>
      <Item>
        <M>\rho(G)</M> and <M>G</M> are isomorphic as digraphs; and
      </Item>
      <Item>
        <M>\rho(G)=\rho(H)</M> if and only if <M>G</M> and <M>H</M> are
        isomorphic as digraphs.
      </Item>
    </List>

    A <E>canonical labelling</E> of a digraph <M>G</M> (under <M>\rho</M>) is an
    isomorphism of <M>G</M> onto its <E>canonical representative</E>,
    <M>\rho(G)</M>.  See <Ref Oper="IsomorphismDigraphs" Label="for digraphs" />
    for more information about isomorphisms of digraphs. <P/>

    <C>BlissCanonicalLabelling</C> returns a canonical labelling of the digraph
    <A>digraph</A> found using &BLISS; by Tommi Junttila and Petteri Kaski.
    <C>NautyCanonicalLabelling</C> returns a canonical labelling of the digraph
    <A>digraph</A> found using &NAUTY; by Brendan McKay and Adolfo Piperno.
    Note that the canonical labellings returned by &BLISS; and &NAUTY; are not
    usually the same (and may depend of the version used).<P/>

    <C>BlissCanonicalLabelling</C> can only be computed if <A>digraph</A> has
    no multiple edges; see <Ref Prop="IsMultiDigraph" />. <P/>

    <Example><![CDATA[
gap> digraph1 := DigraphFromDiSparse6String(".ImNS_AiB?qRN");
<immutable digraph with 10 vertices, 8 edges>
gap> BlissCanonicalLabelling(digraph1);
(1,9,5,7)(3,6,4,10)
gap> p := (1, 2, 7, 5)(3, 9)(6, 10, 8);;
gap> digraph2 := OnDigraphs(digraph1, p);
<immutable digraph with 10 vertices, 8 edges>
gap> digraph1 = digraph2;
false
gap> OnDigraphs(digraph1, BlissCanonicalLabelling(digraph1)) =
>    OnDigraphs(digraph2, BlissCanonicalLabelling(digraph2));
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="BlissCanonicalLabellingColours">
<ManSection>
  <Oper Name="BlissCanonicalLabelling" Label="for a digraph and a list"
    Arg="digraph, colours"/>
  <Oper Name="NautyCanonicalLabelling" Label="for a digraph and a list"
    Arg="digraph, colours"/>
  <Returns>A permutation.</Returns>
  <Description>
    A function <M>\rho</M> that maps a coloured digraph to a coloured digraph is
    a <E>canonical representative map</E> if the following two conditions hold
    for all coloured digraphs <M>G</M> and <M>H</M>:

    <List>
      <Item>
        <M>\rho(G)</M> and <M>G</M> are isomorphic as coloured digraphs; and
      </Item>
      <Item>
        <M>\rho(G)=\rho(H)</M> if and only if <M>G</M> and <M>H</M> are
        isomorphic as coloured digraphs.
      </Item>
    </List>

    A <E>canonical labelling</E> of a coloured digraph <M>G</M> (under
    <M>\rho</M>) is an isomorphism of <M>G</M> onto its <E>canonical
      representative</E>, <M>\rho(G)</M>.  See <Ref Oper="IsomorphismDigraphs"
      Label="for digraphs and homogeneous lists" /> for more information about
    isomorphisms of coloured digraphs. <P/>

    A coloured digraph can be specified by its underlying digraph <A>digraph</A>
    and its colouring <A>colours</A>.  Let <C>n</C> be the number of vertices of
    <A>digraph</A>. The colouring <A>colours</A> may have one of the following
    two forms: <P/>

    <List>
      <Item>
        a list of <C>n</C> integers, where <A>colours</A><C>[i]</C> is the
        colour of vertex <C>i</C>, using the colours <C>[1 .. m]</C> for some
        <C>m &lt;= n</C>; or
      </Item>
      <Item>
        a list of non-empty disjoint lists whose union is
        <C>DigraphVertices(<A>digraph</A>)</C>, such that
        <A>colours</A><C>[i]</C> is the list of all vertices with colour
        <C>i</C>.
      </Item>
    </List>

    If <A>digraph</A> and <A>colours</A> together form a coloured digraph,
    <C>BlissCanonicalLabelling</C> returns a canonical labelling of the digraph
    <A>digraph</A> found using &BLISS; by Tommi Junttila and Petteri Kaski.
    Similarly, <C>NautyCanonicalLabelling</C> returns a canonical labelling of
    the digraph <A>digraph</A> found using &NAUTY; by Brendan McKay and Adolfo
    Piperno.  Note that the canonical labellings returned by &BLISS; and
    &NAUTY; are not usually the same (and may depend of the version used).<P/>

    <C>BlissCanonicalLabelling</C> can only be computed if <A>digraph</A> has
    no multiple edges; see <Ref Prop="IsMultiDigraph" />. The canonical
    labelling of <A>digraph</A> is given as a permutation of its vertices.
    The canonical representative of <A>digraph</A> can be created from
    <A>digraph</A> and its canonical labelling <C>p</C> by using the
    operation <Ref Oper="OnDigraphs" Label="for a digraph and a perm" />:
    <Log>gap> OnDigraphs(digraph, p);</Log>

    The colouring of the canonical representative can easily be
    constructed. A vertex <C>v</C> (in <A>digraph</A>) has colour <C>i</C> if
    and only if the vertex <C>v ^ p</C> (in the canonical representative) has
    colour <C>i</C>, where <C>p</C> is the permutation of the canonical
    labelling that acts on the vertices of <A>digraph</A>. In particular, if
    <A>colours</A> has the first form that is described above, then the
    colouring of the canonical representative is given by:

    <Log>gap> List(DigraphVertices(digraph), i -> colours[i / p]);</Log>

    On the other hand, if <A>colours</A> has the second form above, then the
    canonical representative has colouring:

    <Log>gap> OnTuplesSets(colours, p);</Log>

    <P/>

    <Example><![CDATA[
gap> digraph := DigraphFromDiSparse6String(".ImNS_AiB?qRN");
<immutable digraph with 10 vertices, 8 edges>
gap> colours := [[1, 2, 8, 9, 10], [3, 4, 5, 6, 7]];;
gap> p := BlissCanonicalLabelling(digraph, colours);
(1,5,8,4,10,3,9)(6,7)
gap> OnDigraphs(digraph, p);
<immutable digraph with 10 vertices, 8 edges>
gap> OnTuplesSets(colours, p);
[ [ 1, 2, 3, 4, 5 ], [ 6, 7, 8, 9, 10 ] ]
gap> colours := [1, 1, 1, 1, 2, 3, 1, 3, 2, 1];;
gap> p := BlissCanonicalLabelling(digraph, colours);
(1,6,9,7)(3,4,5,8,10)
gap> OnDigraphs(digraph, p);
<immutable digraph with 10 vertices, 8 edges>
gap> List(DigraphVertices(digraph), i -> colours[i / p]);
[ 1, 1, 1, 1, 1, 1, 2, 2, 3, 3 ]]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsIsomorphicDigraph">
<ManSection>
  <Oper Name="IsIsomorphicDigraph" Label="for digraphs" Arg="digraph1, digraph2"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This operation returns <K>true</K> if there exists an isomorphism from the
    digraph <A>digraph1</A> to the digraph <A>digraph2</A>.  See <Ref
      Oper="IsomorphismDigraphs" Label="for digraphs" /> for more information
    about isomorphisms of digraphs. <P/>

    By default, an isomorphism is found using the canonical labellings of the
    digraphs obtained from &BLISS; by Tommi Junttila
    and Petteri Kaski. If &NautyTracesInterface; is available, then &NAUTY; by
    Brendan Mckay and Adolfo Piperno can be used instead; see
    <Ref Func="DigraphsUseBliss"/>, and <Ref Func="DigraphsUseNauty"/>.

    <Example><![CDATA[
gap> digraph1 := CycleDigraph(4);
<immutable cycle digraph with 4 vertices>
gap> digraph2 := CycleDigraph(5);
<immutable cycle digraph with 5 vertices>
gap> IsIsomorphicDigraph(digraph1, digraph2);
false
gap> digraph2 := DigraphReverse(digraph1);
<immutable digraph with 4 vertices, 4 edges>
gap> IsIsomorphicDigraph(digraph1, digraph2);
true
gap> digraph1 := Digraph([[3], [], []]);
<immutable digraph with 3 vertices, 1 edge>
gap> digraph2 := Digraph([[], [], [2]]);
<immutable digraph with 3 vertices, 1 edge>
gap> IsIsomorphicDigraph(digraph1, digraph2);
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsIsomorphicDigraphColours">
<ManSection>
  <Oper Name="IsIsomorphicDigraph" Label="for digraphs and homogeneous lists"
    Arg="digraph1, digraph2, colours1, colours2"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This operation tests for isomorphism of coloured digraphs.  A coloured
    digraph can be specified by its underlying digraph <A>digraph1</A> and its
    colouring <A>colours1</A>.  Let <C>n</C> be the number of vertices of
    <A>digraph1</A>. The colouring <A>colours1</A> may have one of the following
    two forms:

    <List>
      <Item>
        a list of <C>n</C> integers, where <A>colours</A><C>[i]</C> is the
        colour of vertex <C>i</C>, using the colours <C>[1 .. m]</C> for some
        <C>m &lt;= n</C>; or
      </Item>
      <Item>
        a list of non-empty disjoint lists whose union is
        <C>DigraphVertices(<A>digraph</A>)</C>, such that
        <A>colours</A><C>[i]</C> is the list of all vertices with colour
        <C>i</C>.
      </Item>
    </List>

    If <A>digraph1</A> and <A>digraph2</A> are digraphs without multiple edges,
    and <A>colours1</A> and <A>colours2</A> are colourings of <A>digraph1</A>
    and <A>digraph2</A>, respectively, then this operation returns <K>true</K>
    if there exists an isomorphism between these two coloured digraphs.  See
    <Ref Oper="IsomorphismDigraphs" Label="for digraphs and homogeneous lists"
      /> for more information about isomorphisms of coloured digraphs. <P/>

    By default, an isomorphism is found using the canonical labellings of the
    digraphs obtained from &BLISS; by Tommi Junttila
    and Petteri Kaski. If &NautyTracesInterface; is available, then &NAUTY; by
    Brendan Mckay and Adolfo Piperno can be used instead; see
    <Ref Func="DigraphsUseBliss"/>, and <Ref Func="DigraphsUseNauty"/>.

    <Example><![CDATA[
gap> digraph1 := ChainDigraph(4);
<immutable chain digraph with 4 vertices>
gap> digraph2 := ChainDigraph(3);
<immutable chain digraph with 3 vertices>
gap> IsIsomorphicDigraph(digraph1, digraph2,
>  [[1, 4], [2, 3]], [[1, 2], [3]]);
false
gap> digraph2 := DigraphReverse(digraph1);
<immutable digraph with 4 vertices, 3 edges>
gap> IsIsomorphicDigraph(digraph1, digraph2,
>  [1, 1, 1, 1], [1, 1, 1, 1]);
true
gap> IsIsomorphicDigraph(digraph1, digraph2,
>  [1, 2, 2, 1], [1, 2, 2, 1]);
true
gap> IsIsomorphicDigraph(digraph1, digraph2,
>  [1, 1, 2, 2], [1, 1, 2, 2]);
false]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsomorphismDigraphs">
<ManSection>
  <Oper Name="IsomorphismDigraphs" Label="for digraphs" Arg="digraph1, digraph2"/>
  <Returns> A permutation, or a pair of permutations, or <K>fail</K>.</Returns>
  <Description>
    This operation returns an isomorphism between the digraphs <A>digraph1</A>
    and <A>digraph2</A> if one exists, else this operation returns <K>fail</K>.
    <P/>

    An <E>isomorphism</E> from a digraph <A>digraph1</A> to a digraph
    <A>digraph2</A> is a bijection <C>p</C> from the vertices of
    <A>digraph1</A> to the vertices of <A>digraph2</A> with the following
    property: for all vertices <C>i</C> and <C>j</C> of <A>digraph1</A>,
    <C>[i, j]</C> is an edge of <A>digraph1</A> if and only if <C>[i ^ p, j
      ^ p]</C> is an edge of <A>digraph2</A>. <P/>

    If there exists such an isomorphism, then this operation returns one.
    The form of this isomorphism is a permutation <C>p</C> of the vertices of
    <A>digraph1</A> such that <P/>

    <C>OnDigraphs(<A>digraph1</A>, p) = digraph2</C>.

    By default, an isomorphism is found using the canonical labellings of the
    digraphs obtained from &BLISS; by Tommi Junttila
    and Petteri Kaski. If &NautyTracesInterface; is available, then &NAUTY; by
    Brendan Mckay and Adolfo Piperno can be used instead; see
    <Ref Func="DigraphsUseBliss"/>, and <Ref Func="DigraphsUseNauty"/>.

    <Example><![CDATA[
gap> digraph1 := CycleDigraph(4);
<immutable cycle digraph with 4 vertices>
gap> digraph2 := CycleDigraph(5);
<immutable cycle digraph with 5 vertices>
gap> IsomorphismDigraphs(digraph1, digraph2);
fail
gap> digraph1 := CompleteBipartiteDigraph(10, 5);
<immutable complete bipartite digraph with bicomponent sizes 10 and 5>
gap> digraph2 := CompleteBipartiteDigraph(5, 10);
<immutable complete bipartite digraph with bicomponent sizes 5 and 10>
gap> p := IsomorphismDigraphs(digraph1, digraph2);
(1,6,11)(2,7,12)(3,8,13)(4,9,14)(5,10,15)
gap> OnDigraphs(digraph1, p) = digraph2;
true
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsomorphismDigraphsColours">
<ManSection>
  <Oper Name="IsomorphismDigraphs" Label="for digraphs and homogeneous lists"
    Arg="digraph1, digraph2, colours1, colours2"/>
  <Returns> A permutation, or <K>fail</K>.</Returns>
  <Description>
    This operation searches for an isomorphism between coloured digraphs.  A
    coloured digraph can be specified by its underlying digraph <A>digraph1</A>
    and its colouring <A>colours1</A>.  Let <C>n</C> be the number of vertices
    of <A>digraph1</A>. The colouring <A>colours1</A> may have one of the
    following two forms:

    <List>
      <Item>
        a list of <C>n</C> integers, where <A>colours</A><C>[i]</C> is the
        colour of vertex <C>i</C>, using the colours <C>[1 .. m]</C> for some
        <C>m &lt;= n</C>; or
      </Item>
      <Item>
        a list of non-empty disjoint lists whose union is
        <C>DigraphVertices(<A>digraph</A>)</C>, such that
        <A>colours</A><C>[i]</C> is the list of all vertices with colour
        <C>i</C>.
      </Item>
    </List>

    An <E>isomorphism</E> between coloured digraphs is an isomorphism between
    the underlying digraphs that preserves the colourings.  See <Ref
      Oper="IsomorphismDigraphs" Label="for digraphs"/> for more information
    about isomorphisms of digraphs. More precisely, let <C>f</C> be an
    isomorphism of digraphs from the digraph <A>digraph1</A> (with colouring
    <A>colours1</A>) to the digraph <A>digraph2</A> (with colouring
    <A>colours2</A>), and let <C>p</C> be the permutation of the vertices of
    <A>digraph1</A> that corresponds to <C>f</C>.  Then <C>f</C> preserves the
    colourings of <A>digraph1</A> and <A>digraph2</A> – and hence is an
    isomorphism of coloured digraphs – if <C><A>colours1</A>[i] =
      <A>colours2</A>[i ^ p]</C> for all vertices <C>i</C> in <A>digraph1</A>.
    <P/>

    This operation returns such an isomorphism if one exists, else it returns
    <K>fail</K>. <P/>

    By default, an isomorphism is found using the canonical labellings of the
    digraphs obtained from &BLISS; by Tommi Junttila
    and Petteri Kaski. If &NautyTracesInterface; is available, then &NAUTY; by
    Brendan Mckay and Adolfo Piperno can be used instead; see
    <Ref Func="DigraphsUseBliss"/>, and <Ref Func="DigraphsUseNauty"/>.

    <Example><![CDATA[
gap> digraph1 := ChainDigraph(4);
<immutable chain digraph with 4 vertices>
gap> digraph2 := ChainDigraph(3);
<immutable chain digraph with 3 vertices>
gap> IsomorphismDigraphs(digraph1, digraph2,
>  [[1, 4], [2, 3]], [[1, 2], [3]]);
fail
gap> digraph2 := DigraphReverse(digraph1);
<immutable digraph with 4 vertices, 3 edges>
gap> colours1 := [1, 1, 1, 1];;
gap> colours2 := [1, 1, 1, 1];;
gap> p := IsomorphismDigraphs(digraph1, digraph2, colours1, colours2);
(1,4)(2,3)
gap> OnDigraphs(digraph1, p) = digraph2;
true
gap> List(DigraphVertices(digraph1), i -> colours1[i ^ p]) = colours2;
true
gap> colours1 := [1, 1, 2, 2];;
gap> colours2 := [2, 2, 1, 1];;
gap> p := IsomorphismDigraphs(digraph1, digraph2, colours1, colours2);
(1,4)(2,3)
gap> OnDigraphs(digraph1, p) = digraph2;
true
gap> List(DigraphVertices(digraph1), i -> colours1[i ^ p]) = colours2;
true
gap> IsomorphismDigraphs(digraph1, digraph2,
>  [1, 1, 2, 2], [1, 1, 2, 2]);
fail]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="BlissCanonicalDigraph">
<ManSection>
  <Attr Name="BlissCanonicalDigraph" Arg="digraph"/>
  <Attr Name="NautyCanonicalDigraph" Arg="digraph"/>
  <Returns>A digraph.</Returns>
  <Description>
    The attribute <C>BlissCanonicalLabelling</C> returns the canonical
    representative found by applying <Ref Attr="BlissCanonicalLabelling"
      Label="for a digraph"/>. The digraph returned is canonical in the sense
    that

    <List>
      <Item>
        <C>BlissCanonicalDigraph(<A>digraph</A>)</C> and <A>digraph</A> are
        isomorphic as digraphs; and
      </Item>
      <Item>
        If <C>gr</C> is any digraph then <C>BlissCanonicalDigraph(gr)</C>
        and <C>BlissCanonicalDigraph(<A>digraph</A>)</C> are equal if and only
        if <C>gr</C> and <A>digraph</A> are isomorphic as digraphs.
      </Item>
    </List>

    Analogously, the attribute <C>NautyCanonicalLabelling</C> returns the
    canonical representative found by applying <Ref
      Attr="NautyCanonicalLabelling" Label="for a digraph"/>.
    <P/>

    &MUTABLE_RECOMPUTED_ATTR;

    <Example><![CDATA[
gap> digraph := Digraph([[1], [2, 3], [3], [1, 2, 3]]);
<immutable digraph with 4 vertices, 7 edges>
gap> canon := BlissCanonicalDigraph(digraph);
<immutable digraph with 4 vertices, 7 edges>
gap> OutNeighbours(canon);
[ [ 1 ], [ 2 ], [ 3, 2 ], [ 1, 3, 2 ] ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsDigraphAutomorphism">
<ManSection>
  <Oper Name="IsDigraphIsomorphism" Arg="src, ran, x" 
        Label="for digraphs and transformation or permutation"/>
  <Oper Name="IsDigraphIsomorphism" Arg="src, ran, x, col1, col2"/>
  <Oper Name="IsDigraphAutomorphism" Arg="digraph, x" 
        Label="for a digraph and a transformation or permutation"/>
  <Oper Name="IsDigraphAutomorphism" Arg="digraph, x, col"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    <C>IsDigraphIsomorphism</C> returns <K>true</K> if the permutation or
    transformation <A>x</A> is an isomorphism from the digraph <A>src</A> to
    the digraph <A>ran</A>.
    <P/>

    <C>IsDigraphAutomorphism</C> returns <K>true</K> if the permutation or
    transformation <A>x</A> is an automorphism of the digraph <A>digraph</A>.
    <P/>

    A permutation or transformation <A>x</A> is an <E>isomorphism</E> from a
    digraph <A>src</A> to a digraph <A>ran</A> if the following hold:
    <List>
      <Item>
        <A>x</A> is a bijection from the vertices of <A>src</A> to those of
        <A>ran</A>;
      </Item>
      <Item>
        <C>[u ^ <A>x</A>, v ^ <A>x</A>]</C> is an edge of
        <A>ran</A> if and only if <C>[u, v]</C> is an
        edge of <A>src</A>; and
      </Item>
      <Item>
        <A>x</A> fixes every <C>i</C> which is not a vertex of <A>src</A>.
      </Item>
    </List>
    See also <Ref Attr="AutomorphismGroup" Label="for a digraph"
      />.<P/>

    If <A>col1</A> and <A>col2</A>, or <A>col</A>, are given, then they must
    represent vertex colourings; see 
    <Ref Oper="AutomorphismGroup" Label="for a digraph and a homogeneous list"/> 
    for details of the permissible values for
    these arguments. The homomorphism must then also have the property:

    <List>
      <Item>
        <C>col1[i] = col2[i ^ x]</C> for all vertices <C>i</C> of <A>src</A>,
        for <C>IsDigraphIsomorphism</C>. </Item>
      <Item>
        <C>col[i] = col[i ^ x]</C> for all vertices <C>i</C> of <A>digraph</A>,
        for <C>IsDigraphAutomorphism</C>. </Item>
    </List>

    For some digraphs, it can be faster to use <C>IsDigraphAutomorphism</C>
    than to test membership in the automorphism group of <A>digraph</A>.

    <Example><![CDATA[
gap> src := Digraph([[1], [1, 2], [1, 3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsDigraphAutomorphism(src, (1, 2, 3));
false
gap> IsDigraphAutomorphism(src, (2, 3));
true
gap> IsDigraphAutomorphism(src, (2, 3), [2, 1, 1]);
true
gap> IsDigraphAutomorphism(src, (2, 3), [2, 2, 1]);
false
gap> IsDigraphAutomorphism(src, (2, 3)(4, 5));
true
gap> IsDigraphAutomorphism(src, (1, 4));
false
gap> IsDigraphAutomorphism(src, ());
true
gap> ran := Digraph([[2, 1], [2], [2, 3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsDigraphIsomorphism(src, ran, (1, 2));
true
gap> IsDigraphIsomorphism(ran, src, (1, 2));
true
gap> IsDigraphIsomorphism(ran, src, (1, 2));
true
gap> IsDigraphIsomorphism(src, Digraph([[3], [1, 3], [2]]), (1, 2, 3));
false
gap> IsDigraphIsomorphism(src, ran, (1, 2), [1, 2, 3], [2, 1, 3]);
true
gap> IsDigraphIsomorphism(src, ran, (1, 2), [1, 2, 2], [2, 1, 3]);
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>
