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

<#GAPDoc Label="DigraphHasLoops">
<ManSection>
  <Prop Name="DigraphHasLoops" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    Returns <K>true</K> if the digraph <A>digraph</A> is has loops, and
    <K>false</K> if it does not. A loop is an edge with equal source and range.

    <Example><![CDATA[
gap> gr := Digraph( [ [ 1, 2 ], [ 2 ] ] );
<digraph with 2 vertices, 3 edges>
gap> DigraphEdges(gr);
[ [ 1, 1 ], [ 1, 2 ], [ 2, 2 ] ]
gap> DigraphHasLoops(gr);
true
gap> gr := Digraph( [ [ 2, 3 ], [ 1 ], [ 2 ] ] );
<digraph with 3 vertices, 4 edges>
gap> DigraphEdges(gr);
[ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 3, 2 ] ]
gap> DigraphHasLoops(gr);
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsAcyclicDigraph">
<ManSection>
  <Prop Name="IsAcyclicDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    Returns <K>true</K> if the digraph <A>digraph</A> is acyclic and
    <K>false</K> if it is not. A digraph is <E>acyclic</E> if there are no
    cycles, i.e. if there are no directed walks which start and end at the same
    vertex. <P/>

    The method used in this operation has complexity <M>O(m+n)</M> where
    <M>m</M> is the number of edges (counting multiple edges as one) and
    <M>n</M> is the number of vertices in the digraph. 

    <Example><![CDATA[
gap> Petersen := Graph( SymmetricGroup(5), [ [ 1, 2 ] ], OnSets,           
> function(x, y) return IsEmpty(Intersection(x, y)); end );;
gap> gr:=Digraph(Petersen);                    
<digraph with 10 vertices, 30 edges>
gap> IsAcyclicDigraph(gr);
false
gap> gr:=Digraph( [ [  ], [ 1 ], [ 1 ], [ 1 ], [ 3 ], [ 3 ], 
> [ 4 ], [ 4 ], [ 5 ], [ 5 ], [ 5 ], [ 6 ], [ 6 ], [ 7 ], [ 7 ], 
> [ 7 ], [ 8 ], [ 9 ], [ 9 ], [ 11 ], [ 11 ], [ 12 ], [ 12 ], [ 13 ], 
> [ 14 ], [ 15 ], [ 15 ], [ 16 ], [ 16 ], [ 17 ], [ 17 ], [ 18 ], 
> [ 18 ], [ 19 ], [ 20 ], [ 20 ], [ 21 ], [ 22 ], [ 22 ], [ 23 ], 
> [ 23 ], [ 24 ], [ 28 ], [ 29 ], [ 30 ], [ 30 ], [ 31 ], [ 32 ], 
> [ 32 ], [ 33 ], [ 34 ], [ 41 ], [ 46 ], [ 47 ], [ 51 ] ] );;
gap> IsAcyclicDigraph(gr);
true
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsCompleteDigraph">
<ManSection>
  <Prop Name="IsCompleteDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    Returns <K>true</K> if the digraph <A>digraph</A> is complete, and 
    <K>false</K> if it is not. <P/>
    
    A digraph is <E>complete</E> if it has no loops, and for all
    <E>distinct</E> vertices <C>i</C> and <C>j</C>,
    there is exactly one edge with source <C>i</C> and range <C>j</C>.
    
    Equivalently, a digraph with <M>n</M> vertices is complete precisely when
    it has <M>n(n - 1)</M> edges, no loops, and no multiple edges.

    <Example><![CDATA[
gap> gr := Digraph( [ [ 2, 3 ], [ 1, 3 ], [ 1, 2 ] ] );
<digraph with 3 vertices, 6 edges>
gap> IsCompleteDigraph(gr);
true
gap> gr := Digraph( [ [ 2, 2 ], [ 1 ] ] );
<multidigraph with 2 vertices, 3 edges>
gap> IsCompleteDigraph(gr);
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsCompleteBipartiteDigraph">
<ManSection>
  <Prop Name="IsCompleteBipartiteDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    Returns <K>true</K> if the digraph <A>digraph</A> is a complete bipartite
    digraph, and <K>false</K> if it is not. <P/>
    
    A digraph is a <E>complete bipartite digraph</E> if it is bipartite, see
    <Ref Prop="IsBipartiteDigraph"/>, and there exists a unique edge with
    source <C>i</C> and range <C>j</C> if and only if <C>i</C> and <C>j</C> lie
    in different bicomponents of <A>digraph</A>, see <Ref
      Attr="DigraphBicomponents"/>. <P/>
    
    Equivalently, a bipartite digraph with bicomponents of size <M>m</M> and
    <M>n</M> is complete precisely when it has <M>2mn</M> edges, none of which
    are multiple edges. <P/>

    See also <Ref Oper="CompleteBipartiteDigraph"/>.

    <Example><![CDATA[
gap> gr := CycleDigraph(2);
<digraph with 2 vertices, 2 edges>
gap> IsCompleteBipartiteDigraph(gr);
true
gap> gr := CycleDigraph(4);
<digraph with 4 vertices, 4 edges>
gap> IsBipartiteDigraph(gr);
true
gap> IsCompleteBipartiteDigraph(gr);
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsEmptyDigraph">
<ManSection>
  <Prop Name="IsEmptyDigraph" Arg="digraph"/>
  <Prop Name="IsNullDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    Returns <K>true</K> if the digraph <A>digraph</A> is empty, and
    <K>false</K> if it is not. A digraph is <E>empty</E> if it has no
    edges.<P/>

    <C>IsNullDigraph</C> is a synonym for <C>IsEmptyDigraph</C>.

    <Example><![CDATA[
gap> gr := Digraph( [ [  ], [  ] ] );
<digraph with 2 vertices, 0 edges>
gap> IsEmptyDigraph(gr);
true
gap> IsNullDigraph(gr);
true
gap> gr := Digraph( [ [  ], [ 1 ] ] );
<digraph with 2 vertices, 1 edge>
gap> IsEmptyDigraph(gr);
false
gap> IsNullDigraph(gr);
false]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsFunctionalDigraph">
<ManSection>
  <Prop Name="IsFunctionalDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if the digraph <A>digraph</A> is
    functional. <P/>
    
    A digraph is <E>functional</E> if every vertex is the source of a
    unique edge. 
    <Example><![CDATA[
gap> gr1 := Digraph( [ [ 3 ], [ 2 ], [ 2 ], [ 1 ], [ 6 ], [ 5 ] ] );
<digraph with 6 vertices, 6 edges>
gap> IsFunctionalDigraph(gr1);
true
gap> gr2 := Digraph( [ [ 1, 2 ], [ 1 ] ] );
<digraph with 2 vertices, 3 edges>
gap> IsFunctionalDigraph(gr2);
false
gap> gr3 := Digraph( 3, [ 1, 2, 3 ], [ 2, 3, 1 ] );
<digraph with 3 vertices, 3 edges>
gap> IsFunctionalDigraph(gr3);
true
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>


<#GAPDoc Label="IsReflexiveDigraph">
<ManSection>
  <Prop Name="IsReflexiveDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if the digraph <A>digraph</A> is 
    reflexive, and <K>false</K> if it is not.
    A digraph is <E>reflexive</E> if it has a loop at every vertex. <P/>
    <Example><![CDATA[
gap> gr := Digraph( [ [ 1, 2 ], [ 2 ] ] );
<digraph with 2 vertices, 3 edges>
gap> IsReflexiveDigraph(gr);
true
gap> gr := Digraph( rec ( nrvertices := 4,
> source := [ 1, 1, 2, 2, 3, 4, 4 ],
> range := [ 3, 1, 4, 2, 3, 2, 1 ] )  );
<digraph with 4 vertices, 7 edges>
gap> IsReflexiveDigraph(gr);
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsConnectedDigraph">
<ManSection>
  <Prop Name="IsConnectedDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if the digraph <A>digraph</A>
    is weakly connected and <K>false</K> if it is not.  A digraph
    <A>digraph</A> is <E>weakly connected</E> if it is possible to travel 
    from any vertex to any other vertex by traversing edges in either
    direction (possibly against the orientation of some of them). <P/>

    The method used in this function has complexity <M>O(m)</M> if the 
    digraph's <Ref Attr="DigraphSource"/> attribute is set, otherwise it has
    complexity <M>O(m+n)</M> (where 
    <M>m</M> is the number of edges and
    <M>n</M> is the number of vertices of the digraph).

    <Example><![CDATA[
gap> gr := Digraph( [ [ 2 ], [ 3 ], [  ] ] );;
gap> IsConnectedDigraph(gr);
true
gap> gr := Digraph( [ [ 1, 3 ], [ 4 ], [ 3 ], [  ] ] );;
gap> IsConnectedDigraph(gr);
false]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsStronglyConnectedDigraph">
<ManSection>
  <Prop Name="IsStronglyConnectedDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if the digraph <A>digraph</A> 
    is strongly connected and <K>false</K> if it is not.
    A digraph <A>digraph</A> is <E>strongly connected</E> if there 
    is a directed path from every vertex to every other vertex. <P/>

    The method used in this operation is based on Gabow's Algorithm
    <Cite Key="Gabow2000aa"/> and has complexity <M>O(m+n)</M>,
    where <M>m</M> is the number of edges (counting multiple edges as one) 
    and <M>n</M> is the number of vertices in the digraph. 
  
    <Example><![CDATA[
gap> gr := CycleDigraph(250000);
<digraph with 250000 vertices, 250000 edges>
gap> IsStronglyConnectedDigraph(gr);
true
gap> gr:=DigraphRemoveEdges(gr, [ [ 250000, 1 ] ]);
<digraph with 250000 vertices, 249999 edges>
gap> IsStronglyConnectedDigraph(gr);
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsSymmetricDigraph">
<ManSection>
  <Prop Name="IsSymmetricDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if the digraph <A>digraph</A> 
    is symmetric, and <K>false</K> if it is not.<P/>

    A <E>symmetric digraph</E> is one where for each non-loop edge,
    having source <M>u</M> and range <M>v</M>, there is a corresponding edge
    with source v and range u.
    If there are <M>n</M> edges with source <M>u</M>
    and range <M>v</M>, then there must be precisely <M>n</M> edges with 
    source <M>v</M> and range <M>u</M>.
    In other words, an undirected digraph has a symmetric adjacency 
    matrix <Ref Attr="AdjacencyMatrix"/>.<P/>
    <Example><![CDATA[
gap> gr1 := Digraph( [ [ 2 ], [ 1, 3 ], [ 2, 3 ] ] );
<digraph with 3 vertices, 5 edges>
gap> IsSymmetricDigraph(gr1);
true
gap> adj1 := AdjacencyMatrix(gr1);;
gap> Display(adj1);
[ [  0,  1,  0 ],
  [  1,  0,  1 ],
  [  0,  1,  1 ] ]
gap> adj1 = TransposedMat(adj1);
true
gap> gr1 = DigraphReverse(gr1);
true
gap> gr2 := Digraph( [ [ 2, 3 ], [ 1, 3 ], [ 2, 3 ] ] );
<digraph with 3 vertices, 6 edges>
gap> IsSymmetricDigraph(gr2);
false
gap> adj2 := AdjacencyMatrix(gr2);;
gap> Display(adj2);
[ [  0,  1,  1 ],
  [  1,  0,  1 ],
  [  0,  1,  1 ] ]
gap> adj2 = TransposedMat(adj2);
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsAntisymmetricDigraph">
<ManSection>
  <Prop Name="IsAntisymmetricDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if the digraph <A>digraph</A> 
    is antisymmetric, and <K>false</K> if it is not.
    <P/>

    A digraph is <E>antisymmetric</E> if whenever there is an edge with source
    <C>u</C> and range <C>v</C>, and an edge with source <C>v</C> and range
    <C>u</C>, then the vertices <C>u</C> and <C>v</C> are equal.
    <P/>

    <Example><![CDATA[
gap> gr1 := Digraph( [ [ 2 ], [ 1, 3 ], [ 2, 3 ] ] );
<digraph with 3 vertices, 5 edges>
gap> IsAntisymmetricDigraph(gr1);
false
gap> DigraphEdges(gr1){[ 1, 2 ]};
[ [ 1, 2 ], [ 2, 1 ] ]
gap> gr2 := Digraph( [ [ 1, 2 ], [ 3, 3 ], [ 1 ] ] );
<multidigraph with 3 vertices, 5 edges>
gap> IsAntisymmetricDigraph(gr2);
true
gap> DigraphEdges(gr2);
[ [ 1, 1 ], [ 1, 2 ], [ 2, 3 ], [ 2, 3 ], [ 3, 1 ] ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsTransitiveDigraph">
<ManSection>
  <Prop Name="IsTransitiveDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if the digraph <A>digraph</A>
    is transitive, and <K>false</K> if it is not.
    
    A digraph is <E>transitive</E> if whenever <C>[ i, j ]</C> and 
    <C>[ j, k ]</C> are edges of the digraph, then <C>[ i, k ]</C> is also an
    edge of the digraph. <P/>

    Let <M>n</M> be the number of vertices of an arbitrary digraph, and let
        <M>m</M> be the number of edges.
    For general digraphs, the methods used for this property use a version
    of the Floyd-Warshall algorithm, and have complexity <M>O(n^3)</M>.

    However for digraphs which are topologically sortable
    [<Ref Attr="DigraphTopologicalSort"/>], then methods with
    complexity <M>O(m + n + m \cdot n)</M> will be used when appropriate.
    <P/>
    <Example><![CDATA[
gap> gr := Digraph( [ [ 1, 2 ], [ 3 ], [ 3 ] ] );
<digraph with 3 vertices, 4 edges>
gap> IsTransitiveDigraph(gr);
false
gap> gr2 := Digraph( [ [ 1, 2, 3 ], [ 3 ], [ 3 ] ] );
<digraph with 3 vertices, 5 edges>
gap> IsTransitiveDigraph(gr2);
true
gap> gr2 = DigraphTransitiveClosure(gr);
true
gap> gr3 := Digraph( [ [ 1, 2, 2, 3 ], [ 3, 3 ], [ 3 ] ] );
<multidigraph with 3 vertices, 7 edges>
gap> IsTransitiveDigraph(gr3);
true
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsTournament">
<ManSection>
  <Prop Name="IsTournament" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if the digraph <A>digraph</A> is a tournament,
    and <K>false</K> if it is not. <P/>
    
    A tournament is an orientation of a complete (undirected) graph.
    Specifically, a tournament is a digraph which has a unique directed edge
    (of some orientation) between any pair of distinct vertices, and no loops.
    <P/>
    <Example><![CDATA[
gap> gr := Digraph( [ [ 2, 3, 4 ], [ 3, 4 ], [ 4 ], [  ] ] );
<digraph with 4 vertices, 6 edges>
gap> IsTournament(gr);
true
gap> gr := Digraph( [ [ 2 ], [ 1 ], [ 3 ] ] );
<digraph with 3 vertices, 3 edges>
gap> IsTournament(gr);
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsAperiodicDigraph">
<ManSection>
  <Prop Name="IsAperiodicDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if the digraph <A>digraph</A>
    is aperiodic, i.e. if its <Ref Attr = "DigraphPeriod"/> is equal to 1.
    Otherwise, the property is <K>false</K>.
    <Example><![CDATA[
gap> gr := Digraph( [ [ 6 ], [ 1 ], [ 2 ], [ 3 ], [ 4, 4 ], [ 5 ] ] );
<multidigraph with 6 vertices, 7 edges>
gap> IsAperiodicDigraph(gr);
false
gap> gr := Digraph( [ [ 2 ], [ 3, 5 ], [ 4 ], [ 5 ], [ 1, 2 ] ] );
<digraph with 5 vertices, 7 edges>
gap> IsAperiodicDigraph(gr);
true
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsBipartiteDigraph">
<ManSection>
  <Prop Name="IsBipartiteDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
  This property is <K>true</K> if the digraph <A>digraph</A> is bipartite, and
  <K>false</K> if it is not.  A digraph is bipartite if and only if the
  vertices of <A>digraph</A> can be partitioned into two non-empty sets such
  that the source and range of any edge of <A>digraph</A> lie in distinct sets.
  Equivalently, a digraph is bipartite if and only if it is 2-colorable; see
  <Ref Oper="DigraphColoring" Label="for a digraph"/>. <P/>

  See also <Ref Attr="DigraphBicomponents"/>.
    <Example><![CDATA[
gap> gr := ChainDigraph(4);
<digraph with 4 vertices, 3 edges>
gap> IsBipartiteDigraph(gr);
true
gap> gr := CycleDigraph(3);
<digraph with 3 vertices, 3 edges>
gap> IsBipartiteDigraph(gr);
false]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsInRegularDigraph">
<ManSection>
  <Prop Name="IsInRegularDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if there is an integer <C>n</C> such that
    for every vertex <C>v</C> of digraph <A>digraph</A> there are exactly
    <C>n</C> edges terminating in <C>v</C>. 

    See also <Ref Attr="IsOutRegularDigraph"/> and <Ref
	    Attr="IsRegularDigraph"/>.
    <Example><![CDATA[
gap> IsInRegularDigraph(CompleteDigraph(4));
true
gap> IsInRegularDigraph(ChainDigraph(4));
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsOutRegularDigraph">
<ManSection>
  <Prop Name="IsOutRegularDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if there is an integer <C>n</C> such that
    for every vertex <C>v</C> of digraph <A>digraph</A> there are exactly
    <C>n</C> edges starting at <C>v</C>. 

    See also <Ref Attr="IsInRegularDigraph"/> and <Ref
	    Attr="IsRegularDigraph"/>.
    <Example><![CDATA[
gap> IsOutRegularDigraph(CompleteDigraph(4));
true
gap> IsOutRegularDigraph(ChainDigraph(4));
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsRegularDigraph">
<ManSection>
  <Prop Name="IsRegularDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    This property is <K>true</K> if there is an integer <C>n</C> such that
    for every vertex <C>v</C> of digraph <A>digraph</A> there are exactly
    <C>n</C> edges starting and terminating at <C>v</C>. In other words,
    the property is <K>true</K> if <A>digraph</A> is both in-regular and
    and out-regular.

    See also <Ref Attr="IsInRegularDigraph"/> and <Ref
	    Attr="IsOutRegularDigraph"/>.
    <Example><![CDATA[
gap> IsRegularDigraph(CompleteDigraph(4));
true
gap> IsRegularDigraph(ChainDigraph(4));
false
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsDistanceRegularDigraph">
<ManSection>
  <Prop Name="IsDistanceRegularDigraph" Arg="digraph"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    If <A>digraph</A> is a connected symmetric graph, this property returns
    <K>true</K> if for any two vertices <C>u</C> and <C>v</C> of <A>digraph</A>
    and any two integers <C>i</C> and <C>j</C> between <C>0</C> and the
    diameter of <A>digraph</A>, the number of vertices at distance <C>i</C>
    from <C>u</C> and distance <C>j</C> from <C>v</C> depends only on
    <C>i</C>, <C>j</C>, and the distance between vertices <C>u</C> and
    <C>v</C>.<P/>

    Alternatively, a distance regular graph is a graph for which there exist
    integers <C>b_i</C>, <C>c_i</C>, and <C>i</C> such that for any two
    vertices <C>u</C>, <C>v</C> in <A>digraph</A> which are distance <C>i</C>
    apart, there are exactly <C>b_i</C> neighbors of <C>v</C> which are at
    distance <C>i - 1</C> away from <C>u</C>, and <C>c_i</C> neighbors of
    <C>v</C> which are at distance <C>i + 1</C> away from <C>u</C>. This
    definition is used to check whether <A>digraph</A> is distance regular.<P/>

    In the case where <A>digraph</A> is not symmetric or not connected, the
    property is <K>false</K>.

    <Example><![CDATA[
gap> gr := DigraphSymmetricClosure(ChainDigraph(5));;
gap> IsDistanceRegularDigraph(gr);
false
gap> gr := Digraph([[2, 3, 4], [1, 3, 4], [1, 2, 4], [1, 2, 3]]);
<digraph with 4 vertices, 12 edges>
gap> IsDistanceRegularDigraph(gr);
true
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>
