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

<#GAPDoc Label="IsDigraph">
<ManSection>
  <Filt Name="IsDigraph" Type='Category'/>
  <Description>
    Every  digraph in  &Digraphs;  belongs  to  the  category
    <C>IsDigraph</C>.  Some basic attributes and operations for digraphs
    are <Ref Attr="DigraphVertices"/>, <Ref Attr="DigraphEdges"/>, and
    <Ref Attr="OutNeighbours"/>.
    </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsDigraphWithAdjacencyFunction">
<ManSection>
  <Filt Name="IsDigraphWithAdjacencyFunction" Type='Category'/>
  <Description>
    <C>IsDigraphWithAdjacencyFunction</C> is a subcategory of <C>IsDigraph</C>.
    Digraphs that are <E>created</E> using an adjacency function are constructed
    in this category.
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsCayleyDigraph">
<ManSection>
  <Filt Name="IsCayleyDigraph" Type='Category'/>
  <Description>
    <C>IsCayleyDigraph</C> is a subcategory of <C>IsDigraph</C>. Digraphs that
    are Cayley digraphs of a group and that are constructed by the operation
    <Ref Oper="CayleyDigraph"/> are constructed in this category, and are
    always immutable.
    </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsImmutableDigraph">
<ManSection>
  <Filt Name="IsImmutableDigraph" Type='Category'/>
  <Description>
    <C>IsImmutableDigraph</C> is a subcategory of <Ref Filt="IsDigraph" />.
    Digraphs that lie in <C>IsImmutableDigraph</C> are immutable and
    attribute-storing. In particular, they lie in
    <Ref Filt="IsAttributeStoringRep" BookName="ref" />. <P/>

    A mutable digraph may be converted to an immutable
    digraph that lies in the category <C>IsImmutableDigraph</C> by calling
    <Ref Func="MakeImmutable" BookName="ref"/> on the digraph.<P/>

    The operation <Ref Oper="DigraphMutableCopy"/> can be used
    to construct a mutable copy of an immutable digraph. It is however not
    possible to convert an immutable digraph into a mutable digraph in-place.
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsMutableDigraph">
<ManSection>
  <Filt Name="IsMutableDigraph" Type='Category'/>
  <Description>
    <C>IsMutableDigraph</C> is a synonym for <Ref Filt="IsDigraph" /> and <Ref
    Filt="IsMutable" BookName="ref" />.  A mutable digraph may be changed
    in-place by methods in the &Digraphs; package, and is not attribute-storing
    – see <Ref Filt="IsAttributeStoringRep" BookName="ref" />.
    <P/>

    A mutable digraph may be converted into an immutable attribute-storing
    digraph by calling <Ref Func="MakeImmutable" BookName="ref"/> on the
    digraph.
    </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphByOutNeighboursType">
<ManSection>
  <Var Name="DigraphByOutNeighboursType"/>
  <Fam Name="DigraphFamily"/>
  <Description>
    The type of all digraphs is <C>DigraphByOutNeighboursType</C>.
    The family of all digraphs is <C>DigraphFamily</C>.
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsDigraphByOutNeighboursRep">
<ManSection>
  <Filt Name="IsDigraphByOutNeighboursRep" Type="Representation"/>
  <Description>
    This is the representation for digraphs that are defined by their list of
    out-neighbours. Currently, every digraph in the package belongs to this
    representation, but more representations might be added in the future. 
    <P/>

    See also <Ref Attr="OutNeighbours"/>.
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="Digraph">
<ManSection>
  <Oper Name = "Digraph" Arg = "[filt,] obj[, source, range]"/>
  <Oper Name = "Digraph" Arg = "[filt,] list, func" 
    Label = "for a list and function"/>
  <Oper Name = "Digraph" Arg = "[filt,] G, list, act, adj"
    Label = "for a group, list, function, and function"/>
  <Returns>A digraph.</Returns>
  <Description>
    If the optional first argument <A>filt</A> is present, then this should
    specify the category or representation the digraph being created will
    belong to. For example, if <A>filt</A> is <Ref Filt="IsMutableDigraph"/>,
    then the digraph being created will be mutable, if <A>filt</A> is <Ref
    Filt="IsImmutableDigraph"/>, then the digraph will be immutable. 
    If the optional first argument <A>filt</A> is not present, then <Ref
    Filt="IsImmutableDigraph"/> is used by default.
    <List>
      <Mark>for a list (i.e. an adjacency list)</Mark>
      <Item>
        if <A>obj</A> is a list of lists of positive integers in
        the range from <C>1</C> to <C>Length(<A>obj</A>)</C>, then this function
        returns the digraph with vertices
        <M>E ^ 0 = </M><C>[1 .. Length(<A>obj</A>)]</C>,
        and edges corresponding to the entries of <A>obj</A>. <P/>

        More precisely, there is an edge from vertex <C>i</C> to <C>j</C> if and
        only if <C>j</C> is in <C><A>obj</A>[i]</C>; the source of this edge is
        <C>i</C> and the range is <C>j</C>. If <C>j</C> occurs in
        <C><A>obj</A>[i]</C> with multiplicity <C>k</C>, then there are <C>k</C>
        edges from <C>i</C> to <C>j</C>.
      </Item>

      <Mark>for three lists</Mark>
      <Item>
        if <A>obj</A> is a duplicate-free list, and <A>source</A> and
        <A>range</A> are lists of equal length consisting of positive integers
        in the list <C>[1 .. Length(<A>obj</A>)]</C>, then this function
        returns a digraph with vertices
        <M>E ^ 0 = </M><C>[1 .. Length(<A>obj</A>)]</C>, and
        <C>Length(<A>source</A>)</C> edges.  For each <C>i</C> in
        <C>[1 .. Length(<A>source</A>)]</C> there exists an edge with source
        vertex <C>source[i]</C> and range vertex <C>range[i]</C>.
        See <Ref Attr="DigraphSource"/> and <Ref Attr="DigraphRange"/>.
        <P/>

        The vertices of the digraph will be labelled by the elements of
        <A>obj</A>.
      </Item>

      <Mark>for an integer, and two lists</Mark>
      <Item>
        if <A>obj</A> is an integer, and <A>source</A> and
        <A>range</A> are lists of equal length consisting of positive integers
        in the list <C>[1 .. <A>obj</A>]</C>, then this function
        returns a digraph with vertices
        <M>E ^ 0 = </M><C>[1 .. <A>obj</A>]</C>, and
        <C>Length(<A>source</A>)</C> edges.  For each <C>i</C> in
        <C>[1 .. Length(<A>source</A>)]</C> there exists an edge with source
        vertex <C>source[i]</C> and range vertex <C>range[i]</C>.
        See <Ref Attr="DigraphSource"/> and <Ref Attr="DigraphRange"/>.
      </Item>

      <Mark>for a list and a function</Mark>
      <Item>
        if <A>list</A> is a list and <A>func</A> is a function taking 2
        arguments that are elements of <A>list</A>, and <A>func</A> returns
        <K>true</K> or <K>false</K>, then this operation creates a digraph with
        vertices <C>[1 .. Length(<A>list</A>)]</C> and an edge from vertex
        <C>i</C> to vertex <C>j</C> if and only if
        <C><A>func</A>(<A>list</A>[i], <A>list</A>[j])</C> returns <K>true</K>.
      </Item>

      <Mark>for a group, a list, and two functions</Mark>
      <Item>
        The arguments will be <A>G, list, act, adj</A>. <P/>

        Let <A>G</A> be a group acting on the objects in <A>list</A> via
        the action <A>act</A>, and let <A>adj</A> be a function taking
        two objects from <A>list</A> as arguments and returning <C>true</C> or
        <C>false</C>. The function <A>adj</A> will describe the adjacency
        between objects from <A>list</A>, which is invariant under the action of
        <A>G</A>. This variant of the constructor returns a digraph with
        vertices the objects of <A>list</A> and directed edges <C>[x, y]</C>
        when <C>f(x, y)</C> is <C>true</C>. <P/>

        The action of the group <A>G</A> on the objects in <A>list</A> is stored
        in the attribute <Ref Attr="DigraphGroup"/>, and is used to speed up
        operations like <Ref Attr="DigraphDiameter"/>.
      </Item>

      <Mark>for a Grape package graph</Mark>
      <Item>
        if <A>obj</A> is a &Grape; package graph (i.e. a record for which the
        function <C>IsGraph</C> returns <K>true</K>), then this function returns
        a digraph isomorphic to <A>obj</A>.
      </Item>

      <Mark>for a binary relation</Mark>
      <Item>
        if <A>obj</A> is a binary relation on the points <C>[1 .. n]</C> for
        some posititve integer <M>n</M>, then this function returns the digraph
        defined by <A>obj</A>. Specifically, this function returns a digraph
        which has <M>n</M> vertices, and which has an edge with source <C>i</C>
        and range <C>j</C> if and only if <C>[i,j]</C> is a pair in
        the binary relation <A>obj</A>.
      </Item>
    </List>

    <Example><![CDATA[
gap> gr := Digraph([
> [2, 5, 8, 10], [2, 3, 4, 2, 5, 6, 8, 9, 10], [1],
> [3, 5, 7, 8, 10], [2, 5, 7], [3, 6, 7, 9, 10], [1, 4],
> [1, 5, 9], [1, 2, 7, 8], [3, 5]]);
<immutable multidigraph with 10 vertices, 38 edges>
gap> gr := Digraph(["a", "b", "c"], ["a"], ["b"]);
<immutable digraph with 3 vertices, 1 edge>
gap> gr := Digraph(5, [1, 2, 2, 4, 1, 1], [2, 3, 5, 5, 1, 1]);
<immutable multidigraph with 5 vertices, 6 edges>
gap> Petersen := Graph(SymmetricGroup(5), [[1, 2]], OnSets,
> function(x, y) return Intersection(x, y) = []; end);;
gap> Digraph(Petersen);
<immutable digraph with 10 vertices, 30 edges>
gap> gr := Digraph([1 .. 10], ReturnTrue);
<immutable digraph with 10 vertices, 100 edges>]]></Example>

      The next example illustrates the uses of the fourth and fifth variants of
      this constructor. The resulting digraph is a strongly regular graph, and
      it is actually the point graph of the van Lint-Schrijver partial
      geometry, <Cite Key="vLS81"/>.  The algebraic description
      is taken from the seminal paper of Calderbank and Kantor <Cite
        Key="CK86"/>.
<Example><![CDATA[
gap> f := GF(3 ^ 4);
GF(3^4)
gap> gamma := First(f, x -> Order(x) = 5);
Z(3^4)^64
gap> L := Union([Zero(f)], List(Group(gamma)));
[ 0*Z(3), Z(3)^0, Z(3^4)^16, Z(3^4)^32, Z(3^4)^48, Z(3^4)^64 ]
gap> omega := Union(List(L, x -> List(Difference(L, [x]), y -> x - y)));
[ Z(3)^0, Z(3), Z(3^4)^5, Z(3^4)^7, Z(3^4)^8, Z(3^4)^13, Z(3^4)^15, 
  Z(3^4)^16, Z(3^4)^21, Z(3^4)^23, Z(3^4)^24, Z(3^4)^29, Z(3^4)^31, 
  Z(3^4)^32, Z(3^4)^37, Z(3^4)^39, Z(3^4)^45, Z(3^4)^47, Z(3^4)^48, 
  Z(3^4)^53, Z(3^4)^55, Z(3^4)^56, Z(3^4)^61, Z(3^4)^63, Z(3^4)^64, 
  Z(3^4)^69, Z(3^4)^71, Z(3^4)^72, Z(3^4)^77, Z(3^4)^79 ]
gap> adj := function(x, y)
>   return x - y in omega;
> end;
function( x, y ) ... end
gap> digraph := Digraph(AsList(f), adj);
<immutable digraph with 81 vertices, 2430 edges>
gap> group := Group(Z(3));;
gap> act := \*;
<Operation "*">
gap> digraph := Digraph(group, List(f), act, adj);
<immutable digraph with 81 vertices, 2430 edges>
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphByAdjacencyMatrix">
<ManSection>
  <Oper Name="DigraphByAdjacencyMatrix" Arg="[filt, ]list"/>
  <Returns>A digraph.</Returns>
  <Description>
    If the optional first argument <A>filt</A> is present, then this should
    specify the category or representation the digraph being created will
    belong to. For example, if <A>filt</A> is <Ref Filt="IsMutableDigraph"/>,
    then the digraph being created will be mutable, if <A>filt</A> is <Ref
    Filt="IsImmutableDigraph"/>, then the digraph will be immutable. 
    If the optional first argument <A>filt</A> is not present, then <Ref
    Filt="IsImmutableDigraph"/> is used by default.<P/>

    If <A>list</A> is the adjacency matrix of a digraph in the sense of
    <Ref Attr="AdjacencyMatrix"/>, then this operation returns the digraph
    which is defined by <A>list</A>. <P/>

    Alternatively, if <A>list</A> is a square boolean matrix, then this
    operation returns the digraph with <C>Length(</C><A>list</A><C>)</C>
    vertices which has the edge <C>[i,j]</C> if and only if
    <A>list</A><C>[i][j]</C> is <K>true</K>. <P/>

    <Example><![CDATA[
gap> DigraphByAdjacencyMatrix([
> [0, 1, 0, 2, 0],
> [1, 1, 1, 0, 1],
> [0, 3, 2, 1, 1],
> [0, 0, 1, 0, 1],
> [2, 0, 0, 0, 0]]);
<immutable multidigraph with 5 vertices, 18 edges>
gap> D := DigraphByAdjacencyMatrix([
> [true, false, true],
> [false, false, true],
> [false, true, false]]);
<immutable digraph with 3 vertices, 4 edges>
gap> OutNeighbours(D);
[ [ 1, 3 ], [ 3 ], [ 2 ] ]
gap> D := DigraphByAdjacencyMatrix(IsMutableDigraph, 
> [[true, false, true],
>  [false, false, true],
>  [false, true, false]]);
<mutable digraph with 3 vertices, 4 edges>
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphByEdges">
<ManSection>
  <Oper Name="DigraphByEdges" Arg="[filt, ]list[, n]"/>
  <Returns>A digraph.</Returns>
  <Description>
    If the optional first argument <A>filt</A> is present, then this should
    specify the category or representation the digraph being created will
    belong to. For example, if <A>filt</A> is <Ref Filt="IsMutableDigraph"/>,
    then the digraph being created will be mutable, if <A>filt</A> is <Ref
    Filt="IsImmutableDigraph"/>, then the digraph will be immutable. 
    If the optional first argument <A>filt</A> is not present, then <Ref
    Filt="IsImmutableDigraph"/> is used by default.<P/>

    If <A>list</A> is list of pairs of positive integers, then this function
    returns the digraph with the minimum number of vertices <C>m</C> such that
    its list equal <A>list</A>.<P/>

    If the optional second argument <A>n</A> is a positive integer with
    <C><A>n</A> >= m</C> (with <C>m</C> defined as above),
    then this function returns the digraph with <A>n</A> vertices and list
    <A>list</A>. <P/>

    See <Ref Attr="DigraphEdges"/>.

    <Example><![CDATA[
gap> DigraphByEdges(
> [[1, 3], [2, 1], [2, 3], [2, 5], [3, 6],
>  [4, 6], [5, 2], [5, 4], [5, 6], [6, 6]]);
<immutable digraph with 6 vertices, 10 edges>
gap> DigraphByEdges(
> [[1, 3], [2, 1], [2, 3], [2, 5], [3, 6],
>  [4, 6], [5, 2], [5, 4], [5, 6], [6, 6]], 12);
<immutable digraph with 12 vertices, 10 edges>
gap> DigraphByEdges(IsMutableDigraph, 
> [[1, 3], [2, 1], [2, 3], [2, 5], [3, 6],
>  [4, 6], [5, 2], [5, 4], [5, 6], [6, 6]], 12);
<mutable digraph with 12 vertices, 10 edges>
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphByInNeighbours">
<ManSection>
  <Oper Name="DigraphByInNeighbours" Arg="[filt, ]list"/>
  <Oper Name="DigraphByInNeighbors" Arg="[filt, ]list"/>
  <Returns>A digraph.</Returns>
  <Description>
  If the optional first argument <A>filt</A> is present, then this should
  specify the category or representation the digraph being created will
  belong to. For example, if <A>filt</A> is <Ref Filt="IsMutableDigraph"/>,
  then the digraph being created will be mutable, if <A>filt</A> is <Ref
  Filt="IsImmutableDigraph"/>, then the digraph will be immutable. 
  If the optional first argument <A>filt</A> is not present, then <Ref
  Filt="IsImmutableDigraph"/> is used by default.<P/>

  If <A>list</A> is a list of lists of positive integers list the range
  <C>[1 .. Length(<A>list</A>)]</C>, then this function returns the
  digraph with vertices <M>E^0=</M><C>[1 .. Length(<A>list</A>)]</C>, and
  edges corresponding to the entries of <A>list</A>. More precisely, there is an
  edge with source vertex <C>i</C> and range vertex <C>j</C> if <C>i</C> is list
  <C><A>list</A>[j]</C>. <P/>

  If <C>i</C> occurs list <C><A>list</A>[j]</C> with multiplicity <C>k</C>,
  then there are <C>k</C> multiple edges from <C>i</C> to <C>j</C>. <P/>

  See <Ref Attr="InNeighbours"/>.

    <Example><![CDATA[
gap> D := DigraphByInNeighbours([
> [2, 5, 8, 10], [2, 3, 4, 5, 6, 8, 9, 10],
> [1], [3, 5, 7, 8, 10], [2, 5, 7], [3, 6, 7, 9, 10], [1, 4],
> [1, 5, 9], [1, 2, 7, 8], [3, 5]]);
<immutable digraph with 10 vertices, 37 edges>
gap> D := DigraphByInNeighbours([[2, 3, 2], [1], [1, 2, 3]]);
<immutable multidigraph with 3 vertices, 7 edges>
gap> D := DigraphByInNeighbours(IsMutableDigraph, 
>                               [[2, 3, 2], [1], [1, 2, 3]]);
<mutable multidigraph with 3 vertices, 7 edges>
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsDigraph">
<ManSection>
  <Oper Name="AsDigraph" Arg="[filt, ]trans[, n]"/>
  <Returns>A digraph, or <K>fail</K>.</Returns>
  <Description>
    If the optional first argument <A>filt</A> is present, then this should
    specify the category or representation the digraph being created will
    belong to. For example, if <A>filt</A> is <Ref Filt="IsMutableDigraph"/>,
    then the digraph being created will be mutable, if <A>filt</A> is <Ref
    Filt="IsImmutableDigraph"/>, then the digraph will be immutable. 
    If the optional first argument <A>filt</A> is not present, then <Ref
    Filt="IsImmutableDigraph"/> is used by default.<P/>

    If <A>trans</A> is a transformation, and <A>n</A> is a non-negative integer
    such that the restriction of <A>trans</A> to <C>[1 .. <A>n</A>]</C> defines
    a transformation of <C>[1 .. <A>n</A>]</C>, then <C>AsDigraph</C>
    returns the functional digraph with <A>n</A> vertices defined by
    <A>trans</A>. See <Ref Prop="IsFunctionalDigraph"/>.
    <P/>

    Specifically, the digraph returned by <C>AsDigraph</C> has  <A>n</A> edges:
    for each vertex <C>x</C> in <C>[1 .. <A>n</A>]</C>, there is a unique edge
    with source <C>x</C>; this edge has range <C>x^<A>trans</A></C>.
    <P/>

    If the optional second argument <A>n</A> is not supplied, then the degree of
    the transformation <A>trans</A> is used by default.  If the restriction of
    <A>trans</A> to <C>[1 .. <A>n</A>]</C> does not define a transformation of
    <C>[1 .. <A>n</A>]</C>, then <C>AsDigraph(<A>trans</A>, <A>n</A>)</C>
    returns <K>fail</K>.

    <Example><![CDATA[
gap> f := Transformation([4, 3, 3, 1, 7, 9, 10, 4, 2, 3]);
Transformation( [ 4, 3, 3, 1, 7, 9, 10, 4, 2, 3 ] )
gap> AsDigraph(f);
<immutable functional digraph with 10 vertices>
gap> AsDigraph(f, 4);
<immutable functional digraph with 4 vertices>
gap> AsDigraph(f, 5);
fail
gap> b := BinaryRelationOnPoints(
> [[3], [1, 3, 5], [1], [1, 2, 4], [2, 3, 5]]);
Binary Relation on 5 points
gap> D := AsDigraph(b);
<immutable digraph with 5 vertices, 11 edges>
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphXCopy">
<ManSection>
  <Oper Name="DigraphImmutableCopy" Arg="digraph"/>
  <Oper Name="DigraphMutableCopy" Arg="digraph"/>
  <Oper Name="DigraphCopySameMutability" Arg="digraph"/>
  <Oper Name="DigraphCopy" Arg="digraph"/>
  <Returns>A digraph.</Returns>
  <Description>
    Each of these operations returns a new copy of <A>digraph</A>,
    of the appropriate mutability, retaining none of the attributes or
    properties of <A>digraph</A>. <P/>

    <C>DigraphCopy</C> is a synonym for <C>DigraphCopySameMutability</C>.
<Example><![CDATA[
gap> D := CycleDigraph(10);
<immutable cycle digraph with 10 vertices>
gap> DigraphCopy(D) = D;
true
gap> IsIdenticalObj(DigraphCopy(D), D);
false
gap> DigraphMutableCopy(D);
<mutable digraph with 10 vertices, 10 edges>
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphXCopyIfY">
<ManSection>
  <Oper Name="DigraphImmutableCopyIfImmutable" Arg="digraph"/>
  <Oper Name="DigraphImmutableCopyIfMutable" Arg="digraph"/>
  <Oper Name="DigraphMutableCopyIfMutable" Arg="digraph"/>
  <Oper Name="DigraphMutableCopyIfImmutable" Arg="digraph"/>
  <Returns>A digraph.</Returns>
  <Description>
    Each of these operations returns either the original argument
    <A>digraph</A>, or a new copy of <A>digraph</A> of the appropriate
    mutability, according to the mutability of <A>digraph</A>.
<Example><![CDATA[
gap> C := CycleDigraph(10);
<immutable cycle digraph with 10 vertices>
gap> D := DigraphImmutableCopyIfImmutable(C);
<immutable digraph with 10 vertices, 10 edges>
gap> IsIdenticalObj(C, D);
false
gap> C = D;
true
gap> D := DigraphImmutableCopyIfMutable(C);
<immutable cycle digraph with 10 vertices>
gap> IsIdenticalObj(C, D);
true
gap> C = D;
true
gap> D := DigraphMutableCopyIfMutable(C);
<immutable cycle digraph with 10 vertices>
gap> IsMutableDigraph(D);
false
gap> D := DigraphMutableCopyIfImmutable(C);
<mutable digraph with 10 vertices, 10 edges>
gap> IsMutableDigraph(D);
true
gap> C := CycleDigraph(IsMutableDigraph, 10);
<mutable digraph with 10 vertices, 10 edges>
gap> D := DigraphImmutableCopyIfImmutable(C);
<mutable digraph with 10 vertices, 10 edges>
gap> IsIdenticalObj(C, D);
true
gap> C = D;
true
gap> D := DigraphImmutableCopyIfMutable(C);
<immutable digraph with 10 vertices, 10 edges>
gap> IsIdenticalObj(C, D);
false
gap> C = D;
true
gap> D := DigraphMutableCopyIfMutable(C);
<mutable digraph with 10 vertices, 10 edges>
gap> IsMutableDigraph(D);
true
gap> D := DigraphMutableCopyIfImmutable(C);
<mutable digraph with 10 vertices, 10 edges>
gap> IsIdenticalObj(C, D);
true
gap> IsMutableDigraph(D);
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsBinaryRelation">
<ManSection>
  <Oper Name="AsBinaryRelation" Arg="digraph"/>
  <Returns>A binary relation.</Returns>
  <Description>
    If <A>digraph</A> is a digraph with a positive number of vertices
    <M>n</M>, and no multiple edges, then this operation returns a binary
    relation on the points <C>[1..n]</C>.
    The pair <C>[i,j]</C> is in the binary relation if and only if
    <C>[i,j]</C> is an edge in <A>digraph</A>.
    <P/>
<Example><![CDATA[
gap> D := Digraph([[3, 2], [1, 2], [2], [3, 4]]);
<immutable digraph with 4 vertices, 7 edges>
gap> AsBinaryRelation(D);
Binary Relation on 4 points
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsSemigroup">
  <ManSection>
    <Oper Name="AsSemigroup" Arg="filt, digraph"
      Label="for a filter and a digraph"/>
    <Oper Name="AsMonoid" Arg="filt, digraph"/>
    <Returns>A semilattice of partial perms.</Returns>
    <Description>
      The operation <C>AsSemigroup</C> requires that <A>filt</A> be equal to
      <Ref Filt="IsPartialPermSemigroup" BookName="ref"/>.
      If <A>digraph</A> is a
      <Ref Prop="IsJoinSemilatticeDigraph"/> or <Ref Prop="IsLatticeDigraph"/>
      then <C>AsSemigroup</C> returns a semigroup of partial perms which is
      isomorphic to the semigroup whose elements are the vertices of
      <A>digraph</A> with the binary operation
      <Ref Oper="PartialOrderDigraphJoinOfVertices"
        Label="for a digraph and two vertices"/>. If <A>digraph</A>
      satisfies  <Ref Prop="IsMeetSemilatticeDigraph"/> but not
      <Ref Prop="IsJoinSemilatticeDigraph"/> then
      <C>AsSemigroup</C> returns a semigroup of partial perms which is
      isomorphic to the semigroup whose elements are the vertices of
      <A>digraph</A> with the binary operation
      <Ref Oper="PartialOrderDigraphMeetOfVertices"/>.
      <P/>

      The operation <C>AsMonoid</C> behaves similarly to <C>AsSemigroup</C>
      except that <A>filt</A> may also be equal to
      <Ref Filt="IsPartialPermMonoid" BookName="ref"/>,
      <A>digraph</A> must satisfy <Ref Prop="IsLatticeDigraph"/>, and the
      output satisfies <Ref Filt="IsMonoid" BookName="ref"/>. <P/>

      The output of both of these operations is guaranteed to be of minimal
      degree (see <Ref Attr="DegreeOfPartialPermSemigroup" BookName="ref"/>).
      Furthermore the <Ref Attr="GeneratorsOfSemigroup" BookName="ref"/> of
      the output is guaranteed to be the unique generating set of minimal size.
      <Example><![CDATA[
gap> di := Digraph([[1], [1, 2], [1, 3], [1, 4], [1, 2, 3, 5]]);
<immutable digraph with 5 vertices, 11 edges>
gap> S := AsSemigroup(IsPartialPermSemigroup, di);
<partial perm semigroup of rank 3 with 4 generators>
gap> ForAll(Elements(S), IsIdempotent);
true
gap> IsInverseSemigroup(S);
true
gap> Size(S);
5
gap> di := Digraph([[1], [1, 2], [1, 2, 3]]);
<immutable digraph with 3 vertices, 6 edges>
gap> M := AsMonoid(IsPartialPermMonoid, di);
<partial perm monoid of rank 2 with 3 generators>
gap> Size(M);
3]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsSemigroupDigraph">
  <ManSection>
    <Oper Name="AsSemigroup" Arg="filt, digraph"
      Label="for a filter and a digraph"/>
    <Oper Name="AsMonoid" Arg="filt, digraph"/>
    <Returns>A semilattice of partial perms.</Returns>
    <Description>
      The operation <C>AsSemigroup</C> requires that <A>filt</A> be equal to
      <Ref Filt="IsPartialPermSemigroup" BookName="ref"/>.
      If <A>digraph</A> is a
      <Ref Prop="IsJoinSemilatticeDigraph"/> or <Ref Prop="IsLatticeDigraph"/>
      then <C>AsSemigroup</C> returns a semigroup of partial perms which is
      isomorphic to the semigroup whose elements are the vertices of
      <A>digraph</A> with the binary operation
      <Ref Oper="PartialOrderDigraphJoinOfVertices"/>.
      If <A>digraph</A>
      satisfies  <Ref Prop="IsMeetSemilatticeDigraph"/> but not
      <Ref Prop="IsJoinSemilatticeDigraph"/> then
      <C>AsSemigroup</C> returns a semigroup of partial perms which is
      isomorphic to the semigroup whose elements are the vertices of
      <A>digraph</A> with the binary operation
      <Ref Oper="PartialOrderDigraphMeetOfVertices"/>.
      <P/>

      The operation <C>AsMonoid</C> behaves similarly to <C>AsSemigroup</C>
      except that <A>filt</A> may also be equal to
      <Ref Filt="IsPartialPermMonoid" BookName="ref"/>,
      <A>digraph</A> must satisfy <Ref Prop="IsLatticeDigraph"/>, and the
      output satisfies <Ref Filt="IsMonoid" BookName="ref"/>. <P/>

      The output of both of these operations is guaranteed to be of minimal
      degree (see <Ref Attr="DegreeOfPartialPermSemigroup" BookName="ref"/>).
      Furthermore the <Ref Attr="GeneratorsOfSemigroup" BookName="ref"/> of
      the output is guaranteed to be the unique generating set of minimal size.
      <Example><![CDATA[
gap> di := Digraph([[1], [1, 2], [1, 3], [1, 4], [1, 2, 3, 5]]);
<immutable digraph with 5 vertices, 11 edges>
gap> S := AsSemigroup(IsPartialPermSemigroup, di);
<partial perm semigroup of rank 3 with 4 generators>
gap> ForAll(Elements(S), IsIdempotent);
true
gap> IsInverseSemigroup(S);
true
gap> Size(S);
5
gap> di := Digraph([[1], [1, 2], [1, 2, 3]]);
<immutable digraph with 3 vertices, 6 edges>
gap> M := AsMonoid(IsPartialPermMonoid, di);
<partial perm monoid of rank 2 with 3 generators>
gap> Size(M);
3]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsCliffordSemigroup">
  <ManSection>
    <Oper Name="AsSemigroup" Arg="filt, Y, gps, homs"
      Label="for a filter, semilattice digraph, and two lists"/>
    <Returns> A Clifford semigroup of partial perms. </Returns>
    <Description>
      The operation <C>AsSemigroup</C> requires that <A>filt</A> be equal to
      <Ref Filt="IsPartialPermSemigroup" BookName="ref"/>.
      If <A>Y</A> is a <Ref Prop="IsJoinSemilatticeDigraph"/> or
      <Ref Prop="IsMeetSemilatticeDigraph"/>,
      <A>gps</A> is a list of groups corresponding to each vertex, and
      <A>homs</A> is a list containing for each edge <C>(i, j)</C> in
      the transitive reduction of <A>digraph</A> a triple <C>[i, j, hom]</C>
      where <C>hom</C> is a group homomorphism from <C>gps[i]</C> to
      <C>gps[j]</C>, and the diagram of homomorphisms commutes, then
      <C>AsSemigroup</C> returns a semigroup of partial perms which is
      isomorphic to the strong semilattice of groups <M>S[Y; gps; homs]</M>.
      <Example><![CDATA[
gap> G1 := AlternatingGroup(4);;
gap> G2 := SymmetricGroup(2);;
gap> G3 := SymmetricGroup(3);;
gap> gr := Digraph([[1, 3], [2, 3], [3]]);;
gap> sgn := function(x)
> if SignPerm(x) = 1 then
> return ();
> fi;
> return (1, 2);
> end;;
gap> hom13 := GroupHomomorphismByFunction(G1, G3, sgn);;
gap> hom23 := GroupHomomorphismByFunction(G2, G3, sgn);;
gap> T := AsSemigroup(IsPartialPermSemigroup,
> gr,
> [G1, G2, G3], [[1, 3, hom13], [2, 3, hom23]]);;
gap> Size(T);
20
gap> D := GreensDClasses(T);;
gap> List(D, x -> Size(x));
[ 6, 12, 2 ]
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomDigraph">
<ManSection>
  <Oper Name="RandomDigraph" Arg="[filt, ]n[, p]"/>
  <Returns>A digraph.</Returns>
  <Description>
    If the optional first argument <A>filt</A> is present, then this should
    specify the category or representation the digraph being created will
    belong to. For example, if <A>filt</A> is <Ref Filt="IsMutableDigraph"/>,
    then the digraph being created will be mutable, if <A>filt</A> is <Ref
    Filt="IsImmutableDigraph"/>, then the digraph will be immutable. 
    If the optional first argument <A>filt</A> is not present, then <Ref
      Filt="IsImmutableDigraph"/> is used by default.<P/>

    If <A>n</A> is a positive integer, then this function returns a random
    digraph with <A>n</A> vertices and without multiple edges. The result
    may or may not have loops.<P/>

    If the optional second argument <A>p</A> is a float with value
    <M>0 \leq </M> <A> p </A> <M> \leq 1</M>, then an edge will exist between each
    pair of vertices with probability approximately <A>p</A>.
    If <A>p</A> is not specified, then a random probability will be assumed
    (chosen with uniform probability).
    <Log><![CDATA[
gap> RandomDigraph(1000);
<immutable digraph with 1000 vertices, 364444 edges>
gap> RandomDigraph(10000, 0.023);
<immutable digraph with 10000 vertices, 2300438 edges>
gap> RandomDigraph(IsMutableDigraph, 1000, 1 / 2);
<mutable digraph with 1000 vertices, 499739 edges>
]]></Log>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomTournament">
<ManSection>
  <Oper Name="RandomTournament" Arg="[filt, ]n"/>
  <Returns>A digraph.</Returns>
  <Description>
    If the optional first argument <A>filt</A> is present, then this should
    specify the category or representation the digraph being created will
    belong to. For example, if <A>filt</A> is <Ref Filt="IsMutableDigraph"/>,
    then the digraph being created will be mutable, if <A>filt</A> is <Ref
    Filt="IsImmutableDigraph"/>, then the digraph will be immutable. 
    If the optional first argument <A>filt</A> is not present, then <Ref
      Filt="IsImmutableDigraph"/> is used by default.<P/>

    If <A>n</A> is a non-negative integer, this function returns a random
    tournament with <A>n</A> vertices. See <Ref Prop="IsTournament"/>. <P/>
    <Log><![CDATA[
gap> RandomTournament(10);
<immutable tournament with 10 vertices>
gap> RandomTournament(IsMutableDigraph, 10);
<mutable digraph with 1000 vertices, 500601 edges>
]]></Log>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomLattice">
<ManSection>
  <Oper Name="RandomLattice" Arg="n"/>
  <Returns>A digraph.</Returns>
  <Description>
    If the optional first argument <A>filt</A> is present, then this should
    specify the category or representation the digraph being created will
    belong to. For example, if <A>filt</A> is <Ref Filt="IsMutableDigraph"/>,
    then the digraph being created will be mutable, if <A>filt</A> is <Ref
    Filt="IsImmutableDigraph"/>, then the digraph will be immutable. 
    If the optional first argument <A>filt</A> is not present, then <Ref
      Filt="IsImmutableDigraph"/> is used by default.<P/>

    If <A>n</A> is a positive integer, this function return a random lattice
    with <C>m</C> vertices, where it is guaranteed that <C>m</C> is between
    <A>n</A> and <C>2 * <A>n</A></C>. See <Ref Prop="IsLatticeDigraph"/>. <P/>
    <Log><![CDATA[
gap> RandomLattice(10);
<immutable lattice digraph with 10 vertices, 39 edges>
gap> RandomLattice(IsMutableDigraph, 10);
<mutable digraph with 12 vertices, 52 edges>
]]></Log>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomMultiDigraph">
<ManSection>
  <Oper Name="RandomMultiDigraph" Arg="n[, m]"/>
  <Returns>A digraph.</Returns>
  <Description>
    If <A>n</A> is a positive integer, then this function returns a random
    digraph with <A>n</A> vertices. If the optional second argument
    <A>m</A> is a positive integer, then the digraph will have <A>m</A>
    edges. If <A>m</A> is not specified, then the number of edges will be
    chosen randomly (with uniform probability) from the range
    <C>[1 .. </C><M>{n \choose 2}</M><C>]</C>.
    <P/>

    The method used by this function chooses each edge from the set of
    all possible edges with uniform probability. No effort is made to avoid
    creating multiple edges, so it is possible (but not guaranteed) that the
    result will have multiple edges. The result may or may not have loops.<P/>
    <Log><![CDATA[
gap> RandomMultiDigraph(1000);
<immutable multidigraph with 1000 vertices, 216659 edges>
gap> RandomMultiDigraph(1000, 950);
<immutable multidigraph with 1000 vertices, 950 edges>
]]></Log>
  </Description>
</ManSection>
<#/GAPDoc>
