#############################################################################
##
#W prop.
xml
#Y Copyright (C) 2014-21 James D. Mitchell
##
## Licensing information can be found in the README file of this package.
##
#############################################################################
##
<#GAPDoc Label=
"IsMultiDigraph">
<ManSection>
<Prop Name=
"IsMultiDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
A <E>multidigraph</E> is one that has at least two
edges with equal source and range.<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([
"a",
"b",
"c"], [
"a",
"b",
"b"], [
"b",
"c",
"a"]);
<immutable digraph with 3 vertices, 3 edges>
gap> IsMultiDigraph(D);
false
gap> D := DigraphFromDigraph6String(
"&Bug");
<immutable digraph with 3 vertices, 6 edges>
gap> IsDuplicateFree(DigraphEdges(D));
true
gap> IsMultiDigraph(D);
false
gap> D := Digraph([[1, 2, 3, 2], [2, 1], [3]]);
<immutable multidigraph with 3 vertices, 7 edges>
gap> IsDuplicateFree(DigraphEdges(D));
false
gap> IsMultiDigraph(D);
true
gap> D := DigraphMutableCopy(D);
<mutable multidigraph with 3 vertices, 7 edges>
gap> IsMultiDigraph(D);
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#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> has loops, and
<K>false</K> if it does not. A loop is an edge with equal source and range.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[1, 2], [2]]);
<immutable digraph with 2 vertices, 3 edges>
gap> DigraphEdges(D);
[ [ 1, 1 ], [ 1, 2 ], [ 2, 2 ] ]
gap> DigraphHasLoops(D);
true
gap> D := Digraph([[2, 3], [1], [2]]);
<immutable digraph with 3 vertices, 4 edges>
gap> DigraphEdges(D);
[ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 3, 2 ] ]
gap> DigraphHasLoops(D);
false
gap> D := CompleteDigraph(IsMutableDigraph, 4);
<mutable digraph with 4 vertices, 12 edges>
gap> DigraphHasLoops(D);
false]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsAcyclicDigraph">
<ManSection>
<Prop Name=
"IsAcyclicDigraph" 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 acyclic, and
<K>false</K> if it is not. A digraph is <E>acyclic</E> if every directed
cycle on the digraph is trivial. See Section <Ref Subsect=
"Definitions"
Style=
"Number" /> for the definition of a directed cycle, and of a trivial
directed cycle.<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. <P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> Petersen := Graph(SymmetricGroup(5), [[1, 2]], OnSets,
> function(x, y)
> return IsEmpty(Intersection(x, y));
> end);;
gap> D := Digraph(Petersen);
<immutable digraph with 10 vertices, 30 edges>
gap> IsAcyclicDigraph(D);
false
gap> D := DigraphFromDiSparse6String(
>
".b_OGCIDBaPGkULEbQHCeRIdrHcuZMfRyDAbPhTi|zF");
<immutable digraph with 35 vertices, 34 edges>
gap> IsAcyclicDigraph(D);
true
gap> IsAcyclicDigraph(ChainDigraph(10));
true
gap> D := CompleteDigraph(IsMutableDigraph, 4);
<mutable digraph with 4 vertices, 12 edges>
gap> IsAcyclicDigraph(D);
false
gap> IsAcyclicDigraph(CycleDigraph(10));
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>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[6], [1], [2], [3], [4, 4], [5]]);
<immutable multidigraph with 6 vertices, 7 edges>
gap> IsAperiodicDigraph(D);
false
gap> D := Digraph([[2], [3, 5], [4], [5], [1, 2]]);
<immutable digraph with 5 vertices, 7 edges>
gap> IsAperiodicDigraph(D);
true
gap> D := Digraph(IsMutableDigraph, [[2], [3, 5], [4], [5], [1, 2]]);
<mutable digraph with 5 vertices, 7 edges>
gap> IsAperiodicDigraph(D);
true]]></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. <P/>
A digraph <A>digraph</A> is <E>strongly connected</E> if there is a directed
path from every vertex to every other vertex. See Section <Ref
Subsect=
"Definitions" Style=
"Number" /> for the definition of a directed
path. <P/>
The method used in this operation is based on Gabow
's Algorithm <Cite
Key=
"Gab00"/> 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.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := CycleDigraph(250000);
<immutable cycle digraph with 250000 vertices>
gap> IsStronglyConnectedDigraph(D);
true
gap> D := DigraphRemoveEdges(D, [[250000, 1]]);
<immutable digraph with 250000 vertices, 249999 edges>
gap> IsStronglyConnectedDigraph(D);
false
gap> D := CycleDigraph(IsMutableDigraph, 250000);
<mutable digraph with 250000 vertices, 250000 edges>
gap> IsStronglyConnectedDigraph(D);
true
gap> DigraphRemoveEdge(D, [250000, 1]);
<mutable digraph with 250000 vertices, 249999 edges>
gap> IsStronglyConnectedDigraph(D);
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).
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[2], [3], []]);;
gap> IsConnectedDigraph(D);
true
gap> D := Digraph([[1, 3], [4], [3], []]);;
gap> IsConnectedDigraph(D);
false
gap> D := Digraph(IsMutableDigraph, [[2], [3], []]);;
gap> IsConnectedDigraph(D);
true
gap> D := Digraph(IsMutableDigraph, [[1, 3], [4], [3], []]);;
gap> IsConnectedDigraph(D);
false]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsBiconnectedDigraph">
<ManSection>
<Prop Name=
"IsBiconnectedDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
A connected digraph is <E>biconnected</E> if it is still connected (in the
sense of <Ref Prop=
"IsConnectedDigraph"/>) when any vertex is removed.
If <A>D</A> has at least 3 vertices, then <C>IsBiconnectedDigraph</C>
implies <Ref Prop=
"IsBridgelessDigraph"/>;
see <Ref Attr=
"ArticulationPoints"/> or <Ref Attr=
"Bridges"/> for a more
detailed explanation.
<P/>
<C>IsBiconnectedDigraph</C> returns <K>true</K> if the digraph
<A>digraph</A> is biconnected, and <K>false</K> if it is not. In
particular, <C>IsBiconnectedDigraph</C> returns <K>false</K> if
<A>digraph</A> is not connected. <P/>
Multiple edges are ignored by this method. <P/>
The method used in this operation 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 in
the digraph.
<P/>
See also <Ref Attr=
"Bridges"/>, <Ref Attr=
"ArticulationPoints"/>, and
<Ref Prop=
"IsBridgelessDigraph"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> IsBiconnectedDigraph(Digraph([[1, 3], [2, 3], [3]]));
false
gap> IsBiconnectedDigraph(CycleDigraph(5));
true
gap> D := Digraph([[1, 1], [1, 1, 2], [3], [3, 3, 4, 4]]);;
gap> IsBiconnectedDigraph(D);
false
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 5, 4);
<mutable digraph with 9 vertices, 40 edges>
gap> IsBiconnectedDigraph(D);
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 Attr=
"DigraphGreedyColouring" Label=
"for a digraph"/>. <P/>
See also <Ref Attr=
"DigraphBicomponents"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := ChainDigraph(4);
<immutable chain digraph with 4 vertices>
gap> IsBipartiteDigraph(D);
true
gap> D := CycleDigraph(3);
<immutable cycle digraph with 3 vertices>
gap> IsBipartiteDigraph(D);
false
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 5, 4);
<mutable digraph with 9 vertices, 40 edges>
gap> IsBipartiteDigraph(D);
true]]></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"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := CycleDigraph(2);
<immutable cycle digraph with 2 vertices>
gap> IsCompleteBipartiteDigraph(D);
true
gap> D := CycleDigraph(4);
<immutable cycle digraph with 4 vertices>
gap> IsBipartiteDigraph(D);
true
gap> IsCompleteBipartiteDigraph(D);
false
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 5, 4);
<mutable digraph with 9 vertices, 40 edges>
gap> IsCompleteBipartiteDigraph(D);
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsCompleteMultipartiteDigraph">
<ManSection>
<Prop Name=
"IsCompleteMultipartiteDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
This property returns <K>true</K> if <A>digraph</A> is a complete
multipartite digraph, and <K>false</K> if not. <P/>
A digraph is a <E>complete multipartite digraph</E> if and only if
its vertices can be partitioned into at least two maximal independent sets,
where every possible edge between these independent sets occurs in the
digraph exactly once.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := CompleteMultipartiteDigraph([2, 4, 6]);
<immutable complete multipartite digraph with 12 vertices, 88 edges>
gap> IsCompleteMultipartiteDigraph(D);
true
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 5, 4);
<mutable digraph with 9 vertices, 40 edges>
gap> IsCompleteMultipartiteDigraph(D);
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.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[2, 3], [1, 3], [1, 2]]);
<immutable digraph with 3 vertices, 6 edges>
gap> IsCompleteDigraph(D);
true
gap> D := Digraph([[2, 2], [1]]);
<immutable multidigraph with 2 vertices, 3 edges>
gap> IsCompleteDigraph(D);
false
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 5, 4);
<mutable digraph with 9 vertices, 40 edges>
gap> IsCompleteDigraph(D);
false]]></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/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[2, 3, 4], [3, 4], [4], []]);
<immutable digraph with 4 vertices, 6 edges>
gap> IsTournament(D);
true
gap> D := Digraph([[2], [1], [3]]);
<immutable digraph with 3 vertices, 3 edges>
gap> IsTournament(D);
false
gap> D := CycleDigraph(IsMutableDigraph, 3);
<mutable digraph with 3 vertices, 3 edges>
gap> IsTournament(D);
true
gap> DigraphRemoveEdge(D, 1, 2);
<mutable digraph with 3 vertices, 2 edges>
gap> IsTournament(D);
false
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsChainDigraph">
<ManSection>
<Prop Name=
"IsChainDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
<C>IsChainDigraph</C> returns <K>true</K> if the digraph <A>digraph</A> is
isomorphic to the chain digraph with the same number of vertices as
<A>digraph</A>, and <K>false</K> if it is not; see <Ref
Oper=
"ChainDigraph"/>.<P/>
A digraph is a <E>chain</E> if and only if it is a directed tree, in which
every vertex has out degree at most one; see <Ref Prop=
"IsDirectedTree"/>
and <Ref Attr=
"OutDegrees"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[1, 3], [2, 3], [3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsChainDigraph(D);
false
gap> D := ChainDigraph(5);
<immutable chain digraph with 5 vertices>
gap> IsChainDigraph(D);
true
gap> D := DigraphReverse(D);
<immutable digraph with 5 vertices, 4 edges>
gap> IsChainDigraph(D);
true
gap> D := ChainDigraph(IsMutableDigraph, 5);
<mutable digraph with 5 vertices, 4 edges>
gap> IsChainDigraph(D);
true
gap> DigraphReverse(D);
<mutable digraph with 5 vertices, 4 edges>
gap> IsChainDigraph(D);
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsCycleDigraph">
<ManSection>
<Prop Name=
"IsCycleDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
<C>IsCycleDigraph</C> returns <K>true</K> if the digraph <A>digraph</A> is
isomorphic to the cycle digraph with the same number of vertices as
<A>digraph</A>, and <K>false</K> if it is not; see <Ref
Oper=
"CycleDigraph"/>.<P/>
A digraph is a <E>cycle</E> if and only if it is strongly connected and has
the same number of edges as vertices.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[1, 3], [2, 3], [3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsCycleDigraph(D);
false
gap> D := CycleDigraph(5);
<immutable cycle digraph with 5 vertices>
gap> IsCycleDigraph(D);
true
gap> D := OnDigraphs(D, (1, 2, 3));
<immutable digraph with 5 vertices, 5 edges>
gap> D = CycleDigraph(5);
false
gap> IsCycleDigraph(D);
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsDigraphCore">
<ManSection>
<Prop Name=
"IsDigraphCore" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
This property returns <K>true</K> if <A>digraph</A> is a core,
and <K>false</K> if it is not.<P/>
A digraph <C>D</C> is a <E>core</E> if and only if it has no proper
subdigraphs <C>A</C> such that there exists a homomorphism from <C>D</C>
to <C>A</C>. In other words, a digraph <C>D</C> is a core if and only if
every endomorphism on <C>D</C> is an automorphism on <C>D</C>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := CompleteDigraph(6);
<immutable complete digraph with 6 vertices>
gap> IsDigraphCore(D);
true
gap> D := DigraphSymmetricClosure(CycleDigraph(6));
<immutable symmetric digraph with 6 vertices, 12 edges>
gap> DigraphHomomorphism(D, CompleteDigraph(2));
Transformation( [ 1, 2, 1, 2, 1, 2 ] )
gap> IsDigraphCore(D);
false
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsDirectedTree">
<ManSection>
<Prop Name=
"IsDirectedTree" Arg=
"digraph"/>
<Prop Name=
"IsDirectedForest" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
The property <Ref Prop=
"IsDirectedTree"/> returns <K>true</K> if the
digraph <A>digraph</A> is a directed tree, and the property
<Ref Prop=
"IsDirectedForest"/> returns <K>true</K> if <A>digraph</A> is
a directed forest; otherwise these properties return <K>false</K>. <P/>
A <E>directed tree</E> is an acyclic digraph with precisely one source,
without multiple edges, and such that no two vertices share an
out-neighbour. See and <Ref Attr=
"IsAcyclicDigraph"/> and
<Ref Attr=
"DigraphSources"/> for more information about these terms. <P/>
A <E>directed forest</E> is a digraph with at least one vertex,
each of whose connected components is a directed tree.
In other words, a directed forest is isomorphic to a disjoint union of
directed trees.
In particular, every directed tree is a directed forest.
See <Ref Attr=
"DigraphConnectedComponents" /> and
<Ref Func=
"DigraphDisjointUnion" Label=
"for a list of digraphs" />. <P/>
Please note that the empty digraph with zero vertices is not considered
to be a directed tree or directed forest, because it has no source. <P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[3], [3], []]);
<immutable digraph with 3 vertices, 2 edges>
gap> IsDirectedTree(D);
false
gap> D := Digraph([[2], [3], []]);
<immutable digraph with 3 vertices, 2 edges>
gap> IsDirectedTree(D);
true
gap> IsDirectedForest(DigraphDisjointUnion(D, D));
true
gap> D := Digraph([[2, 3], [6], [4, 5], [], [], []]);
<immutable digraph with 6 vertices, 5 edges>
gap> IsDirectedTree(D);
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsUndirectedTree">
<ManSection>
<Prop Name=
"IsUndirectedTree" Arg=
"digraph"/>
<Prop Name=
"IsUndirectedForest" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
The property <Ref Prop=
"IsUndirectedTree"/> returns <K>true</K> if the
digraph <A>digraph</A> is an undirected tree, and the property
<Ref Prop=
"IsUndirectedForest"/> returns <K>true</K> if <A>digraph</A> is
an undirected forest; otherwise, these properties return <K>false</K>. <P/>
An <E>undirected tree</E> is a symmetric digraph without loops, in which for
any pair of distinct vertices <C>u</C> and <C>v</C>, there is exactly one
directed path from <C>u</C> to <C>v</C>. See <Ref
Prop=
"IsSymmetricDigraph"/> and <Ref Prop=
"DigraphHasLoops"/>, and see
Section <Ref Subsect=
"Definitions" Style=
"Number" /> for the definition of
directed path. This definition implies that an undirected tree has
no multiple edges. <P/>
An <E>undirected forest</E> is a digraph, each of whose connected components
is an undirected tree. In other words, an undirected forest is isomorphic to
a disjoint union of undirected trees. See <Ref
Attr=
"DigraphConnectedComponents" /> and <Ref Func=
"DigraphDisjointUnion"
Label=
"for a list of digraphs" />. In particular, every
undirected tree is an undirected forest. <P/>
Please note that the digraph with zero vertices is considered to be neither
an undirected tree nor an undirected forest.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[3], [3], [1, 2]]);
<immutable digraph with 3 vertices, 4 edges>
gap> IsUndirectedTree(D);
true
gap> IsSymmetricDigraph(D) and not DigraphHasLoops(D);
true
gap> D := Digraph([[3], [5], [1, 4], [3], [2]]);
<immutable digraph with 5 vertices, 6 edges>
gap> IsConnectedDigraph(D);
false
gap> IsUndirectedTree(D);
false
gap> IsUndirectedForest(D);
true
gap> D := Digraph([[1, 2], [1], [2]]);
<immutable digraph with 3 vertices, 4 edges>
gap> IsUndirectedTree(D) or IsUndirectedForest(D);
false
gap> IsSymmetricDigraph(D) or not DigraphHasLoops(D);
false]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsEdgeTransitive">
<ManSection>
<Prop Name=
"IsEdgeTransitive" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
If <A>digraph</A> is a digraph without multiple edges, then
<C>IsEdgeTransitive</C> returns <K>true</K> if <A>digraph</A>
is edge transitive, and <K>false</K> otherwise. A digraph is
<E>edge transitive</E> if its automorphism group acts
transitively on its edges (via the action
<Ref Func=
"OnPairs" BookName=
"ref"/>).
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> IsEdgeTransitive(CompleteDigraph(2));
true
gap> IsEdgeTransitive(ChainDigraph(3));
false
gap> IsEdgeTransitive(Digraph([[2], [3, 3, 3], []]));
Error, the argument <D> must be a digraph with no multiple edges,
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsVertexTransitive">
<ManSection>
<Prop Name=
"IsVertexTransitive" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
If <A>digraph</A> is a digraph, then <C>IsVertexTransitive</C> returns
<K>true</K> if <A>digraph</A> is vertex transitive, and <K>false</K>
otherwise. A digraph is <E>vertex transitive</E> if its automorphism group
acts transitively on its vertices.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> IsVertexTransitive(CompleteDigraph(2));
true
gap> IsVertexTransitive(ChainDigraph(3));
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/>
<Ref Prop=
"IsNullDigraph"/> is a synonym for <Ref Prop=
"IsEmptyDigraph"/>.
See also <Ref Prop=
"IsNonemptyDigraph"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[], []]);
<immutable empty digraph with 2 vertices>
gap> IsEmptyDigraph(D);
true
gap> IsNullDigraph(D);
true
gap> D := Digraph([[], [1]]);
<immutable digraph with 2 vertices, 1 edge>
gap> IsEmptyDigraph(D);
false
gap> IsNullDigraph(D);
false]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsNonemptyDigraph">
<ManSection>
<Prop Name=
"IsNonemptyDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
Returns <K>true</K> if the digraph <A>digraph</A> is nonempty, and
<K>false</K> if it is not. A digraph is <E>nonempty</E> if it has at
least one edge.<P/>
See also <Ref Prop=
"IsEmptyDigraph"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[], []]);
<immutable empty digraph with 2 vertices>
gap> IsNonemptyDigraph(D);
false
gap> D := Digraph([[], [1]]);
<immutable digraph with 2 vertices, 1 edge>
gap> IsNonemptyDigraph(D);
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"DigraphHasAVertex">
<ManSection>
<Prop Name=
"DigraphHasAVertex" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
Returns <K>true</K> if the digraph <A>digraph</A> has at least one vertex,
and <K>false</K> if it does not.<P/>
See also <Ref Prop=
"DigraphHasNoVertices"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([]);
<immutable empty digraph with 0 vertices>
gap> DigraphHasAVertex(D);
false
gap> D := Digraph([[]]);
<immutable empty digraph with 1 vertex>
gap> DigraphHasAVertex(D);
true
gap> D := Digraph([[], [1]]);
<immutable digraph with 2 vertices, 1 edge>
gap> DigraphHasAVertex(D);
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"DigraphHasNoVertices">
<ManSection>
<Prop Name=
"DigraphHasNoVertices" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
Returns <K>true</K> if the digraph <A>digraph</A> is the unique digraph
with zero vertices, and <K>false</K> otherwise.<P/>
See also <Ref Prop=
"DigraphHasAVertex"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([]);
<immutable empty digraph with 0 vertices>
gap> DigraphHasNoVertices(D);
true
gap> D := Digraph([[]]);
<immutable empty digraph with 1 vertex>
gap> DigraphHasNoVertices(D);
false
gap> D := Digraph([[], [1]]);
<immutable digraph with 2 vertices, 1 edge>
gap> DigraphHasNoVertices(D);
false]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsEulerianDigraph">
<ManSection>
<Prop Name=
"IsEulerianDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
This property returns true if the digraph <A>digraph</A> is Eulerian.
<P/>
A connected digraph is called <E>Eulerian</E> if there exists a directed
circuit on the digraph which includes every edge exactly once. See
Section <Ref Subsect=
"Definitions" Style=
"Number" /> for the definition of
a directed circuit. Note that the empty digraph with at most one vertex is
considered to be Eulerian.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[]]);
<immutable empty digraph with 1 vertex>
gap> IsEulerianDigraph(D);
true
gap> D := Digraph([[2], []]);
<immutable digraph with 2 vertices, 1 edge>
gap> IsEulerianDigraph(D);
false
gap> D := Digraph([[3], [], [2]]);
<immutable digraph with 3 vertices, 2 edges>
gap> IsEulerianDigraph(D);
false
gap> D := Digraph([[2], [3], [1]]);
<immutable digraph with 3 vertices, 3 edges>
gap> IsEulerianDigraph(D);
true
]]></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.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> gr1 := Digraph([[3], [2], [2], [1], [6], [5]]);
<immutable digraph with 6 vertices, 6 edges>
gap> IsFunctionalDigraph(gr1);
true
gap> gr2 := Digraph([[1, 2], [1]]);
<immutable digraph with 2 vertices, 3 edges>
gap> IsFunctionalDigraph(gr2);
false
gap> gr3 := Digraph(3, [1, 2, 3], [2, 3, 1]);
<immutable digraph with 3 vertices, 3 edges>
gap> IsFunctionalDigraph(gr3);
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsPermutationDigraph">
<ManSection>
<Prop Name=
"IsPermutationDigraph" 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 and each node has only one in-neighbour. <P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> gr1 := Digraph([[3], [2], [2], [1], [6], [5]]);
<immutable digraph with 6 vertices, 6 edges>
gap> IsPermutationDigraph(gr1);
false
gap> gr2 := Digraph([[1, 2], [1]]);
<immutable digraph with 2 vertices, 3 edges>
gap> IsPermutationDigraph(gr2);
false
gap> gr3 := Digraph(3, [1, 2, 3], [2, 3, 1]);
<immutable digraph with 3 vertices, 3 edges>
gap> IsPermutationDigraph(gr3);
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsHamiltonianDigraph">
<ManSection>
<Prop Name=
"IsHamiltonianDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
If <A>digraph</A> is Hamiltonian, then this property returns
<K>true</K>, and <K>false</K> if it is not. <P/>
A digraph with <C>n</C> vertices is <E>Hamiltonian</E> if it has a
directed cycle of length <C>n</C>. See Section <Ref Subsect=
"Definitions"
Style=
"Number" /> for the definition of a directed cycle.
Note the empty digraphs on 0 and 1 vertices are considered to be
Hamiltonian.<P/>
The method used in this operation has the worst case complexity as
<Ref Oper=
"DigraphMonomorphism"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> g := Digraph([[]]);
<immutable empty digraph with 1 vertex>
gap> IsHamiltonianDigraph(g);
true
gap> g := Digraph([[2], [1]]);
<immutable digraph with 2 vertices, 2 edges>
gap> IsHamiltonianDigraph(g);
true
gap> g := Digraph([[3], [], [2]]);
<immutable digraph with 3 vertices, 2 edges>
gap> IsHamiltonianDigraph(g);
false
gap> g := Digraph([[2], [3], [1]]);
<immutable digraph with 3 vertices, 3 edges>
gap> IsHamiltonianDigraph(g);
true
]]></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 Prop=
"IsInRegularDigraph"/> and
<Ref Prop=
"IsOutRegularDigraph"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> IsRegularDigraph(CompleteDigraph(4));
true
gap> IsRegularDigraph(ChainDigraph(4));
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 Prop=
"IsOutRegularDigraph"/> and
<Ref Prop=
"IsRegularDigraph"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<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>.
<P/>
See also <Ref Prop=
"IsInRegularDigraph"/> and
<Ref Prop=
"IsRegularDigraph"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> IsOutRegularDigraph(CompleteDigraph(4));
true
gap> IsOutRegularDigraph(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>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := DigraphSymmetricClosure(ChainDigraph(5));;
gap> IsDistanceRegularDigraph(D);
false
gap> D := Digraph([[2, 3, 4], [1, 3, 4], [1, 2, 4], [1, 2, 3]]);
<immutable digraph with 4 vertices, 12 edges>
gap> IsDistanceRegularDigraph(D);
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/>
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[1, 2], [2]]);
<immutable digraph with 2 vertices, 3 edges>
gap> IsReflexiveDigraph(D);
true
gap> D := Digraph([[3, 1], [4, 2], [3], [2, 1]]);
<immutable digraph with 4 vertices, 7 edges>
gap> IsReflexiveDigraph(D);
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 <C>u</C> and range <C>v</C>, there is a corresponding edge with
source <C>v</C> and range <C>u</C>. If there are <C>n</C> edges with
source <C>u</C> and range <C>v</C>, then there must be precisely <C>n</C>
edges with source <C>v</C> and range <C>u</C>. In other words, a symmetric
digraph has a symmetric adjacency matrix <Ref Attr=
"AdjacencyMatrix"/>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> gr1 := Digraph([[2], [1, 3], [2, 3]]);
<immutable 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]]);
<immutable 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"/>
<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/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> gr1 := Digraph([[2], [1, 3], [2, 3]]);
<immutable 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]]);
<immutable 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/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[1, 2], [3], [3]]);
<immutable digraph with 3 vertices, 4 edges>
gap> IsTransitiveDigraph(D);
false
gap> gr2 := Digraph([[1, 2, 3], [3], [3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsTransitiveDigraph(gr2);
true
gap> gr2 = DigraphTransitiveClosure(D);
true
gap> gr3 := Digraph([[1, 2, 2, 3], [3, 3], [3]]);
<immutable multidigraph with 3 vertices, 7 edges>
gap> IsTransitiveDigraph(gr3);
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsMeetSemilatticeDigraph">
<ManSection>
<Prop Name=
"IsMeetSemilatticeDigraph" Arg=
"digraph"/>
<Prop Name=
"IsJoinSemilatticeDigraph" Arg=
"digraph"/>
<Prop Name=
"IsLatticeDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
<C>IsMeetSemilatticeDigraph</C> returns <K>true</K> if the digraph
<A>digraph</A> is a meet semilattice; <C>IsJoinSemilatticeDigraph</C>
returns <K>true</K> if the digraph <A>digraph</A> is a join semilattice;
and <C>IsLatticeDigraph</C> returns <K>true</K> if the digraph
<A>digraph</A> is both a meet and a join semilattice.
<P/>
For a partial order digraph <Ref Prop=
"IsPartialOrderDigraph"/> the
corresponding partial order is the relation <M>\leq</M>, defined by
<M>x \leq y</M> if and only if <C>[x, y]</C> is an edge.
A digraph is a <E>meet semilattice</E> if it is a partial order and every
pair of vertices has a greatest lower bound (meet) with respect to the
aforementioned relation. A <E>join semilattice</E> is a partial order where
every pair of vertices has a least upper bound (join) with respect to
the relation.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[1, 3], [2, 3], [3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsMeetSemilatticeDigraph(D);
false
gap> IsJoinSemilatticeDigraph(D);
true
gap> IsLatticeDigraph(D);
false
gap> D := Digraph([[1], [2], [1 .. 3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsJoinSemilatticeDigraph(D);
false
gap> IsMeetSemilatticeDigraph(D);
true
gap> IsLatticeDigraph(D);
false
gap> D := Digraph([[1 .. 4], [2, 4], [3, 4], [4]]);
<immutable digraph with 4 vertices, 9 edges>
gap> IsMeetSemilatticeDigraph(D);
true
gap> IsJoinSemilatticeDigraph(D);
true
gap> IsLatticeDigraph(D);
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsDistributiveLatticeDigraph">
<ManSection>
<Prop Name=
"IsDistributiveLatticeDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
<C>IsDistributiveLatticeDigraph</C> returns <K>true</K> if the digraph
<A>digraph</A> is a distributive lattice digraph.<P/>
A <E>distributive lattice digraph</E> is a lattice digraph (<Ref
Prop=
"IsLatticeDigraph"/>) which is distributive. That is to say, the
functions <Ref Oper=
"PartialOrderDigraphMeetOfVertices"/> and <Ref
Oper=
"PartialOrderDigraphJoinOfVertices"/> distribute over each other.<P/>
Equivalently, a distributive lattice digraph is a lattice digraph in which
the <E>lattice digraphs</E> representing <M>M3</M> and <M>N5</M> are not
embeddable as lattices
(see <
URL>
https://en.wikipedia.org/wiki/Distributive_lattice</
URL> and
<Ref Prop=
"IsLatticeEmbedding"
Label=
"for digraphs and a permutation or transformation"/>).<P/>
<Alt Only=
"HTML">
<![
CDATA[
<figure>
<img height=
"200" src=
"m3.png"/>
<img height=
"200" src=
"n5.png"/>
<figcaption>The lattices <e>M3</e> and <e>N5</e>.</figcaption>
</figure>
]]>
</Alt>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[2, 3], [4], [4], []]);
<immutable digraph with 4 vertices, 4 edges>
gap> D := DigraphReflexiveTransitiveClosure(D);
<immutable preorder digraph with 4 vertices, 9 edges>
gap> IsDistributiveLatticeDigraph(D);
true
gap> N5 := Digraph([[2, 4], [3], [5], [5], []]);
<immutable digraph with 5 vertices, 5 edges>
gap> N5 := DigraphReflexiveTransitiveClosure(N5);
<immutable preorder digraph with 5 vertices, 13 edges>
gap> IsDistributiveLatticeDigraph(N5);
false]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsModularLatticeDigraph">
<ManSection>
<Prop Name=
"IsModularLatticeDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
<C>IsModularLatticeDigraph</C> returns <K>true</K> if the digraph
<A>digraph</A> is a modular lattice digraph.<P/>
A <E>modular lattice digraph</E> is a lattice digraph (<Ref
Prop=
"IsLatticeDigraph"/>) which is modular. That is to say, the lattice
digraph representing <M>N5</M> is not embeddable as a lattice (see
<
URL>
https://en.wikipedia.org/wiki/Modular_lattice</
URL> and <Ref
Prop=
"IsLatticeEmbedding"
Label=
"for digraphs and a permutation or transformation"/>).<P/>
<Alt Only=
"HTML">
<![
CDATA[
<figure>
<img height=
"200" src=
"n5.png"/>
<figcaption>The lattice <e>N5</e>.</figcaption>
</figure>
]]>
</Alt>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := ChainDigraph(5);
<immutable chain digraph with 5 vertices>
gap> D := DigraphReflexiveTransitiveClosure(D);
<immutable preorder digraph with 5 vertices, 15 edges>
gap> IsModularLatticeDigraph(D);
true
gap> N5 := Digraph([[2, 3], [4], [4], []]);
<immutable digraph with 4 vertices, 4 edges>
gap> DigraphReflexiveTransitiveClosure(N5);
<immutable preorder digraph with 4 vertices, 9 edges>
gap> IsModularLatticeDigraph(N5);
false
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsPreorderDigraph">
<ManSection>
<Prop Name=
"IsPreorderDigraph" Arg=
"digraph"/>
<Prop Name=
"IsQuasiorderDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
A digraph is a preorder digraph if and only if the digraph satisfies both
<Ref Prop=
"IsReflexiveDigraph"/> and <Ref Prop=
"IsTransitiveDigraph"/>.
A preorder digraph (or quasiorder digraph) <A>digraph</A> corresponds to
the preorder relation <M>\leq</M> defined by <M>x \leq y</M> if and only
if <C>[x, y]</C> is an edge of <A>digraph</A>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[1], [2, 3], [2, 3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsPreorderDigraph(D);
true
gap> D := Digraph([[1 .. 4], [1 .. 4], [1 .. 4], [1 .. 4]]);
<immutable digraph with 4 vertices, 16 edges>
gap> IsPreorderDigraph(D);
true
gap> D := Digraph([[2], [3], [4], [5], [1]]);
<immutable digraph with 5 vertices, 5 edges>
gap> IsPreorderDigraph(D);
false
gap> D := Digraph([[1], [1, 2], [2, 3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsQuasiorderDigraph(D);
false
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsPartialOrderDigraph">
<ManSection>
<Prop Name=
"IsPartialOrderDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
A digraph is a partial order digraph if and only if the digraph satisfies
all of <Ref Prop=
"IsReflexiveDigraph"/>,
<Ref Prop=
"IsAntisymmetricDigraph"/> and <Ref Prop=
"IsTransitiveDigraph"/>.
A partial order <A>digraph</A> corresponds
to the partial order relation <M>\leq</M> defined by <M>x \leq y</M> if and
only if <C>[x, y]</C> is an edge of <A>digraph</A>.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[1, 3], [2, 3], [3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsPartialOrderDigraph(D);
true
gap> D := CycleDigraph(5);
<immutable cycle digraph with 5 vertices>
gap> IsPartialOrderDigraph(D);
false
gap> D := Digraph([[1, 1], [1, 1, 2], [3], [3, 3, 4, 4]]);
<immutable multidigraph with 4 vertices, 10 edges>
gap> IsPartialOrderDigraph(D);
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsEquivalenceDigraph">
<ManSection>
<Prop Name=
"IsEquivalenceDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
A digraph is an equivalence digraph if and only if the digraph satisfies
all of <Ref Prop=
"IsReflexiveDigraph"/>,
<Ref Prop=
"IsSymmetricDigraph"/> and <Ref Prop=
"IsTransitiveDigraph"/>.
A partial order <A>digraph</A> corresponds to an equivalence relation.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := Digraph([[1, 3], [2], [1, 3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsEquivalenceDigraph(D);
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsBridgelessDigraph">
<ManSection>
<Prop Name=
"IsBridgelessDigraph" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
A connected digraph is <E>bridgeless</E> if it is still connected (in the
sense of <Ref Prop=
"IsConnectedDigraph"/>) when any edge is removed.
If <A>digraph</A> has at least 3 vertices, then <Ref
Prop=
"IsBiconnectedDigraph"/> implies <C>IsBridgelessDigraph</C>;
see <Ref Attr=
"ArticulationPoints"/> or <Ref Attr=
"Bridges"/> for a more
detailed explanation.
<P/>
<C>IsBridgelessDigraph</C> returns <K>true</K> if the digraph
<A>digraph</A> is bridgeless, and <K>false</K> if it is not. In
particular, <C>IsBridgelessDigraph</C> returns <K>false</K> if
<A>digraph</A> is not connected. <P/>
Multiple edges are ignored by this method. <P/>
The method used in this operation 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 in
the digraph.
<P/>
See also <Ref Attr=
"Bridges"/>, <Ref Attr=
"ArticulationPoints"/>, and
<Ref Prop=
"IsBiconnectedDigraph"/>. <P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> IsBridgelessDigraph(Digraph([[1, 3], [2, 3], [3]]));
false
gap> IsBridgelessDigraph(CycleDigraph(5));
true
gap> D := Digraph([[1, 1], [1, 1, 2], [3], [3, 3, 4, 4]]);;
gap> IsBridgelessDigraph(D);
false
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 5, 4);
<mutable digraph with 9 vertices, 40 edges>
gap> IsBridgelessDigraph(D);
true
gap> D := Digraph([[2, 5], [1, 3, 4, 5], [2, 4], [2, 3], [1, 2]]);
<immutable digraph with 5 vertices, 12 edges>
gap> IsBridgelessDigraph(D);
true
gap> IsBiconnectedDigraph(D);
false
gap> D := Digraph([[2], [3], [4], [2]]);
<immutable digraph with 4 vertices, 4 edges>
gap> IsBridgelessDigraph(D);
false
gap> IsBiconnectedDigraph(D);
false
gap> IsBridgelessDigraph(ChainDigraph(2));
false
gap> IsBiconnectedDigraph(ChainDigraph(2));
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"IsUpperSemimodularDigraph">
<ManSection>
<Prop Name=
"IsUpperSemimodularDigraph" Arg=
"D"/>
<Prop Name=
"IsLowerSemimodularDigraph" Arg=
"D"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
<C>IsUpperSemimodularDigraph</C> returns <K>true</K> if the digraph
<A>D</A> represents an upper semimodular lattice and <K>false</K> if it
does not. Similarly, <C>IsLowerSemimodularDigraph</C> returns <K>true</K>
if <A>D</A> represents a lower semimodular lattice and <K>false</K> if
it does not. <P/>
In a lattice we say that a vertex <C>a</C> <E>covers</E> a vertex <C>b</C>
if <C>a</C> is greater than <C>b</C>, and there are no further vertices
between <C>a</C> and <C>b</C>. A lattice is <E>upper semimodular</E> if
whenever the meet of <C>a</C> and <C>b</C> is covered by <C>a</C>, the join
of <C>a</C> and <C>b</C> covers <C>b</C>. <E>Lower semimodularity</E> is
defined analogously. <P/>
See also <Ref Prop=
"IsLatticeDigraph"/>, <Ref Oper=
"NonUpperSemimodularPair"/>,
and <Ref Oper=
"NonLowerSemimodularPair"/>.
&MUTABLE_RECOMPUTED_PROP;
<Example><![
CDATA[
gap> D := DigraphFromDigraph6String(
>
"&M~~sc`lYUZO__KIBboC_@h?U_?_GL?A_?c");
<immutable digraph with 14 vertices, 66 edges>
gap> IsUpperSemimodularDigraph(D);
true
gap> IsLowerSemimodularDigraph(D);
false]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label=
"Is2EdgeTransitive">
<ManSection>
<Prop Name=
"Is2EdgeTransitive" Arg=
"digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
If <A>digraph</A> is a digraph without multiple edges, then <C>Is2EdgeTransitive</C>
returns <K>true</K> if <A>digraph</A> is 2-edge transitive, and <K>false</K>
otherwise. If <A>digraph</A> has multiple edges, then <C>Is2EdgeTransitive</C> returns an error.
A digraph is <E>2-edge transitive</E> if its automorphism group
acts transitively on 2-edges via the action
<Ref Func=
"OnTuples" BookName=
"ref"/>. A <E>2-edge</E> in a digraph is a triple (u, v, w) of distinct
vertices
such that (u, v) and (v, w) are edges.
<P/>
&MUTABLE_RECOMPUTED_PROP;
<Example><![CDATA[
gap> Is2EdgeTransitive(CompleteDigraph(4));
true
gap> Is2EdgeTransitive(DigraphByEdges([[1, 2], [2, 3], [3, 4]]));
false
gap> Is2EdgeTransitive(CycleDigraph(5));
true
gap> Is2EdgeTransitive(Digraph([[2], [3, 3, 3], []]));
Error, the argument <D> must be a digraph with no multiple edges,
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>