#############################################################################
##
#W oper.xml
#Y Copyright (C) 2014-19 James D. Mitchell
##
## Licensing information can be found in the README file of this package.
##
#############################################################################
##
<#GAPDoc Label="DigraphKings">
<ManSection>
<Oper Name="DigraphKings" Arg="D, n"/>
<Returns>A list.</Returns>
<Description>
If <A>D</A> is a tournament, then this operation returns a list of the
<A>n</A>-kings in the tournament (see <Ref Oper="DigraphIsKing"/>).<P/>
If <A>D</A> is not tournament, then an error is given
(see <Ref Prop="IsTournament"/>).
If the tournament contains a source, then the source is the only 2-king
(see <Ref Attr="DigraphSources"/>). The number of 2-kings in a tournament
without a source is at least three. A tournament cannot have exactly two
2-kings.
<#GAPDoc Label="DigraphIsKing">
<ManSection>
<Oper Name="DigraphIsKing" Arg="D, v, k"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
If <A>D</A> is a tournament and <A>v</A> is a vertex in the tournament,
then this operation returns <K>true</K> if every other vertex of <A>D</A>
is reachable from <A>v</A> by a path of length at most <A>k</A>. Otherwise,
an error is given.
If <K>true</K> is returned, then the vertex, <A>v</A>, is a <A>k</A>-king.
<P/>
<#GAPDoc Label="IsSubdigraph">
<ManSection>
<Oper Name="IsSubdigraph" Arg="super, sub"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
If <A>super</A> and <A>sub</A> are digraphs, then this operation returns
<K>true</K> if <A>sub</A> is a subdigraph of <A>super</A>, and <K>false</K>
if it is not. <P/>
A digraph <A>sub</A> is a <E>subdigraph</E> of a digraph <A>super</A> if
<A>sub</A> and <A>super</A> share the same number of vertices, and the
collection of edges of <A>super</A> (including repeats) contains the
collection of edges of <A>sub</A> (including repeats). <P/>
In other words, <A>sub</A> is a subdigraph of <A>super</A> if and only if
<C>DigraphNrVertices(<A>sub</A>) = DigraphNrVertices(<A>super</A>)</C>, and
for each pair of vertices <C>i</C> and <C>j</C>, there are at least as many
edges of the form <C>[i, j]</C> in <A>super</A> as there are in <A>sub</A>.
<P/>
<#GAPDoc Label="IsUndirectedSpanningTree">
<ManSection>
<Oper Name="IsUndirectedSpanningTree" Arg="super, sub"/>
<Oper Name="IsUndirectedSpanningForest" Arg="super, sub"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
The operation <C>IsUndirectedSpanningTree</C> returns <K>true</K> if the
digraph <A>sub</A> is an undirected spanning tree of the digraph
<A>super</A>, and the operation <C>IsUndirectedSpanningForest</C> returns
<K>true</K> if the digraph <A>sub</A> is an undirected spanning forest of
the digraph <A>super</A>. <P/>
An <E>undirected spanning tree</E> of a digraph <A>super</A> is a subdigraph
of <A>super</A> that is an undirected tree (see <Ref Oper="IsSubdigraph" />
and <Ref Prop="IsUndirectedTree" />). Note that a digraph whose <Ref
Oper="MaximalSymmetricSubdigraph"/> is not connected has no undirected
spanning trees (see <Ref Prop="IsConnectedDigraph"/>). <P/>
An <E>undirected spanning forest</E> of a digraph <A>super</A> is a
subdigraph of <A>super</A> that is an undirected forest (see <Ref
Oper="IsSubdigraph"/> and <Ref Prop="IsUndirectedForest"/>), and is not
contained in any larger such subdigraph of <A>super</A>. Equivalently, an
undirected spanning forest is a subdigraph of <A>super</A> whose connected
components coincide with those of the <Ref
Oper="MaximalSymmetricSubdigraph"/> of <A>super</A> (see <Ref
Attr="DigraphConnectedComponents"/>). <P/>
Note that an undirected spanning tree is an undirected spanning forest that
is connected.
<Example><![CDATA[
gap> D := CompleteDigraph(4);
<immutable complete digraph with 4 vertices>
gap> tree := Digraph([[3], [4], [1, 4], [2, 3]]);
<immutable digraph with 4 vertices, 6 edges>
gap> IsSubdigraph(D, tree) and IsUndirectedTree(tree);
true
gap> IsUndirectedSpanningTree(D, tree);
true
gap> forest := EmptyDigraph(4);
<immutable empty digraph with 4 vertices>
gap> IsSubdigraph(D, forest) and IsUndirectedForest(forest);
true
gap> IsUndirectedSpanningForest(D, forest);
false
gap> IsSubdigraph(tree, forest);
true
gap> D := DigraphDisjointUnion(CycleDigraph(2), CycleDigraph(2));
<immutable digraph with 4 vertices, 4 edges>
gap> IsUndirectedTree(D);
false
gap> IsUndirectedForest(D) and IsUndirectedSpanningForest(D, D);
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphReverseEdges">
<ManSection>
<Oper Name="DigraphReverseEdges" Arg="digraph, edges"
Label="for a digraph and a list of edges"/>
<Oper Name="DigraphReverseEdge" Arg="digraph, edge"
Label="for a digraph and an edge"/>
<Oper Name="DigraphReverseEdge" Arg="digraph, src, ran"
Label="for a digraph, source, and range"/>
<Returns>A digraph.</Returns>
<Description>
If <A>digraph</A> is a digraph without multiple edges, and <A>edges</A> is a
list of pairs of vertices of <A>digraph</A> (the entries of each pair
corresponding to the source and the range of an edge, respectively),
then <C>DigraphReverseEdges</C> returns a digraph constructed from
<A>digraph</A> by reversing the orientation of every edge specified by
<A>edges</A>. If only one edge is to be reversed, then
<C>DigraphReverseEdge</C> can be used instead. In this case, the second
argument should just be a single vertex-pair, or the second and third
arguments should be the source and range of an edge respectively. <P/>
Note that even though <A>digraph</A> cannot have multiple edges, the
output may have multiple edges. <P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then the edges
are reversed in <A>digraph</A>. If <A>digraph</A> belongs to <Ref
Filt="IsImmutableDigraph"/>, an immutable copy of <A>digraph</A> with the
specified edges reversed is returned.<P/>
<Example><![CDATA[
gap> D := DigraphFromDiSparse6String(".Tg?i@s?t_e?_qEsC");
<immutable digraph with 21 vertices, 8 edges>
gap> DigraphEdges(D);
[ [ 1, 2 ], [ 1, 7 ], [ 1, 8 ], [ 5, 21 ], [ 7, 19 ], [ 9, 1 ],
[ 11, 2 ], [ 21, 1 ] ]
gap> new := DigraphReverseEdge(D, [7, 19]);
<immutable digraph with 21 vertices, 8 edges>
gap> DigraphEdges(new);
[ [ 1, 2 ], [ 1, 7 ], [ 1, 8 ], [ 5, 21 ], [ 9, 1 ], [ 11, 2 ],
[ 19, 7 ], [ 21, 1 ] ]
gap> D2 := DigraphMutableCopy(new);;
gap> new := DigraphReverseEdges(D2, [[19, 7]]);;
gap> D2 = new;
true
gap> D = new;
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="OnDigraphs">
<ManSection>
<Oper Name="OnDigraphs" Arg="digraph, perm"
Label="for a digraph and a perm"/>
<Oper Name="OnDigraphs" Arg="digraph, trans"
Label="for a digraph and a transformation"/>
<Returns>A digraph.</Returns>
<Description>
If <A>digraph</A> is a digraph, and the second argument <A>perm</A> is a
<E>permutation</E> of the vertices of <A>digraph</A>, then this operation
returns a digraph constructed by relabelling the vertices of
<A>digraph</A> according to <A>perm</A>. Note that for an automorphism
<C>f</C> of a digraph, we have <C>OnDigraphs(<A>digraph</A>, f) =
</C><A>digraph</A>.
<P/>
If the second argument is a <E>transformation</E> <A>trans</A> of the
vertices of <A>digraph</A>, then this operation returns a digraph
constructed by transforming the source and range of each edge according to
<A>trans</A>. Thus a vertex which does not appear in the image of
<A>trans</A> will be isolated in the returned digraph, and the returned
digraph may contain multiple edges, even if <A>digraph</A> does not.
If <A>trans</A> is mathematically a permutation, then the result coincides
with <C>OnDigraphs(<A>digraph</A>, AsPermutation(<A>trans</A>))</C>.
<P/>
The <Ref Oper="DigraphVertexLabels"/> of <A>digraph</A> will not be retained
in the returned digraph. <P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then
relabelling of the vertices is performed directly on <A>digraph</A>.
If <A>digraph</A> belongs to <Ref Filt="IsImmutableDigraph"/>, an immutable
copy of <A>digraph</A> with the vertices relabelled is returned.<P/>
<#GAPDoc Label="OnMultiDigraphs">
<ManSection>
<Oper Name="OnMultiDigraphs" Arg="digraph, pair"/>
<Oper Name="OnMultiDigraphs" Arg="digraph, perm1, perm2"
Label="for a digraph, perm, and perm"/>
<Returns>A digraph.</Returns>
<Description>
If <A>digraph</A> is a digraph, and <A>pair</A> is a pair consisting of a
permutation of the vertices and a permutation of the edges of
<A>digraph</A>, then this operation returns a digraph
constructed by relabelling the vertices and edges of <A>digraph</A>
according to <A>perm[1]</A> and <A>perm[2]</A>, respectively. <P/>
In its second form, <C>OnMultiDigraphs</C> returns a digraph with vertices
and edges permuted by <A>perm1</A> and <A>perm2</A>, respectively. <P/>
Note that <C>OnDigraphs(<A>digraph</A>,
perm)=OnMultiDigraphs(<A>digraph</A>, [perm, ()])</C> where <C>perm</C> is
a permutation of the vertices of <A>digraph</A>. If you are only interested
in the action of a permutation on the vertices of a digraph, then you can
use <C>OnDigraphs</C> instead of <C>OnMultiDigraphs</C>.
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then
relabelling of the vertices is performed directly on <A>digraph</A>.
If <A>digraph</A> belongs to <Ref Filt="IsImmutableDigraph"/>, an immutable
copy of <A>digraph</A> with the vertices relabelled is returned.<P/>
<#GAPDoc Label="OnTuplesDigraphs">
<ManSection>
<Oper Name="OnTuplesDigraphs" Arg="list, perm"
Label="for a list of digraphs and a perm"/>
<Oper Name="OnSetsDigraphs" Arg="list, perm"
Label="for a set of digraphs and a perm"/>
<Returns>A list or set of digraphs.</Returns>
<Description>
If <A>list</A> is a list of digraphs, and <A>perm</A> is a
<E>permutation</E> of the vertices of the digraphs in <A>list</A>, then
<Ref Oper="OnTuplesDigraphs" Label="for a list of digraphs and a perm"/>
returns a new list constructed by applying <A>perm</A> via
<Ref Oper="OnDigraphs" Label="for a digraph and a perm"/>
to a copy (with the same mutability) of each entry of <A>list</A> in turn.
<P/>
More precisely, <C>OnTuplesDigraphs(<A>list</A>,<A>perm</A>)</C> is a list
of length <C>Length(<A>list</A>)</C>, whose <C>i</C>-th entry is
<C>OnDigraphs(DigraphCopy(<A>list</A>[i]), <A>perm</A>)</C>.
<P/>
If <A>list</A> is moreover a &GAP; set (i.e. a duplicate-free sorted list),
then <Ref Oper="OnSetsDigraphs" Label="for a set of digraphs and a perm"/>
returns the sorted output of
<Ref Oper="OnTuplesDigraphs" Label="for a list of digraphs and a perm"/>,
which is therefore again a set.
<Example><![CDATA[
gap> list := [CycleDigraph(IsMutableDigraph, 6),
> DigraphReverse(CycleDigraph(6))];
[ <mutable digraph with 6 vertices, 6 edges>,
<immutable digraph with 6 vertices, 6 edges> ]
gap> p := (1, 6)(2, 5)(3, 4);;
gap> result_tuples := OnTuplesDigraphs(list, p);
[ <mutable digraph with 6 vertices, 6 edges>,
<immutable digraph with 6 vertices, 6 edges> ]
gap> result_tuples[2] = OnDigraphs(list[2], p);
true
gap> result_tuples = list;
false
gap> result_tuples = Reversed(list);
true
gap> result_sets := OnSetsDigraphs(list, p);
[ <immutable digraph with 6 vertices, 6 edges>,
<mutable digraph with 6 vertices, 6 edges> ]
gap> result_sets = list;
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphAddVertex">
<ManSection>
<Oper Name="DigraphAddVertex" Arg="digraph[, label ]"/>
<Returns>A digraph.</Returns>
<Description>
The operation returns a digraph constructed from <A>digraph</A> by adding a
single new vertex, and no new edges. <P/>
If the optional second argument <A>label</A> is a &GAP; object,
then the new vertex will be labelled <A>label</A>.
<P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then the
vertex is added directly to <A>digraph</A>. If <A>digraph</A> belongs to
<Ref Filt="IsImmutableDigraph"/>, an immutable copy of <A>digraph</A> with
the additional vertex is returned.<P/>
<Example><![CDATA[
gap> D := CompleteDigraph(3);
<immutable complete digraph with 3 vertices>
gap> new := DigraphAddVertex(D);
<immutable digraph with 4 vertices, 6 edges>
gap> D = new;
false
gap> DigraphVertices(new);
[ 1 .. 4 ]
gap> new := DigraphAddVertex(D, Group([(1, 2)]));
<immutable digraph with 4 vertices, 6 edges>
gap> DigraphVertexLabels(new);
[ 1, 2, 3, Group([ (1,2) ]) ]
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 2, 3);
<mutable digraph with 5 vertices, 12 edges>
gap> new := DigraphAddVertex(D);
<mutable digraph with 6 vertices, 12 edges>
gap> D = new;
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphAddVertices">
<ManSection>
<Oper Name="DigraphAddVertices" Arg="digraph, m"
Label="for a digraph and an integer"/>
<Oper Name="DigraphAddVertices" Arg="digraph, labels"
Label="for a digraph and a list of labels"/> <!-- The 3-argument version is deliberately undocumented. It is redundant,
but it is included for backwards compatibility. -->
<Returns>A digraph.</Returns>
<Description>
For a non-negative integer <A>m</A>, this operation returns a digraph
constructed from <A>digraph</A> by adding <A>m</A> new vertices.
<P/>
Otherwise, if <A>labels</A> is a list
consisting of <C>k</C> &GAP; objects, then this operation returns a
digraph constructed from <A>digraph</A> by adding <C>k</C> new vertices,
which are labelled according to this list.
<P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then the
vertices are added directly to <A>digraph</A>, which is changed in-place.
If <A>digraph</A> belongs to <Ref Filt="IsImmutableDigraph"/>, then
<A>digraph</A> itself is returned if no vertices are added
(i.e. <C><A>m</A>=0</C> or <A>labels</A> is empty), otherwise
the result is a new immutable digraph.
<P/>
<Example><![CDATA[
gap> D := CompleteDigraph(3);
<immutable complete digraph with 3 vertices>
gap> new := DigraphAddVertices(D, 3);
<immutable digraph with 6 vertices, 6 edges>
gap> DigraphVertices(new);
[ 1 .. 6 ]
gap> new := DigraphAddVertices(D, [Group([(1, 2)]), "d"]);
<immutable digraph with 5 vertices, 6 edges>
gap> DigraphVertexLabels(new);
[ 1, 2, 3, Group([ (1,2) ]), "d" ]
gap> DigraphAddVertices(D, 0) = D;
true
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 2, 3);
<mutable digraph with 5 vertices, 12 edges>
gap> new := DigraphAddVertices(D, 4);
<mutable digraph with 9 vertices, 12 edges>
gap> D = new;
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphRemoveVertex">
<ManSection>
<Oper Name="DigraphRemoveVertex" Arg="digraph, v"/>
<Returns>A digraph.</Returns>
<Description>
If <A>v</A> is a vertex of <A>digraph</A>, then this operation returns a
digraph constructed from <A>digraph</A> by removing vertex <A>v</A>,
along with any edge whose source or range vertex is <A>v</A>.<P/>
If <A>digraph</A> has <C>n</C> vertices, then the vertices of the returned
digraph are <C>[1..n-1]</C>, but the original labels can be
accessed via <Ref Oper="DigraphVertexLabels"/>. <P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then the
vertex is removed directly from <A>digraph</A>. If <A>digraph</A> belongs
to <Ref Filt="IsImmutableDigraph"/>, an immutable copy of <A>digraph</A>
without the vertex is returned.<P/>
<#GAPDoc Label="DigraphRemoveVertices">
<ManSection>
<Oper Name="DigraphRemoveVertices" Arg="digraph, verts"/>
<Returns>A digraph.</Returns>
<Description>
If <A>verts</A> is a (possibly empty) duplicate-free list of vertices of
<A>digraph</A>, then this operation returns a digraph constructed from
<A>digraph</A> by removing every vertex in <A>verts</A>, along with any edge
whose source or range vertex is in <A>verts</A>.<P/>
If <A>digraph</A> has <C>n</C> vertices, then the vertices of the new
digraph are <C>[1 .. n-Length(<A>verts</A>)]</C>, but the
original labels can be accessed via <Ref Oper="DigraphVertexLabels"/>. <P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then the
vertices are removed directly from <A>digraph</A>. If <A>digraph</A> belongs
to <Ref Filt="IsImmutableDigraph"/>, an immutable copy of <A>digraph</A>
without the vertices is returned.<P/>
<Example><![CDATA[
gap> D := Digraph([[3], [1, 3, 5], [1], [1, 2, 4], [2, 3, 5]]);
<immutable digraph with 5 vertices, 11 edges>
gap> SetDigraphVertexLabels(D, ["a", "b", "c", "d", "e"]);
gap> new := DigraphRemoveVertices(D, [2, 4]);
<immutable digraph with 3 vertices, 4 edges>
gap> DigraphVertexLabels(new);
[ "a", "c", "e" ]
gap> D := CycleDigraph(IsMutableDigraph, 5);
<mutable digraph with 5 vertices, 5 edges>
gap> new := DigraphRemoveVertices(D, [1, 3]);
<mutable digraph with 3 vertices, 1 edge>
gap> DigraphVertexLabels(D);
[ 2, 4, 5 ]
gap> D = new;
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphAddEdge">
<ManSection>
<Oper Name="DigraphAddEdge" Arg="digraph, edge"
Label="for a digraph and an edge"/>
<Oper Name="DigraphAddEdge" Arg="digraph, src, ran"
Label="for a digraph, source, and range"/>
<Returns>A digraph.</Returns>
<Description>
If <A>edge</A> is a pair of vertices of <A>digraph</A>, or <A>src</A> and
<A>ran</A> are vertices of <A>digraph</A>,
then this operation returns a digraph constructed from <A>digraph</A>
by adding a new edge with source <A>edge</A><C>[1]</C> [<A>src</A>] and range
<A>edge</A><C>[2]</C> [<A>ran</A>].
<P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then the edge
is added directly to <A>digraph</A>. If <A>digraph</A> belongs to <Ref
Filt="IsImmutableDigraph"/>, then an immutable copy of <A>digraph</A> with the
additional edge is returned. <P/>
<#GAPDoc Label="DigraphAddEdges">
<ManSection>
<Oper Name="DigraphAddEdges" Arg="digraph, edges"/>
<Returns>A digraph.</Returns>
<Description>
If <A>edges</A> is a (possibly empty) list of pairs of vertices of
<A>digraph</A>, then this operation returns a digraph constructed from
<A>digraph</A> by adding the edges specified by <A>edges</A>. More
precisely, for every <C>edge</C> in <A>edges</A>, a new edge
will be added with source <C>edge[1]</C> and range <C>edges[2]</C>.
<P/>
If an edge is included in <A>edges</A> with multiplicity <C>k</C>,
then it will be added <C>k</C> times.
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then the edges
are added directly to <A>digraph</A>. If <A>digraph</A> belongs to <Ref
Filt="IsImmutableDigraph"/>, then the result is returned as an immutable
digraph.
<P/>
<Example><![CDATA[
gap> func := function(n)
> local source, range, i;
> source := [];
> range := [];
> for i in [1 .. n - 2] do
> Add(source, i);
> Add(range, i + 1);
> od;
> return Digraph(n, source, range);
> end;;
gap> D := func(1024);
<immutable digraph with 1024 vertices, 1022 edges>
gap> new := DigraphAddEdges(D,
> [[1023, 1024], [1, 1024], [1023, 1024], [1024, 1]]);
<immutable multidigraph with 1024 vertices, 1026 edges>
gap> D = new;
false
gap> D2 := DigraphMutableCopy(func(1024));
<mutable digraph with 1024 vertices, 1022 edges>
gap> new := DigraphAddEdges(D2,
> [[1023, 1024], [1, 1024], [1023, 1024], [1024, 1]]);
<mutable multidigraph with 1024 vertices, 1026 edges>
gap> D2 = new;
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphRemoveEdge">
<ManSection>
<Oper Name="DigraphRemoveEdge" Arg="digraph, edge"
Label="for a digraph and an edge"/>
<Oper Name="DigraphRemoveEdge" Arg="digraph, src, ran"
Label="for a digraph, source, and range"/>
<Returns>A digraph.</Returns>
<Description>
If <A>digraph</A> is a digraph with no multiple edges and <A>edge</A> is a
pair of vertices of <A>digraph</A>, or <A>src</A> and <A>ran</A> are
vertices of <A>digraph</A>, then this operation returns a digraph
constructed from <A>digraph</A> by removing the edge specified by
<A>edge</A> or <A>[src, ran]</A>. <P/>
If <A>digraph</A> belongs to <Ref
Filt="IsMutableDigraph"/>, then the edge is removed directly from
<A>digraph</A>. If <A>digraph</A> belongs to <Ref
Filt="IsImmutableDigraph"/>, an immutable copy of <A>digraph</A> without
the edge is returned.
<P/>
Note that if <A>digraph</A> belongs to <Ref Filt="IsImmutableDigraph"/>,
then a new copy of <A>digraph</A> will be returned even if <A>edge</A> or
<A>[src, ran]</A> does not define an edge of <A>digraph</A>.<P/>
<Example><![CDATA[
gap> D := CycleDigraph(250000);
<immutable cycle digraph with 250000 vertices>
gap> D := DigraphRemoveEdge(D, [250000, 1]);
<immutable digraph with 250000 vertices, 249999 edges>
gap> new := DigraphRemoveEdge(D, [25000, 2]);;
gap> new = D;
true
gap> IsIdenticalObj(new, D);
false
gap> D := DigraphMutableCopy(D);;
gap> new := DigraphRemoveEdge(D, 2500, 2);;
gap> IsIdenticalObj(new, D);
true]]>
</Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphRemoveEdges">
<ManSection>
<Oper Name="DigraphRemoveEdges" Arg="digraph, edges"/>
<Returns>A digraph.</Returns>
<Description>
If one of the following holds:
<List>
<Item>
<A>digraph</A> is a digraph with no multiple edges, and
<A>edges</A> is a list of pairs of vertices of <A>digraph</A>, or
</Item>
<Item> <A>digraph</A> is a digraph and <A>edges</A> is an empty list </Item>
</List>
then this operation returns a digraph constructed from <A>digraph</A>
by removing all of the edges specified by <A>edges</A>
(see <Ref Oper="DigraphRemoveEdge" Label="for a digraph and an edge"/>).
<P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then the edge
is removed directly from <A>digraph</A>. If <A>digraph</A> belongs to <Ref
Filt="IsImmutableDigraph"/>, the edge is removed from an immutable copy of
<A>digraph</A> and this new digraph is returned.<P/>
Note that if <A>edges</A> is empty, then this operation
will always return <A>digraph</A> rather than a copy. Also, if any element
of <A>edges</A> is invalid (i.e. does not define an edge of <A>digraph</A>)
then that element will simply be ignored.
<Example><![CDATA[
gap> D := CycleDigraph(250000);
<immutable cycle digraph with 250000 vertices>
gap> D := DigraphRemoveEdges(D, [[250000, 1]]);
<immutable digraph with 250000 vertices, 249999 edges>
gap> D := DigraphMutableCopy(D);
<mutable digraph with 250000 vertices, 249999 edges>
gap> new := DigraphRemoveEdges(D, [[1, 2], [2, 3], [3, 100]]);
<mutable digraph with 250000 vertices, 249997 edges>
gap> new = D;
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="InducedSubdigraph">
<ManSection>
<Oper Name="InducedSubdigraph" Arg="digraph, verts"/>
<Returns>A digraph.</Returns>
<Description>
If <A>digraph</A> is a digraph, and <A>verts</A> is a subset of the
vertices of <A>digraph</A>, then this operation returns a digraph
constructed from <A>digraph</A> by retaining precisely those vertices in
<A>verts</A>, and those edges whose source and range vertices are both
contained in <A>verts</A>. <P/>
The vertices of the induced subdigraph are
<C>[1..Length(verts)]</C> but the original vertex labels can be
accessed via <Ref Oper="DigraphVertexLabels"/>. <P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then
<A>digraph</A> is modified in place. If <A>digraph</A> belongs to <Ref
Filt="IsImmutableDigraph"/>, a new immutable digraph containing the
appropriate
vertices and edges is returned.<P/>
<Example><![CDATA[
gap> D := Digraph([[1, 1, 2, 3, 4, 4], [1, 3, 4], [3, 1], [1, 1]]);
<immutable multidigraph with 4 vertices, 13 edges>
gap> InducedSubdigraph(D, [1, 3, 4]);
<immutable multidigraph with 3 vertices, 9 edges>
gap> DigraphVertices(last);
[ 1 .. 3 ]
gap> D := DigraphMutableCopy(D);
<mutable multidigraph with 4 vertices, 13 edges>
gap> new := InducedSubdigraph(D, [1, 3, 4]);
<mutable multidigraph with 3 vertices, 9 edges>
gap> D = new;
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="OutDegreeOfVertex">
<ManSection>
<Oper Name="OutDegreeOfVertex" Arg="digraph, vertex"/>
<Returns>The non-negative integer.</Returns>
<Description>
This operation returns the out-degree of the vertex <A>vertex</A> in the
digraph <A>digraph</A>.
The out-degree of <A>vertex</A> is the number of edges in <A>digraph</A>
whose source is <A>vertex</A>.
<P/>
<Example><![CDATA[
gap> D := Digraph([
> [2, 2, 1], [1, 4], [2, 2, 4, 2], [1, 1, 2, 2, 1, 2, 2]]);
<immutable multidigraph with 4 vertices, 16 edges>
gap> OutDegreeOfVertex(D, 1);
3
gap> OutDegreeOfVertex(D, 2);
2
gap> OutDegreeOfVertex(D, 3);
4
gap> OutDegreeOfVertex(D, 4);
7
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="OutNeighboursOfVertex">
<ManSection>
<Oper Name="OutNeighboursOfVertex" Arg="digraph, vertex"/>
<Oper Name="OutNeighborsOfVertex" Arg="digraph, vertex"/>
<Returns>A list of vertices.</Returns>
<Description>
This operation returns the list <C>out</C> of vertices of the digraph
<A>digraph</A>.
A vertex <C>i</C> appears in the list <C>out</C> each time there exists an
edge with source <A>vertex</A> and range <C>i</C> in <A>digraph</A>; in
particular, this means that <C>out</C> may contain duplicates.<P/>
<Example><![CDATA[
gap> D := Digraph([
> [2, 2, 3], [1, 3, 4], [2, 2, 3], [1, 1, 2, 2, 1, 2, 2]]);
<immutable multidigraph with 4 vertices, 16 edges>
gap> OutNeighboursOfVertex(D, 1);
[ 2, 2, 3 ]
gap> OutNeighboursOfVertex(D, 3);
[ 2, 2, 3 ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="InDegreeOfVertex">
<ManSection>
<Oper Name="InDegreeOfVertex" Arg="digraph, vertex"/>
<Returns>A non-negative integer.</Returns>
<Description>
This operation returns the in-degree of the vertex <A>vertex</A> in the
digraph <A>digraph</A>.
The in-degree of <A>vertex</A> is the number of edges in <A>digraph</A>
whose range is <A>vertex</A>.
<Example><![CDATA[
gap> D := Digraph([
> [2, 2, 1], [1, 4], [2, 2, 4, 2], [1, 1, 2, 2, 1, 2, 2]]);
<immutable multidigraph with 4 vertices, 16 edges>
gap> InDegreeOfVertex(D, 1);
5
gap> InDegreeOfVertex(D, 2);
9
gap> InDegreeOfVertex(D, 3);
0
gap> InDegreeOfVertex(D, 4);
2
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="InNeighboursOfVertex">
<ManSection>
<Oper Name="InNeighboursOfVertex" Arg="digraph, vertex"/>
<Oper Name="InNeighborsOfVertex" Arg="digraph, vertex"/>
<Returns>A list of positive vertices.</Returns>
<Description>
This operation returns the list <C>inn</C> of vertices of the digraph
<A>digraph</A>.
A vertex <C>i</C> appears in the list <C>inn</C> each time there exists an
edge with source <C>i</C> and range <A>vertex</A> in <A>digraph</A>; in
particular, this means that <C>inn</C> may contain duplicates. <P/>
<#GAPDoc Label="DigraphInEdges">
<ManSection>
<Oper Name="DigraphInEdges" Arg="digraph, vertex"/>
<Returns>A list of edges.</Returns>
<Description>
<C>DigraphInEdges</C> returns the list of all edges of <A>digraph</A>
which have <A>vertex</A> as their range.
<Example><![CDATA[
gap> D := Digraph([[2, 2], [3, 3], [4, 4], [1, 1]]);
<immutable multidigraph with 4 vertices, 8 edges>
gap> DigraphInEdges(D, 2);
[ [ 1, 2 ], [ 1, 2 ] ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphOutEdges">
<ManSection>
<Oper Name="DigraphOutEdges" Arg="digraph, vertex"/>
<Returns>A list of edges.</Returns>
<Description>
<C>DigraphOutEdges</C> returns the list of all edges of <A>digraph</A>
which have <A>vertex</A> as their source.
<Example><![CDATA[
gap> D := Digraph([[2, 2], [3, 3], [4, 4], [1, 1]]);
<immutable multidigraph with 4 vertices, 8 edges>
gap> DigraphOutEdges(D, 2);
[ [ 2, 3 ], [ 2, 3 ] ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphStronglyConnectedComponent">
<ManSection>
<Oper Name="DigraphStronglyConnectedComponent" Arg="digraph, vertex"/>
<Returns>A list of vertices.</Returns>
<Description>
If <A>vertex</A> is a vertex in the digraph <A>digraph</A>, then
this operation returns the strongly connected component of <A>vertex</A>
in <A>digraph</A>.
See <Ref Attr="DigraphStronglyConnectedComponents"/> for more information.
<Example><![CDATA[
gap> D := Digraph([[3], [2], [1, 2], [3]]);
<immutable digraph with 4 vertices, 5 edges>
gap> DigraphStronglyConnectedComponent(D, 3);
[ 1, 3 ]
gap> DigraphStronglyConnectedComponent(D, 2);
[ 2 ]
gap> DigraphStronglyConnectedComponent(D, 4);
[ 4 ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphConnectedComponent">
<ManSection>
<Oper Name="DigraphConnectedComponent" Arg="digraph, vertex"/>
<Returns>A list of vertices.</Returns>
<Description>
If <A>vertex</A> is a vertex in the digraph <A>digraph</A>, then
this operation returns the connected component of <A>vertex</A>
in <A>digraph</A>.
See <Ref Attr="DigraphConnectedComponents"/> for more information.
<Example><![CDATA[
gap> D := Digraph([[3], [2], [1, 2], [4]]);
<immutable digraph with 4 vertices, 5 edges>
gap> DigraphConnectedComponent(D, 3);
[ 1, 2, 3 ]
gap> DigraphConnectedComponent(D, 2);
[ 1, 2, 3 ]
gap> DigraphConnectedComponent(D, 4);
[ 4 ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="QuotientDigraph">
<ManSection>
<Oper Name="QuotientDigraph" Arg="digraph, p"/>
<Returns>A digraph.</Returns>
<Description>
If <A>digraph</A> is a digraph, and <A>p</A> is a partition of the vertices
of <A>digraph</A>, then this operation returns a digraph constructed by
amalgamating all vertices of <A>digraph</A> which lie in the same part of
<A>p</A>.
<P/>
A partition of the vertices of <A>digraph</A> is a list of non-empty
disjoint lists, such that the union of all the sub-lists is equal
to vertex set of <A>digraph</A>. In particular, each vertex must appear
in precisely one sub-list.
<P/>
The vertices of <A>digraph</A> in part <C>i</C> of <A>p</A> will become
vertex <C>i</C> in the quotient, and there exists some edge in <A>digraph</A>
with source in part <C>i</C> and range in part <C>j</C> if and only if there
is an edge from <C>i</C> to <C>j</C> in the quotient.
In particular, this means that the quotient of a digraph has no multiple edges.
which was a change introduced in version 1.0.0 of the &Digraphs; package.
<P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then
<A>digraph</A> is modified in place. If <A>digraph</A> belongs to <Ref
Filt="IsImmutableDigraph"/>, a new immutable digraph with the above
properties is returned.<P/>
<#GAPDoc Label="IsDigraphEdge">
<ManSection>
<Oper Name="IsDigraphEdge" Arg="digraph, list"
Label="for digraph and list"/>
<Oper Name="IsDigraphEdge" Arg="digraph, u, v"
Label="for digraph and two pos ints"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
In the first form, this function returns <K>true</K> if and only if the list
<A>list</A> specifies an edge in the digraph <A>digraph</A>. Specifically,
this operation returns <K>true</K> if <A>list</A> is a pair of positive
integers where <A>list</A><C>[1]</C> is the source and <A>list</A><C>[2]</C>
is the range of an edge in <A>digraph</A>, and <K>false</K> otherwise. <P/>
The second form simply returns <K>true</K> if <C>[<A>u</A>, <A>v</A>]</C> is
an edge in <A>digraph</A>, and <K>false</K> otherwise.
<#GAPDoc Label="DigraphFloydWarshall">
<ManSection>
<Oper Name="DigraphFloydWarshall" Arg="digraph, func, nopath, edge"/>
<Returns>A matrix.</Returns>
<Description>
If <A>digraph</A> is a digraph with <M>n</M> vertices, then
this operation returns an <M>n \times n</M> matrix <C>mat</C> containing
the output of a generalised version of the Floyd-Warshall algorithm,
applied to <A>digraph</A>. <P/>
The operation <C>DigraphFloydWarshall</C> is customised by the arguments
<A>func</A>, <A>nopath</A>, and <A>edge</A>.
The arguments <A>nopath</A> and <A>edge</A> can be arbitrary &GAP; objects.
The argument <A>func</A> must be a function which accepts 4 arguments:
the matrix <C>mat</C>, followed by 3 positive integers. The function
<A>func</A> is where the work to calculate the desired outcome must be
performed. <P/>
This method initialises the matrix <C>mat</C> by setting entry
<C>mat[i][j]</C> to equal <A>edge</A> if there is an edge with source
<C>i</C> and range <C>j</C>, and by setting entry <C>mat[i][j]</C> to equal
<A>nopath</A> otherwise.
The final part of <C>DigraphFloydWarshall</C> then calls the function
<A>func</A> inside three nested for loops, over the vertices of
<A>digraph</A>: <P/>
<Listing><![CDATA[
for i in DigraphsVertices(digraph) do
for j in DigraphsVertices(digraph) do
for k in DigraphsVertices(digraph) do
func(mat, i, j, k);
od;
od;
od;
]]></Listing>
The matrix <C>mat</C> is then returned as the result. An example of using
<C>DigraphFloydWarshall</C> to calculate the shortest (non-zero) distances
between the vertices of a digraph is shown below: <P/>
<#GAPDoc Label="DigraphEdgeUnion">
<ManSection>
<Func Name="DigraphEdgeUnion" Arg="D1, D2, ..."
Label="for a positive number of digraphs"/>
<Func Name="DigraphEdgeUnion" Arg="list" Label="for a list of digraphs"/>
<Returns>A digraph.</Returns>
<Description>
In the first form, if <A>D1</A>, <A>D2</A>, etc. are digraphs, then
<C>DigraphEdgeUnion</C> returns their edge union.
In the second form, if <A>list</A> is a non-empty list of digraphs, then
<C>DigraphEdgeUnion</C> returns the edge union of the digraphs contained
in the list. <P/>
The vertex set of the edge union of a collection of digraphs is the
<E>union</E> of the vertex sets, whilst the edge list of the edge union is
the <E>concatenation</E> of the edge lists. The number of vertices of the
edge union is equal to the <E>maximum</E> number of vertices of one of the
digraphs, whilst the number of edges of the edge union will equal the
<E>sum</E> of the number of edges of each digraph. <P/>
Note that previously set <Ref Oper="DigraphVertexLabels"/> will be lost.
<P/>
If the first digraph <A>D1</A> [<A>list[1]</A>] belongs to <Ref
Filt="IsMutableDigraph"/>, then <A>D1</A> [<A>list[1]</A>] is modified in
place to contain the appropriate vertices and edges. If <A>digraph</A> belongs
to <Ref Filt="IsImmutableDigraph"/>, a new immutable digraph containing the
appropriate vertices and edges is returned.
<Example><![CDATA[
gap> D := CycleDigraph(10);
<immutable cycle digraph with 10 vertices>
gap> DigraphEdgeUnion(D, D);
<immutable multidigraph with 10 vertices, 20 edges>
gap> D1 := Digraph([[2], [1]]);
<immutable digraph with 2 vertices, 2 edges>
gap> D2 := Digraph([[2, 3], [2], [1]]);
<immutable digraph with 3 vertices, 4 edges>
gap> union := DigraphEdgeUnion(D1, D2);
<immutable multidigraph with 3 vertices, 6 edges>
gap> OutNeighbours(union);
[ [ 2, 2, 3 ], [ 1, 2 ], [ 1 ] ]
gap> union = DigraphByEdges(
> Concatenation(DigraphEdges(D1), DigraphEdges(D2)));
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphDisjointUnion">
<ManSection>
<Func Name="DigraphDisjointUnion" Arg="D1, D2, ..." Label="for an
arbitrary number of digraphs"/>
<Func Name="DigraphDisjointUnion" Arg="list" Label="for a list of digraphs"/>
<Returns>A digraph.</Returns>
<Description>
In the first form, if <A>D1</A>, <A>D2</A>, etc. are digraphs, then
<C>DigraphDisjointUnion</C> returns their disjoint union.
In the second form, if <A>list</A> is a non-empty list of digraphs, then
<C>DigraphDisjointUnion</C> returns the disjoint union of the digraphs
contained in the list. <P/>
For a disjoint union of digraphs, the vertex set is the disjoint union of
the vertex sets, and the edge list is the disjoint union of the edge lists.
<P/>
More specifically, for a collection of digraphs <A>D1</A>, <A>D2</A>,
<C>...</C>, the disjoint union with have
<C>DigraphNrVertices(</C><A>D1</A><C>)</C> <C>+</C>
<C>DigraphNrVertices(</C><A>D2</A><C>)</C> <C>+</C> <C>...</C> vertices.
The edges of <A>D1</A> will remain unchanged, whilst the edges of the
<C>i</C>th digraph, <A>D</A><C>[i]</C>, will be changed so that they
belong to the vertices of the disjoint union corresponding to
<A>D</A><C>[i]</C>. In particular, the edges of <A>D</A><C>[i]</C> will
have their source and range increased by
<C>DigraphNrVertices(</C><A>D1</A><C>)</C> <C>+</C> <C>...</C> <C>+</C>
<C>DigraphNrVertices(</C><A>D</A><C>[i-1])</C>.
<P/>
Note that previously set <Ref Oper="DigraphVertexLabels"/> will be lost.<P/>
If the first digraph <A>D1</A> [<A>list[1]</A>] belongs to <Ref
Filt="IsMutableDigraph"/>, then <A>D1</A> [<A>list[1]</A>] is modified in
place to contain the appropriate vertices and edges. If <A>digraph</A> belongs
to <Ref Filt="IsImmutableDigraph"/>, a new immutable digraph containing the
appropriate vertices and edges is returned.
<Example><![CDATA[
gap> D1 := CycleDigraph(3);
<immutable cycle digraph with 3 vertices>
gap> OutNeighbours(D1);
[ [ 2 ], [ 3 ], [ 1 ] ]
gap> D2 := CompleteDigraph(3);
<immutable complete digraph with 3 vertices>
gap> OutNeighbours(D2);
[ [ 2, 3 ], [ 1, 3 ], [ 1, 2 ] ]
gap> union := DigraphDisjointUnion(D1, D2);
<immutable digraph with 6 vertices, 9 edges>
gap> OutNeighbours(union);
[ [ 2 ], [ 3 ], [ 1 ], [ 5, 6 ], [ 4, 6 ], [ 4, 5 ] ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphJoin">
<ManSection>
<Func Name="DigraphJoin" Arg="D1, D2, ..."
Label="for a positive number of digraphs"/>
<Func Name="DigraphJoin" Arg="list" Label="for a list of digraphs"/>
<Returns>A digraph.</Returns>
<Description>
In the first form, if <A>D1</A>, <A>D2</A>, etc. are digraphs, then
<C>DigraphJoin</C> returns their join.
In the second form, if <A>list</A> is a non-empty list of digraphs,
then <C>DigraphJoin</C> returns the join of the digraphs contained in the
list. <P/>
The join of a collection of digraphs <A>D1</A>, <A>D2</A>, <C>...</C> is
formed by first taking the <Ref Func="DigraphDisjointUnion"
Label="for a list of digraphs"/> of the collection.
In the disjoint union, if <M>i \neq j</M> then there are no edges between
vertices corresponding to digraphs <A>D</A><C>[i]</C> and
<A>D</A><C>[j]</C> in the collection; the join is created by including
all such edges.<P/>
For example, the join of two empty digraphs is a complete bipartite
digraph.<P/>
Note that previously set <Ref Oper="DigraphVertexLabels"/> will be lost.
<P/>
If the first digraph <A>D1</A> [<A>list[1]</A>] belongs to <Ref
Filt="IsMutableDigraph"/>, then <A>D1</A> [<A>list[1]</A>] is modified in
place to contain the appropriate vertices and edges. If <A>digraph</A> belongs
to <Ref Filt="IsImmutableDigraph"/>, a new immutable digraph containing the
appropriate vertices and edges is returned.
<Example><![CDATA[
gap> D := CompleteDigraph(3);
<immutable complete digraph with 3 vertices>
gap> IsCompleteDigraph(DigraphJoin(D, D));
true
gap> D2 := CycleDigraph(3);
<immutable cycle digraph with 3 vertices>
gap> DigraphJoin(D, D2);
<immutable digraph with 6 vertices, 27 edges>
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphCartesianProduct">
<ManSection>
<Func Name="DigraphCartesianProduct" Arg="gr1, gr2, ..."
Label="for a positive number of digraphs"/>
<Func Name="DigraphCartesianProduct" Arg="list"
Label="for a list of digraphs"/>
<Returns>A digraph.</Returns>
<Description>
In the first form, if <A>gr1</A>, <A>gr2</A>, etc. are digraphs, then
<C>DigraphCartesianProduct</C> returns a digraph isomorphic to their
Cartesian product.
<P/>
In the second form, if <A>list</A> is a non-empty list of digraphs,
then <C>DigraphCartesianProduct</C> returns a digraph isomorphic to the
Cartesian product of the digraphs contained in the list.
<P/>
Mathematically, the Cartesian product of two digraphs <C>G</C>, <C>H</C>
is a digraph with vertex set <C>Cartesian(DigraphVertices(G),
DigraphVertices(H))</C> such that there is an edge from <C>[u, u']</C> to
<C>[v, v']</C> iff <C> u = v </C> and there is an edge from <C>u'</C> to
<C>v'</C> in <C>H</C> or <C> u' = v'</C> and there is an edge from
<C>u</C> to <C>v</C> in <C>G</C>.
<P/>
Due to technical reasons, the digraph <C>D</C> returned by
<C>DigraphCartesianProduct</C> has vertex set
<C>[1 .. DigraphNrVertices(G)*DigraphNrVertices(H)]</C> instead, and the
exact
method of encoding pairs of vertices into integers is implementation
specific. The original vertex pair can be somewhat regained by using
<Ref Attr="DigraphCartesianProductProjections"/>. In addition,
<Ref Oper="DigraphVertexLabels"/> are preserved: if vertex pair
<C>[u,u']</C> was encoded as <C>i</C> then the vertex label of <C>i</C>
will be the pair of vertex labels of <C>u</C> and <C>u'</C> i.e.
<C>DigraphVertexLabel(D,i) = [DigraphVertexLabel(G,u),
DigraphVertexLabel(H,u')]</C>.
<P/>
As the Cartesian product is associative, the Cartesian product of a collection
of digraphs <A>gr1</A>, <A>gr2</A>, <C>...</C> is computed in the obvious
fashion.
<P/>
<#GAPDoc Label="DigraphDirectProduct">
<ManSection>
<Func Name="DigraphDirectProduct" Arg="gr1, gr2, ..."
Label="for a positive number of digraphs"/>
<Func Name="DigraphDirectProduct" Arg="list"
Label="for a list of digraphs"/>
<Returns>A digraph.</Returns>
<Description>
In the first form, if <A>gr1</A>, <A>gr2</A>, etc. are digraphs, then
<C>DigraphDirectProduct</C> returns a digraph isomorphic to their direct
product.
<P/>
In the second form, if <A>list</A> is a non-empty list of digraphs, then
<C>DigraphDirectProduct</C> returns a digraph isomorphic to the direct
product of the digraphs contained in the list.
<P/>
Mathematically, the direct product of two digraphs <C>G</C>, <C>H</C> is a
digraph with vertex set <C>Cartesian(DigraphVertices(G),
DigraphVertices(H))</C> such that there is an edge from <C>[u, u']</C>
to <C>[v, v']</C> iff there is an edge from <C>u</C> to <C>v</C> in
<C>G</C> and an edge from <C>u'</C> to <C>v'</C> in <C>H</C>.
<P/>
Due to technical reasons, the digraph <C>D</C> returned by
<C>DigraphDirectProduct</C> has vertex set
<C>[1 .. DigraphNrVertices(G)*DigraphNrVertices(H)]</C> instead, and the
exact method of encoding pairs of vertices into integers is implementation
specific. The original vertex pair can be somewhat regained by using
<Ref Attr="DigraphDirectProductProjections"/>. In addition
<Ref Oper="DigraphVertexLabels"/> are preserved: if vertex pair
<C>[u,u']</C> was encoded as <C>i</C> then the vertex label of <C>i</C>
will be the pair of vertex labels of <C>u</C> and <C>u'</C> i.e.
<C>DigraphVertexLabel(D,i) = [DigraphVertexLabel(G,u),
DigraphVertexLabel(H,u')]</C>.
<P/>
As the direct product is associative, the direct product of a collection
of digraphs <A>gr1</A>, <A>gr2</A>, <C>...</C> is computed in the obvious
fashion.
<P/>
<#GAPDoc Label="IsReachable">
<ManSection>
<Oper Name="IsReachable" Arg="digraph, u, v"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
This operation returns <K>true</K> if there exists a non-trivial directed
walk from vertex <A>u</A> to vertex <A>v</A> in the digraph <A>digraph</A>,
and <K>false</K> if there does not exist such a directed walk. See Section
<Ref Subsect="Definitions" Style="Number" /> for the definition of a
non-trivial directed walk.
<P/>
The method for <C>IsReachable</C> has worst case complexity of <M>O(m +
n)</M> where <M>m</M> is the number of edges and <M>n</M> the number of
vertices in <A>digraph</A>.
<#GAPDoc Label="VerticesReachableFrom">
<ManSection>
<Oper Name="VerticesReachableFrom" Arg="digraph, root" Label="for a digraph and vertex"/>
<Oper Name="VerticesReachableFrom" Arg="digraph, list" Label="for a digraph and a list of vertices"/>
<Returns>A list.</Returns>
<Description>
This operation returns a list of the vertices <C>v</C>, for which there
exists a non-trivial directed walk from the vertex <A>root</A>, or any of
the list of vertices <A>list</A>, to vertex <C>v</C> in the digraph
<A>digraph</A>. See Section <Ref Subsect="Definitions" Style="Number" />
for the definition of a non-trivial directed walk.
<P/>
The method for <C>VerticesReachableFrom</C> has worst case complexity of
<M>O(m + n)</M> where <M>m</M> is the number of edges and <M>n</M> the
number of vertices in <A>digraph</A>.
<P/>
This function returns an error if <A>root</A>, or any vertex in <A>list</A>,
is not a vertices of <A>digraph</A>.
<#GAPDoc Label="DigraphPath">
<ManSection>
<Oper Name="DigraphPath" Arg="digraph, u, v"/>
<Returns>A pair of lists, or <K>fail</K>.</Returns>
<Description>
If there exists a non-trivial directed path (or a non-trivial cycle, in the
case that <A>u</A> <C>=</C> <A>v</A>) from vertex <A>u</A> to vertex
<A>v</A> in the digraph <A>digraph</A>, then this operation returns such a
directed path (or directed cycle). Otherwise, this operation returns
<K>fail</K>. See Section <Ref Subsect="Definitions" Style="Text"/> for the
definition of a directed path and a directed cycle.
<P/>
A directed path (or directed cycle) of non-zero length <C>n-1</C>,
<M>(v_1, e_1, v_2, e_2, ..., e_{n-1}, v_n)</M>,
is represented by a pair of lists <C>[v,a]</C> as follows:
<List>
<Item>
<C>v</C> is the list <M>[v_1, v_2, ..., v_n]</M>.
</Item>
<Item>
<C>a</C> is the list of positive integers <M>[a_1, a_2, ..., a_{n-1}]</M>
where for each each <M>i < n</M>, <M>a_i</M> is the position of
<M>v_{i+1}</M> in
<C>OutNeighboursOfVertex(</C><A>digraph</A><C>,</C><M>v_i</M><C>)</C>
corresponding to the edge <M>e_i</M>. This can be useful if the
position of a vertex in a list of out-neighours is significant, for
example in orbit digraphs.
</Item>
</List>
The method for <C>DigraphPath</C> has worst case complexity of <M>O(m +
n)</M> where <M>m</M> is the number of edges and <M>n</M> the number of
vertices in <A>digraph</A>.<P/>
<#GAPDoc Label="DigraphShortestPathSpanningTree">
<ManSection>
<Oper Name="DigraphShortestPathSpanningTree" Arg="digraph, v"/>
<Returns>A digraph, or <K>fail</K>.</Returns>
<Description>
If <A>v</A> is a vertex in <A>digraph</A> and every other
vertex of <A>digraph</A> is reachable from <A>v</A>,
then this operation returns the shortest path spanning tree of
<A>digraph</A> rooted at <A>v</A>.
If there exist vertices in <A>digraph</A> (other than <A>v</A>) that are
not reachable from <A>v</A>, then <C>DigraphShortestPathSpanningTree</C>
returns <K>fail</K>. See <Ref Oper="IsReachable"/>. <P/>
The <E>shortest path spanning tree of <A>digraph</A> rooted at <A>v</A></E>
is a subdigraph of <A>digraph</A> that is a directed tree, with unique
source vertex <A>v</A>, and where for each other vertex <A>u</A> in
<A>digraph</A>, the unique directed path from <A>v</A> to <A>u</A> in the
tree is the lexicographically-least shortest directed path from <A>v</A> to
<A>u</A> in <A>digraph</A>. <P/>
See <Ref Prop="IsDirectedTree"/>, <Ref Attr="DigraphSources"/>, and
<Ref Oper="DigraphShortestPath"/>. <P/>
If <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>, then
<A>digraph</A> is modified in place. If <A>digraph</A> belongs to <Ref
Filt="IsImmutableDigraph"/>, then the spanning tree is a new immutable
digraph.
<!-- TODO is it *the* lexicographically least shortest path? -->
<#GAPDoc Label="DigraphShortestPath">
<ManSection>
<Oper Name="DigraphShortestPath" Arg="digraph, u, v"/>
<Returns>A pair of lists, or <K>fail</K>.</Returns>
<Description>
Returns a shortest directed path in the digraph <A>digraph</A> from vertex
<A>u</A> to vertex <A>v</A>, if such a path exists. If <C><A>u</A> =
<A>v</A></C>, then the shortest non-trivial cycle is returned, again, if it
exists. Otherwise, this operation returns <K>fail</K>. See Section
<Ref Subsect="Definitions" Style="Text"/> for the definition of a directed
path and a directed cycle.
<P/>
See <Ref Oper="DigraphPath"/> for details on the output.
The method for <C>DigraphShortestPath</C> has worst case complexity of
<M>O(m + n)</M> where <M>m</M> is the number of edges and <M>n</M> the
number of vertices in <A>digraph</A>.
<#GAPDoc Label="DigraphRandomWalk">
<ManSection>
<Oper Name="DigraphRandomWalk" Arg="digraph, v, t"/>
<Returns>A pair of lists.</Returns>
<Description>
Returns a directed path corresponding to a <E>random walk</E> in the digraph
<A>digraph</A>, starting at vertex <A>v</A> and having length no more than
<A>t</A>.
<P/>
A random walk is defined as follows. The path begins at <A>v</A>, and at
each step it follows a random edge leaving the current vertex. It continues
through the digraph in this way until it has traversed <A>t</A> edges, or
until it reaches a vertex with no out-edges (a <E>sink</E>) and therefore
cannot continue.
<P/>
The output has the same form as that of <Ref Oper="DigraphPath"/>.
<P/>
<#GAPDoc Label="IteratorOfPaths">
<ManSection>
<Oper Name="IteratorOfPaths" Arg="digraph, u, v"/>
<Returns>An iterator.</Returns>
<Description>
If <A>digraph</A> is a digraph or a list of adjacencies which defines a
digraph - see <Ref Attr="OutNeighbours"/> - then this operation returns an
iterator of the non-trivial directed paths (or directed cycles, in the case
that <A>u</A> <C>=</C> <A>v</A>) in <A>digraph</A> from the vertex <A>u</A>
to the vertex <A>v</A>.
<P/>
See <Ref Oper="DigraphPath"/> for more information about the representation
of a directed path or directed cycle which is used, and see <Ref
Sect="Iterators" BookName="ref"/> for more information about iterators.
See Section <Ref Subsect="Definitions" Style="Text"/> for the definition of
a directed path and a directed cycle.
<P/>
<#GAPDoc Label="DigraphLongestDistanceFromVertex">
<ManSection>
<Oper Name="DigraphLongestDistanceFromVertex" Arg="digraph, v"/>
<Returns>An integer, or <K>infinity</K>.</Returns>
<Description>
If <A>digraph</A> is a digraph and <A>v</A> is a vertex in <A>digraph</A>,
then this operation returns the length of the longest directed walk in
<A>digraph</A> which begins at vertex <A>v</A>. See Section <Ref
Subsect="Definitions" Style="Number" /> for the definitions of directed
walk, directed cycle, and loop.
<P/>
<List>
<Item>
If there exists a directed walk starting at vertex <A>v</A>
which traverses a loop or a directed cycle,
then we consider there to be a walk of infinite length from <A>v</A>
(realised by repeatedly traversing the loop/directed cycle),
and so the result is <K>infinity</K>.
To disallow walks using loops, try using
<Ref Oper="DigraphRemoveLoops"/>:<P/>
<Item>
Otherwise, if all directed walks
starting at vertex <A>v</A> have finite length,
then the length of the longest such walk is returned.
</Item>
</List>
Note that the result is <C>0</C> if and only if <A>v</A> is a sink of
<A>digraph</A>. See <Ref Attr="DigraphSinks"/>.
<#GAPDoc Label="DigraphLayers">
<ManSection>
<Oper Name="DigraphLayers" Arg="digraph, vertex"/>
<Returns>A list.</Returns>
<Description>
This operation returns a list <K>list</K> such that <K>list[i]</K> is the
list of vertices whose minimum distance from the vertex <A>vertex</A> in
<A>digraph</A> is <K>i - 1</K>. Vertex <A>vertex</A> is
assumed to be at distance <K>0</K> from itself.
<Example><![CDATA[
gap> D := CompleteDigraph(4);;
gap> DigraphLayers(D, 1);
[ [ 1 ], [ 2, 3, 4 ] ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphDistanceSet">
<ManSection>
<Oper Name="DigraphDistanceSet" Label="for a digraph, a pos int, and an int" Arg="digraph, vertex, distance"/>
<Oper Name="DigraphDistanceSet" Label="for a digraph, a pos int, and a list" Arg="digraph, vertex, distances"/>
<Returns>A list of vertices</Returns>
<Description>
This operation returns the list of all vertices in digraph <A>digraph</A>
such that the shortest distance to a vertex <A>vertex</A> is
<A>distance</A> or is in the list <A>distances</A>. <P/>
<A>digraph</A> should be a digraph, <A>vertex</A> should be a positive
integer, <A>distance</A> should be a non-negative integer, and
<A>distances</A> should be a list of non-negative integers.
<#GAPDoc Label="DigraphShortestDistance">
<ManSection>
<Oper Name="DigraphShortestDistance" Label="for a digraph and two vertices"
Arg="digraph, u, v"/>
<Oper Name="DigraphShortestDistance" Label="for a digraph and a list"
Arg="digraph, list"/>
<Oper Name="DigraphShortestDistance" Label="for a digraph, a list, and a list"
Arg="digraph, list1, list2"/>
<Returns>An integer or <K>fail</K></Returns>
<Description>
If there is a directed path in the digraph <A>digraph</A> between vertex
<A>u</A> and vertex <A>v</A>, then this operation returns the length of the
shortest such directed path. If no such directed path exists, then this
operation returns <K>fail</K>. See Section <Ref Subsect="Definitions"
Style="Number" /> for the definition of a directed path. <P/>
If the second form is used, then <A>list</A> should be a list of length two,
containing two positive integers which correspond to the vertices <A>u</A>
and <A>v</A>. <P/>
Note that as usual, a vertex is considered to be at distance 0 from
itself .<P/>
If the third form is used, then <A>list1</A> and <A>list2</A> are both lists
of vertices. The shortest directed path between <A>list1</A> and
<A>list2</A> is then the length of the shortest directed path which starts
with a vertex in <A>list1</A> and terminates at a vertex in <A>list2</A>, if
such directed path exists. If <A>list1</A> and <A>list2</A> have non-empty
intersection, the operation returns <C>0</C>.<P/>
<Example><![CDATA[
gap> D := Digraph([[2], [3], [1, 4], [1, 3], [5]]);
<immutable digraph with 5 vertices, 7 edges>
gap> DigraphShortestDistance(D, 1, 3);
2
gap> DigraphShortestDistance(D, [3, 3]);
0
gap> DigraphShortestDistance(D, 5, 2);
fail
gap> DigraphShortestDistance(D, [1, 2], [4, 5]);
2
gap> DigraphShortestDistance(D, [1, 3], [3, 5]);
0
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="Dominators">
<ManSection>
<Oper Name="Dominators" Arg="digraph, root"/>
<Returns>A list of lists.</Returns>
<Description>
<C>Dominators</C> takes a <A>digraph</A> and a root <A>root</A> and returns
the dominators of each vertex with respect to the root. The output is
returned as a list of length <C>DigraphNrVertices(<A>Digraph</A>)</C>,
whose <A>i</A>th entry is a list with the dominators of vertex <A>i</A> of
the <A>digraph</A>. If there is no path from the root to a specific vertex,
the output will contain a hole in the corresponding position. The
<E>dominators</E> of a vertex <M>u</M> are the vertices that are
contained in every path from the <M>root</M> to <M>u</M>, not including
<M>u</M> itself.
The method for this operation is an implementation of an algorithm by
Thomas Lengauer and Robert Endre Tarjan <Cite Key="LT79"/>. The complexity
of this algorithm is <M>O(mlog n)</M> where <M>m</M> is the number of edges
and <M>n</M> is the number of nodes in the subdigraph induced by the nodes
in <A>digraph</A> reachable from <A>root</A>.
<Example><![CDATA[
gap> D := Digraph([[2], [3, 6], [2, 4], [1], [], [3]]);
<immutable digraph with 6 vertices, 7 edges>
gap> Dominators(D, 1);
[ , [ 1 ], [ 2, 1 ], [ 3, 2, 1 ],, [ 2, 1 ] ]
gap> Dominators(D, 2);
[ [ 4, 3, 2 ],, [ 2 ], [ 3, 2 ],, [ 2 ] ]
gap> Dominators(D, 3);
[ [ 4, 3 ], [ 3 ],, [ 3 ],, [ 2, 3 ] ]
gap> Dominators(D, 4);
[ [ 4 ], [ 1, 4 ], [ 2, 1, 4 ],,, [ 2, 1, 4 ] ]
gap> Dominators(D, 5);
[ ]
gap> Dominators(D, 6);
[ [ 4, 3, 6 ], [ 3, 6 ], [ 6 ], [ 3, 6 ] ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DominatorTree">
<ManSection>
<Oper Name="DominatorTree" Arg="digraph, root"/>
<Returns>A record.</Returns>
<Description>
<C>DominatorTree</C> takes a <A>digraph</A> and a
<A>root</A> vertex and returns a record with the following components:
<List>
<Mark>idom</Mark>
<Item>
the immediate dominators of the vertices with respect
to the root.
</Item>
<Mark>preorder</Mark>
<Item>
the preorder values of the vertices defined by the depth first search
executed on the digraph.
</Item>
</List>
The <E>immediate dominator</E> of a vertex <M>u</M> is the unique dominator
of <M>u</M> that is dominated by all other dominators of <M>u</M>. The
algorithm is an implementation of the fast algorithm written by Thomas
Lengauer and Robert Endre Tarjan <Cite Key="LT79"/>. The complexity of
this algorithm is <M>O(mlog n)</M> where <M>m</M> is the number of edges
and <M>n</M> is the number of nodes in the subdigraph induced by the nodes
in <A>digraph</A> reachable from <A>root</A>.
<Example><![CDATA[
gap> D := Digraph([[2, 3], [4, 6], [4, 5], [3, 5], [1, 6], [2, 3]]);
<immutable digraph with 6 vertices, 12 edges>
gap> DominatorTree(D, 1);
rec( idom := [ fail, 1, 1, 1, 1, 1 ],
preorder := [ 1, 2, 4, 3, 5, 6 ] )
gap> DominatorTree(D, 5);
rec( idom := [ 5, 5, 5, 5, fail, 5 ],
preorder := [ 5, 1, 2, 4, 3, 6 ] )
gap> D := CompleteDigraph(5);
<immutable complete digraph with 5 vertices>
gap> DominatorTree(D, 1);
rec( idom := [ fail, 1, 1, 1, 1 ], preorder := [ 1, 2, 3, 4, 5 ] )
gap> DominatorTree(D, 2);
rec( idom := [ 2, fail, 2, 2, 2 ], preorder := [ 2, 1, 3, 4, 5 ] )
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="PartialOrderDigraphMeetOfVertices">
<ManSection>
<Oper Name="PartialOrderDigraphMeetOfVertices"
Arg="digraph, u, v"/>
<Oper Name="PartialOrderDigraphJoinOfVertices"
Arg="digraph, u, v"/>
<Returns>A positive integer or <K>fail</K></Returns>
<Description>
If the first argument is a partial order digraph <Ref
Prop="IsPartialOrderDigraph"/> then these operations return the meet, or
the join, of the two input vertices. If the meet (or join) is does not
exist then <K>fail</K> is returned. The meet (or join) is guaranteed to
exist when the first argument satisfies
<Ref Prop="IsMeetSemilatticeDigraph"/> (or
<Ref Prop="IsJoinSemilatticeDigraph"/>) - see the documentation for these
properties for the definition of the meet (or the join).
<#GAPDoc Label="DigraphClosure">
<ManSection>
<Oper Name="DigraphClosure" Arg="digraph, k"/>
<Returns>A digraph.</Returns>
<Description>
Given a symmetric loopless digraph with no multiple edges <A>digraph</A>,
the <E><A>k</A>-closure of <A>digraph</A></E> is defined to be the unique
smallest symmetric loopless digraph <C>C</C> with no multiple edges on the
vertices of <A>digraph</A> that contains all the edges of <A>digraph</A>
and satisfies the property that the sum of the degrees of every two
non-adjacenct vertices in <C>C</C> is less than <A>k</A>. See <Ref
Prop="IsSymmetricDigraph"/>, <Ref Prop="DigraphHasLoops"/>, <Ref
Prop="IsMultiDigraph"/>, and <Ref Oper="OutDegreeOfVertex"/>. <P/>
The operation <C>DigraphClosure</C> returns the <A>k</A>-closure of
<A>digraph</A>.
<Example><![CDATA[
gap> D := CompleteDigraph(6);
<immutable complete digraph with 6 vertices>
gap> D := DigraphRemoveEdges(D, [[1, 2], [2, 1]]);
<immutable digraph with 6 vertices, 28 edges>
gap> closure := DigraphClosure(D, 6);
<immutable digraph with 6 vertices, 30 edges>
gap> IsCompleteDigraph(closure);
true
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DigraphContractEdge">
<ManSection>
<Oper Name="DigraphContractEdge" Arg="digraph, edge"
Label="for a digraph and a list of positive integers"/>
<Oper Name="DigraphContractEdge" Arg="digraph, src, ran"
Label="for a digraph and two positive integers"/>
<Returns>A digraph.</Returns>
<Description>
If <A>edge</A> is a pair of vertices of <A>digraph</A>, or <A>src</A> and
<A>ran</A> are vertices of <A>digraph</A>, where <A>ran</A> <> <A>src</A>,
then then this operation merges the two vertices of the edge given into one.
Edges incident to <A>src</A> and <A>ran</A> will now be incident to <C>v</C>,
the new vertex, with their direction preserved. <P/>
A new digraph constructed from <A>digraph</A> is returned,
unless <A>digraph</A> belongs to <Ref Filt="IsMutableDigraph"/>;
in this case changes are made directly to <A>digraph</A>, which is then returned.
The <A>digraph</A> must not belong to <Ref Filt="IsMultiDigraph"/>. <P/>
The labels of any remaining edges will be preserved. <P/>
Assigned vertex labels for <A>src</A> and <A>ran</A> are
combined into a list, and assigned to the new vertex <C>v</C>. <P/>
If an edge <A>[src, src]</A> or <A>[ran, ran]</A> exists,
a singular edge <C>[v, v]</C> is created. If edge <A>[ran, src]</A>
exists, this is also removed. <P/>
<#GAPDoc Label="IsMatching">
<ManSection>
<Oper Name="IsMatching" Arg="digraph, list"/>
<Oper Name="IsMaximalMatching" Arg="digraph, list"/>
<Oper Name="IsMaximumMatching" Arg="digraph, list"/>
<Oper Name="IsPerfectMatching" Arg="digraph, list"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
If <A>digraph</A> is a digraph and <A>list</A> is a list of pairs of
vertices of <A>digraph</A>, then <C>IsMatching</C> returns <K>true</K> if
<A>list</A> is a matching of <A>digraph</A>. The operation
<C>IsMaximalMatching</C> returns <K>true</K> if <A>list</A> is a maximal
matching, <C>IsMaximumMatching</C> returns <K>true</K> if <A>list</A> is a
maximum matching and <C>IsPerfectMatching</C> returns <K>true</K> if
<A>list</A> is a perfect, matching of <A>digraph</A>, respectively.
Otherwise, each of these operations return <K>false</K>.
<P/>
A <E>matching</E> <C>M</C> of a digraph <A>digraph</A> is a subset of the
edges of <A>digraph</A>, i.e. <C>DigraphEdges(<A>digraph</A>)</C>, such
that no pair of distinct edges in <C>M</C> are incident to the same vertex
of <A>digraph</A>. Note that this definition allows a matching to contain
loops. See <Ref Prop="DigraphHasLoops" />. The matching <C>M</C> is
<E>maximal</E> if it is contained in no larger matching of the digraph,
is <E>maximum</E> if it has the greatest cardinality among all matchings and
is <E>perfect</E> if every vertex of the digraph is incident to an edge in
the matching. Every maximum or perfect matching is maximal. Note, however,
that not every perfect matching of digraphs with loops is maximum.
<#GAPDoc Label="DigraphDijkstra">
<ManSection>
<Oper Name="DigraphDijkstra" Arg="digraph, source, target" Label="for a source and target"/>
<Oper Name="DigraphDijkstra" Arg="digraph, source" Label="for a source"/>
<Returns>Two lists.</Returns>
<Description>
If <A>digraph</A> is a digraph and <A>source</A> and <A>target</A> are
vertices of <A>digraph</A>, then <C>DigraphDijkstra</C> calculates the
length of the shortest path from <A>source</A> to <A>target</A> and returns
two lists. Each element of the first list is the distance of the
corresponding element from <A>source</A>. If a vertex was not visited in
the process of calculating the shortest distance to <A>target</A> or if
there is no path connecting that vertex with <A>source</A>, then
the corresponding distance is <K>infinity</K>. Each element of the
second list gives the previous vertex in the shortest path
from <A>source</A> to the corresponding vertex. For
<A>source</A> and for any vertices that remained unvisited this
will be <C>-1</C>.<P/>
If the optional second argument <A>target</A> is not present, then
<C>DigraphDijkstra</C> returns the shortest path from <A>source</A> to
every vertex that is reachable from <A>source</A>.
<#GAPDoc Label="ModularProduct">
<ManSection>
<Oper Name="ModularProduct" Arg="D1, D2"/>
<Returns>A digraph.</Returns>
<Description>
If <A>D1</A> and <A>D2</A> are digraphs without multiple edges, then
<C>ModularProduct</C> calculates the <E>modular product digraph</E>
(<C>MPD</C>) of <A>D1</A> and <A>D2</A>.
<C>MPD</C> has vertex set <C>V1 x V2</C> where <C>V1</C> is the vertex set of
<A>D1</A> and <C>V2</C> is the vertex set of <A>D2</A> (a vertex
<C>[a, b]</C> has label <C>(a - 1) * |V2| + b</C> in the output). There is
an edge from <C>[a, b]</C> to <C>[c, d]</C> precisely when the following
two conditions are satisfied:
<List>
<Item>
The vertices <C>a</C> and <C>c</C> of <A>D1</A> are equal if and only if
the vertices <C>b</C> and <C>d</C> of <A>D2</A> are equal.
</Item>
<Item>
There is an edge from <C>a</C> to <C>c</C> in <A>D1</A> if and only if
there is an edge from <C>b</C> to <C>d</C> in <A>D2</A>.
</Item>
</List>
Notably, the complete (with loops) subdigraphs of <C>MPD</C> are
precisely the partial isomorphisms from <A>D1</A> to <A>D2</A>.
<#GAPDoc Label="StrongProduct">
<ManSection>
<Oper Name="StrongProduct" Arg="D1, D2"/>
<Returns>A digraph.</Returns>
<Description>
If <A>D1</A> and <A>D2</A> are digraphs without multiple edges,
then <C>StrongProduct</C> calculates the <E>strong product digraph</E>
(<C>SPD</C>) of <A>D1</A> and <A>D2</A>.
<C>SPD</C> has vertex set <C>V1 x V2</C> where <C>V1</C> is the vertex set of
<A>D1</A> and <C>V2</C> is the vertex set of <A>D2</A> (a vertex
<C>[a, b]</C> has label <C>(a - 1) * |V2| + b</C> in the output). There is
an edge from <C>[a, b]</C> to <C>[c, d]</C> when at least one of the
following three conditions are satisfied:
<List>
<Item>
The vertices <C>a</C> and <C>c</C> of <A>D1</A> are equal and there is
an edge from <C>b</C> to <C>d</C> in <A>D2</A>.
</Item>
<Item>
The vertices <C>b</C> and <C>d</C> of <A>D2</A> are equal and there is
an edge from <C>a</C> to <C>c</C> in <A>D1</A>.
</Item>
<Item>
There is an edge from <C>a</C> to <C>c</C> in <A>D1</A> and there is
an edge from <C>b</C> to <C>d</C> in <A>D2</A>.
</Item>
</List>
The SPD of two paths of lengths <C>m</C> and <C>n</C> is also the king's graph
for an <C>m</C> by <C>n</C> board.
<#GAPDoc Label="ConormalProduct">
<ManSection>
<Oper Name="ConormalProduct" Arg="D1, D2"/>
<Returns>A digraph.</Returns>
<Description>
If <A>D1</A> and <A>D2</A> are digraphs without multiple edges,
then <C>ConormalProduct</C> calculates the <E>co-normal product digraph</E>
(<C>CNPD</C>) of <A>D1</A> and <A>D2</A>.
<C>CNPD</C> has vertex set <C>V1 x V2</C> where <C>V1</C> is the vertex set of
<A>D1</A> and <C>V2</C> is the vertex set of <A>D2</A> (a vertex
<C>[a, b]</C> has label <C>(a - 1) * |V2| + b</C> in the output). There is
an edge from <C>[a, b]</C> to <C>[c, d]</C> when at least one of the
following two conditions are satisfied:
<List>
<Item>
There is an edge from <C>a</C> to <C>c</C> in <A>D1</A>.
</Item>
<Item>
There is an edge from <C>b</C> to <C>d</C> in <A>D2</A>.
</Item>
</List>
<#GAPDoc Label="HomomorphicProduct">
<ManSection>
<Oper Name="HomomorphicProduct" Arg="D1, D2"/>
<Returns>A digraph.</Returns>
<Description>
If <A>D1</A> and <A>D2</A> are digraphs without multiple edges,
then <C>HomomorphicProduct</C> calculates the <E>homomorphic product digraph</E>
(<C>HPD</C>) of <A>D1</A> and <A>D2</A>.
<C>HPD</C> has vertex set <C>V1 x V2</C> where <C>V1</C> is the vertex set of
<A>D1</A> and <C>V2</C> is the vertex set of <A>D2</A> (a vertex
<C>[a, b]</C> has label <C>(a - 1) * |V2| + b</C> in the output). There is
an edge from <C>[a, b]</C> to <C>[c, d]</C> when at least one of the
following two conditions are satisfied:
<List>
<Item>
The vertices <C>a</C> and <C>c</C> of <A>D1</A> are equal.
</Item>
<Item>
There is an edge from <C>a</C> to <C>c</C> in <A>D1</A> and no edge from
<C>b</C> to <C>d</C> in <A>D2</A>.
</Item>
</List>
<#GAPDoc Label="LexicographicProduct">
<ManSection>
<Oper Name="LexicographicProduct" Arg="D1, D2"/>
<Returns>A digraph.</Returns>
<Description>
If <A>D1</A> and <A>D2</A> are digraphs without multiple edges,
then <C>LexicographicProduct</C> calculates the <E>lexicographic product digraph</E>
(<C>LPD</C>) of <A>D1</A> and <A>D2</A>.
<C>LPD</C> has vertex set <C>V1 x V2</C> where <C>V1</C> is the vertex set of
<A>D1</A> and <C>V2</C> is the vertex set of <A>D2</A> (a vertex
<C>[a, b]</C> has label <C>(a - 1) * |V2| + b</C> in the output). There is
an edge from <C>[a, b]</C> to <C>[c, d]</C> when at least one of the
following two conditions are satisfied:
<List>
<Item>
There is an edge from <C>a</C> to <C>c</C> in <A>D1</A>.
</Item>
<Item>
The vertices <C>a</C> and <C>c</C> of <A>D1</A> are equal and there is
an edge from <C>b</C> to <C>d</C> in <A>D2</A>.
</Item>
</List>
<#GAPDoc Label="IsDigraphPath">
<ManSection>
<Oper Name="IsDigraphPath" Arg="D, v, a"/>
<Oper Name="IsDigraphPath" Arg="D, list" Label="for a digraph and list"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
This function returns <K>true</K> if the arguments <A>v</A> and <A>a </A>
describe a path in the digraph <A>D</A>.
A directed path (or directed cycle) of non-zero length <C>n-1</C>,
<M>(v_1, e_1, v_2, e_2, ..., e_{n-1}, v_n)</M>,
is represented by a pair of lists <C>[<A>v</A>, <A>a</A>]</C> as follows:
<List>
<Item>
<A>v</A> is the list <M>[v_1, v_2, ..., v_n]</M>.
</Item>
<Item>
<A>a</A> is the list of positive integers <M>[a_1, a_2, ..., a_{n-1}]</M>
where for each each <M>i < n</M>, <M>a_i</M> is the position of
<M>v_{i+1}</M> in
<C>OutNeighboursOfVertex(</C><A>D</A><C>,</C><M>v_i</M><C>)</C>
corresponding to the edge <M>e_i</M>. This can be useful if the
position of a vertex in a list of out-neighours is significant, for
example in orbit digraphs.
</Item>
</List>
If the arguments to <C>IsDigraphPath</C> are a digraph <A>D</A> and list
<A>list</A>, then this is equivalent to calling <C>IsDigraphPath(<A>D</A>,
<A>list</A>[1], <A>list</A>[2])</C>.
<#GAPDoc Label="DigraphCycleBasis">
<ManSection>
<Oper Name="DigraphCycleBasis" Arg="digraph"/>
<Returns>A list and a list of GF(2) vectors</Returns>
<Description>
If <A>digraph</A> is a symmetric loopless digraph with no multiple edges, then
<C>DigraphCycleBasis</C> calculates the <E>fundamental cycle basis</E> of
<A>digraph</A> and returns a list of edges and a list of a basis vectors.
If <A>digraph</A> contains a loop, this function will return an error. If <A>digraph</A>
is a multi-digraph, then multiple edges incident to the same vertices are treated as a single edge by this function.
See <Ref Prop="IsSymmetricDigraph"/>, <Ref Prop="DigraphHasLoops"/>, and <Ref
Prop="IsMultiDigraph"/>.
The first list returned contains the out-neighours that provide the ordering
on the edges with the symmetric edges appearing only once;
these are the same as <E>OutNeighbours(MaximalAntiSymmetricSubdigraph(G))</E>.
See <Ref Oper="MaximalAntiSymmetricSubdigraph"/>
<Ref Oper="OutNeighbours"/>.
The second list returned contains the basis vectors of the cycle space of the
digraph. These vectors belongs to <M>(GF(2))^m</M> where <M>m</M> is the
length of the list of edges.<P/>
A graph is <E>eulerian</E> if every vertex has an even degree. A <E>cycle
space</E> of a graph is a subspace of <M>(GF(2))^m</M> representing the set
of all <E>eulerian</E> subgraphs without isolated vertices.
An eulerian subgraph without isolated vertices can be uniquely
identified using the edges that is contains. Therefore, given some ordering
on the edges of the graph, a subgraph can be represented by a vector in
<M>(GF(2))^m</M> where the <M>i</M>-th entry is <M>1</M> if the <M>i</M>-th edge
is in the subgraph and <M>0</M> otherwise. In this function, the ordering of the
edges is returned as the first list which corresponds to
<C>OutNeighbours(MaximalAntiSymmetricSubdigraph(G))</C>.
See <Ref Oper="MaximalAntiSymmetricSubdigraph"/>
and <Ref Oper="OutNeighbours"/>.
The first basis vector for the complete digraph with 4 vertices shown below
represents the edges <C>[1, 2]</C>, <C>[1, 3]</C> and <C>[2, 3]</C> i.e. cycle subgraph
between the vertices <C>1</C>, <C>2</C> and <C>3</C>
The cycle space is closed under the symmetric difference of the edges of
the graph. This nicely corresponds to the addition of vectors in
<M>(GF(2))^m</M> which makes the vector space formulation of the cycle
space very natural.<P/>
A <E>cycle basis</E> is a basis of the cycle space.
A <E>fundamental cycle basis</E> is a special
kind of basis of the cycle space where there is a specific spanning tree
(forest, when the graph is disconnected) of the graph and each basis
corresponds to the unique cycle created by adding an edge outside the
spanning tree of the graph to the spanning tree. In this function, the
spanning forest is rooted in the vertex with the smallest label for each
connected component of the graph. <P/>
The fundamental cycle basis is unique up to reordering of the basis vectors.
The number of basis vectors in the fundamental cycle basis is
<M>m - n + c</M>, where <M>m</M> is the number
of edges, <M>n</M> is the number of vertices, and <M>c</M> is the number of
connected components. See <Ref Oper="DigraphConnectedComponents"/>.<P/>
This function performs a depth first traversal of the input digraph with complexity <M>O(m + n)</M> and
the complexity of the computation of the basis is <M>O(m^2)</M> where <M>m</M>
is the number of edges in the input digraph.
<#GAPDoc Label="IsOrderIdeal">
<ManSection>
<Oper Name="IsOrderIdeal" Arg="D, subset" Label="for a digraph and list"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
This function returns <K>true</K> if the specified subset is "downwards"
closed, i.e. contains every vertex less than the given vertices in the
order defined by <A>D</A>. The function can only be used on digraphs
satisfying <Ref Prop="IsPartialOrderDigraph"/> and will throw an error if
passed a digraph that is not a partial order digraph.
<Example><![CDATA[
gap> D1 := Digraph([[1, 3], [2, 3], [3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsOrderIdeal(D1, [1, 2, 3]);
true
gap> D2 := DigraphDisjointUnion(D1, D1);
<immutable digraph with 6 vertices, 10 edges>
gap> IsOrderIdeal(D2, [1, 2, 3]);
true
gap> IsOrderIdeal(D2, [4, 5, 6]);
true
gap> IsOrderIdeal(D2, [1, 5, 6]);
false
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="IsOrderFilter">
<ManSection>
<Oper Name="IsOrderFilter" Arg="D, subset" Label="for a digraph and a list"/>
<Returns> <K>true</K> or <K>false</K>.</Returns>
<Description>
This function returns <K>true</K> if the specified subset is upwards
closed. A subset is upwards closed if it contains every vertex greater than the given vertices in the
order defined by <A>D</A>. The function can only be used on digraphs
satisfying <Ref Prop="IsPartialOrderDigraph"/> and will throw an error if
passed a digraph that is not a partial order digraph.
<Example><![CDATA[gap> D1 := DigraphByEdges(
> [[1, 2], [2, 3], [1, 3], [1, 1], [2, 2], [3, 3]]);
<immutable digraph with 3 vertices, 6 edges>
gap> IsOrderFilter(D1, [2, 3]);
false
gap> IsOrderFilter(D1, [1, 2]);
true]]>
</Example>
</Description>
</ManSection>
<#/GAPDoc>
<#GAPDoc Label="DIGRAPHS_FREE_HOMOS_DATA">
<Oper Name="DIGRAPHS_FREE_HOMOS_DATA"/>
<Returns> This function does not return a value. </Returns>
<Description>
Releases the memory used by the internal data structures for homomorphism
finding. This will not have any noticeable impact on your &GAP; session, but
will reduce memory usage of &Digraphs;. After <C>DIGRAPHS_FREE_HOMOS_DATA</C>
is called, any subsequent calls to <Ref Func="HomomorphismDigraphsFinder"/>
will have to reallocate memory for the internal data structures used by the
homomorphism finding code in the kernel extension, and, depending on the
amount of memory required, there might be a one-off time penalty for doing
this.
</Description>
<Example><![CDATA[
gap> DIGRAPHS_FREE_HOMOS_DATA();
]]></Example>
<#/GAPDoc>
<#GAPDoc Label="DIGRAPHS_FREE_CLIQUES_DATA">
<Oper Name="DIGRAPHS_FREE_CLIQUES_DATA"/>
<Returns> This function does not return a value. </Returns>
<Description>
Releases the memory used by the internal data structures for clique
finding. This will not have any noticeable impact on your &GAP; session, but
will reduce memory usage of &Digraphs;. After <C>DIGRAPHS_FREE_CLIQUES_DATA</C>
is called, any subsequent calls to <Ref Func="DigraphsCliquesFinder"/>
will have to reallocate memory for the internal data structures used by the
clique finding code in the kernel extension, and, depending on the
amount of memory required, there might be a one-off time penalty for doing
this.
</Description>
<Example><![CDATA[
gap> DIGRAPHS_FREE_CLIQUES_DATA();
]]></Example>
<#/GAPDoc>
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.47 Sekunden
(vorverarbeitet am 2026-04-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.