#############################################################################
##
#W  digraph.xml
#Y  Copyright (C) 2014-21                               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>
    &STANDARD_FILT_TEXT;

    <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 positive 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>

      <Mark>for a string naming a digraph</Mark>
      <Item>
        if <A>obj</A> is a non-empty string, then this function returns the
        digraph that has name <A>obj</A>. &Digraphs; comes with a database
        containing a few hundred common digraph names that can be loaded in this
        way. Valid names include <C>"folkman"</C>, <C>"diamond"</C> and
        <C>"brinkmann"</C>. If the name is commonly followed by the word
        <C>"graph"</C>, then it is called without writing <C>"graph"</C> at the
        end. You can explore the available graph names using
        <Ref Oper="ListNamedDigraphs"/>. Digraph names are case and whitespace
        insensitive. <P/>

        Note that any undirected graphs in the database are stored as symmetric
        digraphs, so the resulting digraph will have twice as many edges as its
        undirected counterpart.
      </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>
gap> Digraph("Diamond");
<immutable digraph with 4 vertices, 10 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>
    &STANDARD_FILT_TEXT;

    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>
    &STANDARD_FILT_TEXT;

    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>
    &STANDARD_FILT_TEXT;

  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
  in the list <C><A>list</A>[j]</C>. <P/>

  If <C>i</C> occurs in the 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="ListNamedDigraphs">
<ManSection>
  <Oper Name="ListNamedDigraphs" Arg="s[, level]"/>
  <Returns>A list of strings representing digraph names.</Returns>
  <Description>
    This function searches through the list of names that are
    currently in the &Digraphs; database of named digraphs. The first argument
    <A>s</A> should be a partially completed string; this function returns all
    completions <C>str</C> of the string <A>s</A> such that <C>Digraph(str)</C>
    will successfully return a digraph. <P/>

    The optional second argument <A>level</A> controls the flexibility of the
    search. If <C><A>level</A> = 1</C>, then only strings beginning exactly with
    <A>s</A> are returned. If <C><A>level</A> = 2</C>, then all names containing
    <A>s</A> as a substring are returned. If <C><A>level</A> = 3</C>, then
    once again a substring search is carried out, but
    characters that are not alphanumeric are ignored in the search. <P/>

    If <A>level</A> is not specified, it is set by default to equal 2. <P/>

    The search is always case and whitespace insensitive, and this is also the
    case when applying <Ref Oper="Digraph"/> to a string.
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsDigraph">
<ManSection>
  <Oper Name="AsDigraph" Arg="[filt, ]f[, n]" Label="for a binary relation"/>
  <Returns>A digraph, or <K>fail</K>.</Returns>
  <Description>

      If <A>f</A> is a binary relation represented as one of the following in
        &GAP;:
      <List>
        <Mark>
          a transformation
        </Mark>
        <Item>
          satisfying <Ref Filt="IsTransformation" BookName="ref"/>;
        </Item>
        <Mark>
          a permutation
        </Mark>
        <Item>
          satisfying <Ref Filt="IsPerm" BookName="ref"/>;
        </Item>
        <Mark>
          a partial perm
        </Mark>
        <Item>
          satisfying <Ref Filt="IsPartialPerm" BookName="ref"/>;
        </Item>
        <Mark>
          a binary relation
        </Mark>
        <Item>
          satisfying <Ref Filt="IsBinaryRelation" BookName="ref"/>;
        </Item>
      </List>
      and <A>n</A> is a non-negative integer, then <C>AsDigraph</C> attempts
      to construct a digraph with <A>n</A> vertices whose edges are determined
      by <A>f</A>.<P/>

    The digraph returned by <C>AsDigraph</C> has for each vertex
    <C>v</C> in <C>[1 .. <A>n</A>]</C>, an edge with source <C>v</C> and range
    <C>v ^ <A>f</A></C>.  If <C>v ^ <A>f</A></C> is greater than <A>n</A> for any
    <C>v</C>, then <K>fail</K> is returned.
    <P/>

    If the optional second argument <A>n</A> is not supplied, then the degree
    of the transformation <A>f</A>, the largest moved point of the permutation
    <A>f</A>, the maximum of the degree and the codegree of the partial perm
    <A>f</A>, or as applicable, is used by default.  
    <P/>

    &STANDARD_FILT_TEXT;

    <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> AsDigraph((1, 2, 3, 4)) = CycleDigraph(4);
true
gap> D := AsDigraph(IsMutableDigraph, (1, 3)(2, 4), 5);
<mutable digraph with 5 vertices, 5 edges>
gap> DigraphEdges(D);
[ [ 1, 3 ], [ 2, 4 ], [ 3, 1 ], [ 4, 2 ], [ 5, 5 ] ]
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>
    &STANDARD_FILT_TEXT;
      
    The other implemented filters are as follows:
      <Ref Filt='IsConnectedDigraph'/>, <Ref Filt='IsSymmetricDigraph'/>, <Ref Filt='IsAcyclicDigraph'/>, <Ref Filt='IsEulerianDigraph'/>, <Ref Filt='IsHamiltonianDigraph'/>.<P/>
      
    For <Ref Filt='IsConnectedDigraph'/>, a random tree is first created independent of the value of <A>p</A>,
      guaranteeing connectivity (with <M><A>n</A>-1</M> edges), and then edges are added between the remaining pairs
      of vertices with probability approximately <A>p</A>.<P/>
      
    For <Ref Filt='IsHamiltonianDigraph'/>, a random Hamiltonian cycle is first created independent of the
      value of <A>p</A> (with <A>n</A> edges), and then edges are added between the remaining pairs of vertices 
      with probability approximately <A>p</A>.<P/>
      
    For <Ref Filt='IsEulerianDigraph'/>, a random Eulerian cycle is created where <A>p</A> influences how 
      long the cycle will be. The cycle grows by randomly considering edges that extend the cycle, and 
      adding an edge with probability approximately <A>p</A>. The cycle stops when we get back to the start vertex 
      and have no more edges left to consider from it that extend the cycle further (any possible edge from the 
      start vertex has either been added to the cycle, or rejected, leaving no more edges to consider). Thus 
      <M><A>p</A> = 1</M> does not necessarily guarantee a complete digraph. Instead, it guarantees that all edges 
      considered up to the point where the cycle stops, are added.<P/>
      
    For <Ref Filt='IsAcyclicDigraph'/> and <Ref Filt='IsSymmetricDigraph'/>, edges are added between any 
      pairs of vertices with probability approximately <A>p</A>.<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. If using <Ref Filt='IsAcyclicDigraph'/>, the resulting graph 
      will not have any loops by definition.<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).<P/>
    <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>
gap> RandomDigraph(IsConnectedDigraph, 1000, 0.75);
<immutable digraph with 1000 vertices, 750265 edges>
gap> RandomDigraph(IsSymmetricDigraph, 1000);
<immutable digraph with 1000 vertices, 329690 edges>
gap> RandomDigraph(IsAcyclicDigraph, 1000, 0.25);
<immutable digraph with 1000 vertices, 125070 edges>
gap> RandomDigraph(IsHamiltonianDigraph, 1000, 0.5);
<immutable digraph with 1000 vertices, 500327 edges>
gap> RandomDigraph(IsEulerianDigraph, 1000, 0.5);
<immutable digraph with 1000 vertices, 433869 edges>
]]></Log>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RandomTournament">
<ManSection>
  <Oper Name="RandomTournament" Arg="[filt, ]n"/>
  <Returns>A digraph.</Returns>
  <Description>
    &STANDARD_FILT_TEXT;

    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>
    &STANDARD_FILT_TEXT;

    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>
