rs_graph/
traits.rs

1/*
2 * Copyright (c) 2017-2022 Frank Fischer <frank-fischer@shadow-soft.de>
3 *
4 * This program is free software: you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.  If not, see  <http://www.gnu.org/licenses/>
16 */
17
18//! Traits for graph data structures.
19//!
20//! The traits for graph data structures provide an additional level
21//! of information about (the edges of) the graph. There are three
22//! levels:
23//!
24//! 1. `Graph`: an undirected graph, edges have no defined source or
25//!     sink.
26//! 2. `Digraph`: a directed graph, each edge has a designated source
27//!     and a designated sink node. Furthermore, there is the concept
28//!     of "outgoing" and "incoming" edges. A `Digraph` is also a
29//!     `Graph`, which basically means ignoring the direction
30//!     information of the edges.
31
32use crate::adjacencies::{InEdges, Neighbors, OutEdges};
33use std::rc::Rc;
34
35pub mod refs;
36
37/// A graph iterator.
38///
39/// This is roughly the same interface as a standard iterator. However,
40/// all its method take additionally the graph itself as parameter. This
41/// allows the iterator to not contain a reference to internal graph data.
42///
43/// This might be useful for algorithms that need to store several
44/// iterators because they require less memory (they do not need to store
45/// a reference to the same graph, each!).
46pub trait GraphIterator<G: ?Sized>: Clone {
47    type Item;
48
49    fn next(&mut self, g: &G) -> Option<Self::Item>;
50
51    fn size_hint(&self, _g: &G) -> (usize, Option<usize>) {
52        (0, None)
53    }
54
55    fn count(mut self, g: &G) -> usize {
56        let mut c = 0;
57        while self.next(g).is_some() {
58            c += 1
59        }
60        c
61    }
62
63    fn iter(self, g: &G) -> GraphIter<G, Self>
64    where
65        G: Sized,
66    {
67        GraphIter(self, g)
68    }
69}
70
71/// A graph iterator as a standard iterator.
72///
73/// This is a pair consisting of a graph iterator and a reference the
74/// graph itself. It can be used as a standard iterator.
75pub struct GraphIter<'a, G, I>(pub(crate) I, pub(crate) &'a G);
76
77impl<'a, G, I> Clone for GraphIter<'a, G, I>
78where
79    I: Clone,
80{
81    fn clone(&self) -> Self {
82        GraphIter(self.0.clone(), self.1)
83    }
84}
85
86impl<'a, G, I> Iterator for GraphIter<'a, G, I>
87where
88    I: GraphIterator<G>,
89{
90    type Item = I::Item;
91
92    fn next(&mut self) -> Option<Self::Item> {
93        self.0.next(self.1)
94    }
95
96    fn size_hint(&self) -> (usize, Option<usize>) {
97        self.0.size_hint(self.1)
98    }
99
100    fn count(self) -> usize {
101        self.0.count(self.1)
102    }
103}
104
105/// Base information of a graph.
106pub trait GraphType {
107    /// Type of a node.
108    type Node<'a>: Copy + Eq;
109
110    /// Type of an edge.
111    type Edge<'a>: Copy + Eq;
112}
113
114/// Iterator over all nodes of a graph.
115pub type NodeIterator<'a, G> = GraphIter<'a, G, <G as FiniteGraph>::NodeIt<'a>>;
116
117/// Iterator over all edges of a graph.
118pub type EdgeIterator<'a, G> = GraphIter<'a, G, <G as FiniteGraph>::EdgeIt<'a>>;
119
120/// A (finite) graph with a known number of nodes and edges.
121///
122/// Finite graphs also provide access to the list of all nodes and edges.
123pub trait FiniteGraph: GraphType {
124    /// Type of an iterator over all nodes.
125    type NodeIt<'a>: GraphIterator<Self, Item = Self::Node<'a>>
126    where
127        Self: 'a;
128
129    /// Type of an iterator over all edges.
130    type EdgeIt<'a>: GraphIterator<Self, Item = Self::Edge<'a>>
131    where
132        Self: 'a;
133
134    /// Return the number of nodes in the graph.
135    fn num_nodes(&self) -> usize;
136    /// Return the number of edges in the graph.
137    fn num_edges(&self) -> usize;
138
139    /// Return a graph iterator over all nodes.
140    fn nodes_iter(&self) -> Self::NodeIt<'_>;
141
142    /// Return an iterator over all nodes.
143    fn nodes(&self) -> NodeIterator<'_, Self>
144    where
145        Self: Sized,
146    {
147        GraphIter(self.nodes_iter(), self)
148    }
149
150    /// Return a graph iterator over all edges.
151    ///
152    /// This iterator traverses only the forward edges.
153    fn edges_iter(&self) -> Self::EdgeIt<'_>;
154
155    /// Return an iterator over all edges.
156    ///
157    /// This iterator traverses only the forward edges.
158    fn edges(&self) -> EdgeIterator<Self>
159    where
160        Self: Sized,
161    {
162        GraphIter(self.edges_iter(), self)
163    }
164
165    /// Return the nodes connected by an edge.
166    ///
167    /// The order of the nodes is undefined.
168    fn enodes(&self, e: Self::Edge<'_>) -> (Self::Node<'_>, Self::Node<'_>);
169}
170
171/// A (finite) directed graph with a known number of nodes and edges.
172///
173/// For each edge the source and the sink node may be returned.
174pub trait FiniteDigraph: FiniteGraph {
175    /// Return the source node of an edge.
176    fn src(&self, e: Self::Edge<'_>) -> Self::Node<'_>;
177
178    /// Return the sink node of an edge.
179    fn snk(&self, e: Self::Edge<'_>) -> Self::Node<'_>;
180}
181
182/// Iterator over incident edges and neighbors of some node.
183type NeighIterator<'a, G> = GraphIter<'a, G, <G as Undirected>::NeighIt<'a>>;
184
185/// A graph with list access to undirected incident edges.
186pub trait Undirected: GraphType {
187    /// Type of a graph iterator over all incident edges.
188    type NeighIt<'a>: GraphIterator<Self, Item = (Self::Edge<'a>, Self::Node<'a>)>
189    where
190        Self: 'a;
191
192    /// Return a graph iterator over the edges adjacent to some node.
193    fn neigh_iter(&self, u: Self::Node<'_>) -> Self::NeighIt<'_>;
194
195    /// Return an iterator over the edges adjacent to some node.
196    fn neighs(&self, u: Self::Node<'_>) -> NeighIterator<Self>
197    where
198        Self: Sized,
199    {
200        self.neigh_iter(u).iter(self)
201    }
202
203    /// Return access to the neighbors via an `Adjacencies` trait.
204    ///
205    /// This is the same as calling `Neighbors(&g)` on the graph.
206    fn neighbors(&self) -> Neighbors<Self>
207    where
208        Self: Sized,
209    {
210        Neighbors(self)
211    }
212}
213
214/// A directed edge.
215///
216/// A directed edge is either incoming or outgoing.
217pub trait DirectedEdge {
218    /// The underlying edge.
219    type Edge;
220
221    /// Whether the edge is incoming.
222    fn is_incoming(&self) -> bool;
223
224    /// Whether the edge is outgoing.
225    fn is_outgoing(&self) -> bool {
226        !self.is_incoming()
227    }
228
229    /// The underlying edge.
230    fn edge(&self) -> Self::Edge;
231}
232
233/// Iterator over edges leaving a node.
234type OutIterator<'a, G> = GraphIter<'a, G, <G as Directed>::OutIt<'a>>;
235
236/// Iterator over edges entering a node.
237type InIterator<'a, G> = GraphIter<'a, G, <G as Directed>::InIt<'a>>;
238
239/// Iterator over directed edges incident with a node.
240type IncidentIterator<'a, G> = GraphIter<'a, G, <G as Directed>::IncidentIt<'a>>;
241
242/// A graph with list access to directed incident edges.
243///
244/// Note that each directed graph is also an undirected graph
245/// by simply ignoring the direction of each edge. Hence, each
246/// type implementing `Directed` must also implement `Undirected`.
247///
248/// This trait adds a few additional methods to explicitely access the
249/// direction information of an edge. In particular, the direction
250/// information can be used in the following ways:
251///
252///  - The `src` and `snk` methods return the source and sink nodes of
253///    an edge.
254///  - The iterators `outedges` and `inedges` iterate only over edges
255///    leaving or entering a certain node, respectively.
256pub trait Directed: Undirected {
257    /// Type of a graph iterator over edges leaving a node.
258    type OutIt<'a>: GraphIterator<Self, Item = (Self::Edge<'a>, Self::Node<'a>)>
259    where
260        Self: 'a;
261
262    /// Type of a graph iterator over edges entering a node.
263    type InIt<'a>: GraphIterator<Self, Item = (Self::Edge<'a>, Self::Node<'a>)>
264    where
265        Self: 'a;
266
267    /// Type of an iterator over all incident edges.
268    type IncidentIt<'a>: GraphIterator<Self, Item = (Self::DirectedEdge<'a>, Self::Node<'a>)>
269    where
270        Self: 'a;
271
272    /// Type of a directed edge.
273    type DirectedEdge<'a>: DirectedEdge<Edge = Self::Edge<'a>> + Copy + Eq
274    where
275        Self: 'a;
276
277    /// Return a graph iterator over the edges leaving a node.
278    fn out_iter(&self, u: Self::Node<'_>) -> Self::OutIt<'_>;
279
280    /// Return an iterator over the edges leaving a node.
281    fn outedges(&self, u: Self::Node<'_>) -> OutIterator<Self>
282    where
283        Self: Sized,
284    {
285        GraphIter(self.out_iter(u), self)
286    }
287
288    /// Return access to the outgoing arcs via an `Adjacencies` trait.
289    ///
290    /// This is the same as calling `OutEdges(&g)` on the graph.
291    fn outgoing(&self) -> OutEdges<Self>
292    where
293        Self: Sized,
294    {
295        OutEdges(self)
296    }
297
298    /// Return a graph iterator over the edges leaving a node.
299    fn in_iter(&self, u: Self::Node<'_>) -> Self::InIt<'_>;
300
301    /// Return an iterator over the edges leaving a node.
302    fn inedges(&self, u: Self::Node<'_>) -> InIterator<Self>
303    where
304        Self: Sized,
305    {
306        GraphIter(self.in_iter(u), self)
307    }
308
309    /// Return access to the incoming arcs via an `Adjacencies` trait.
310    ///
311    /// This is the same as calling `InEdges(&g)` on the graph.
312    fn incoming(&self) -> InEdges<Self>
313    where
314        Self: Sized,
315    {
316        InEdges(self)
317    }
318
319    /// Return an iterator over all directed edges incident with a node.
320    fn incident_iter(&self, u: Self::Node<'_>) -> Self::IncidentIt<'_>;
321
322    /// Return an iterator over all directed edges incident with a node.
323    fn incident_edges(&self, u: Self::Node<'_>) -> IncidentIterator<Self>
324    where
325        Self: Sized,
326    {
327        GraphIter(self.incident_iter(u), self)
328    }
329}
330
331/// A trait for general undirected, finite graphs.
332pub trait Graph: FiniteGraph + Undirected {}
333
334impl<G> Graph for G where G: FiniteGraph + Undirected {}
335
336/// A trait for general directed, finite graphs.
337pub trait Digraph: Graph + FiniteDigraph + Directed {}
338
339impl<G> Digraph for G where G: FiniteDigraph + Directed {}
340
341/// An item that has an index.
342pub trait Indexable {
343    fn index(&self) -> usize;
344}
345
346/// Associates nodes and edges with unique ids.
347pub trait IndexGraph: Graph {
348    /// Return a unique id associated with a node.
349    fn node_id(&self, u: Self::Node<'_>) -> usize;
350
351    /// Return the node associated with the given id.
352    ///
353    /// The method panics if the id is invalid.
354    fn id2node(&self, id: usize) -> Self::Node<'_>;
355
356    /// Return a unique id associated with an edge.
357    ///
358    /// The returned id is the same for the edge and its reverse edge.
359    fn edge_id(&self, e: Self::Edge<'_>) -> usize;
360
361    /// Return the edge associated with the given id.
362    ///
363    /// The method returns the forward edge.
364    ///
365    /// The method panics if the id is invalid.
366    fn id2edge(&self, id: usize) -> Self::Edge<'_>;
367}
368
369/// A `Digraph` that is also an `IndexGraph`.
370pub trait IndexDigraph: IndexGraph + Digraph {}
371
372impl<T> IndexDigraph for T where T: IndexGraph + Digraph {}
373
374/// Marker trait for graphs with directly numbered nodes and edges.
375pub trait NumberedGraph: Graph
376where
377    for<'a> <Self as GraphType>::Node<'a>: Indexable,
378    for<'a> <Self as GraphType>::Edge<'a>: Indexable,
379{
380}
381
382impl<G> NumberedGraph for G
383where
384    G: Graph,
385    for<'a> G::Node<'a>: Indexable,
386    for<'a> G::Edge<'a>: Indexable,
387{
388}
389
390/// Marker trait for digraphs with directly numbered nodes and edges.
391pub trait NumberedDigraph: NumberedGraph + Digraph
392where
393    for<'a> <Self as GraphType>::Node<'a>: Indexable,
394    for<'a> <Self as GraphType>::Edge<'a>: Indexable,
395{
396}
397
398impl<G> NumberedDigraph for G
399where
400    G: Digraph + NumberedGraph,
401    for<'a> G::Node<'a>: Indexable,
402    for<'a> G::Edge<'a>: Indexable,
403{
404}
405
406// Implementation of basis traits for refs
407impl<'g, G> GraphType for &'g G
408where
409    G: GraphType,
410{
411    type Node<'a> = G::Node<'a>;
412    type Edge<'a> = G::Edge<'a>;
413}
414
415impl<'g, G> FiniteGraph for &'g G
416where
417    G: FiniteGraph,
418{
419    type NodeIt<'a> = refs::WrapIt<G::NodeIt<'a>>
420    where
421        G: 'a,
422        'g: 'a;
423
424    type EdgeIt<'a> = refs::WrapIt<G::EdgeIt<'a>>
425    where
426        G: 'a,
427        'g: 'a;
428
429    fn num_nodes(&self) -> usize {
430        (*self).num_nodes()
431    }
432
433    fn nodes_iter(&self) -> Self::NodeIt<'_> {
434        (*self).nodes_iter().into()
435    }
436
437    fn num_edges(&self) -> usize {
438        (*self).num_edges()
439    }
440
441    fn edges_iter(&self) -> Self::EdgeIt<'_> {
442        (*self).edges_iter().into()
443    }
444
445    fn enodes(&self, e: Self::Edge<'_>) -> (Self::Node<'_>, Self::Node<'_>) {
446        (*self).enodes(e)
447    }
448}
449
450impl<'g, G> Undirected for &'g G
451where
452    G: Undirected,
453{
454    type NeighIt<'a> = refs::WrapIt<G::NeighIt<'a>>
455    where
456        G: 'a,
457        'g: 'a;
458
459    fn neigh_iter(&self, u: Self::Node<'_>) -> Self::NeighIt<'_> {
460        (*self).neigh_iter(u).into()
461    }
462}
463
464impl<'g, G> Directed for &'g G
465where
466    G: Directed,
467{
468    type OutIt<'a> = refs::WrapIt<G::OutIt<'a>>
469    where
470        G: 'a,
471        'g: 'a;
472
473    type InIt<'a> = refs::WrapIt<G::InIt<'a>>
474    where
475        G: 'a,
476        'g: 'a;
477
478    type IncidentIt<'a> = refs::WrapIt<G::IncidentIt<'a>>
479    where
480        G: 'a,
481        'g: 'a;
482
483    type DirectedEdge<'a> = G::DirectedEdge<'a>
484    where
485        Self: 'a;
486
487    fn out_iter(&self, u: Self::Node<'_>) -> Self::OutIt<'_> {
488        (*self).out_iter(u).into()
489    }
490
491    fn in_iter(&self, u: Self::Node<'_>) -> Self::InIt<'_> {
492        (*self).in_iter(u).into()
493    }
494
495    fn incident_iter(&self, u: Self::Node<'_>) -> Self::IncidentIt<'_> {
496        (*self).incident_iter(u).into()
497    }
498}
499
500impl<'g, G> FiniteDigraph for &'g G
501where
502    G: FiniteDigraph,
503{
504    fn src(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
505        (*self).src(e)
506    }
507
508    fn snk(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
509        (*self).snk(e)
510    }
511}
512
513impl<'g, G> IndexGraph for &'g G
514where
515    G: IndexGraph,
516{
517    fn node_id(&self, u: Self::Node<'_>) -> usize {
518        (*self).node_id(u)
519    }
520
521    fn edge_id(&self, e: Self::Edge<'_>) -> usize {
522        (*self).edge_id(e)
523    }
524
525    fn id2node(&self, id: usize) -> Self::Node<'_> {
526        (*self).id2node(id)
527    }
528
529    fn id2edge(&self, id: usize) -> Self::Edge<'_> {
530        (*self).id2edge(id)
531    }
532}
533
534// Implementation of basis traits for Rc
535impl<G, I> GraphIterator<Rc<G>> for refs::WrapIt<I>
536where
537    I: GraphIterator<G>,
538{
539    type Item = I::Item;
540
541    fn next(&mut self, g: &Rc<G>) -> Option<Self::Item> {
542        self.0.next(g.as_ref())
543    }
544
545    fn size_hint(&self, g: &Rc<G>) -> (usize, Option<usize>) {
546        self.0.size_hint(g.as_ref())
547    }
548
549    fn count(self, g: &Rc<G>) -> usize {
550        self.0.count(g.as_ref())
551    }
552}
553
554impl<G> GraphType for Rc<G>
555where
556    G: GraphType,
557{
558    type Node<'a> = G::Node<'a>;
559    type Edge<'a> = G::Edge<'a>;
560}
561
562impl<G> FiniteGraph for Rc<G>
563where
564    G: FiniteGraph,
565{
566    type NodeIt<'a> = refs::WrapIt<G::NodeIt<'a>>
567    where
568        G: 'a;
569
570    type EdgeIt<'a> = refs::WrapIt<G::EdgeIt<'a>>
571    where
572        G: 'a;
573
574    fn num_nodes(&self) -> usize {
575        self.as_ref().num_nodes()
576    }
577
578    fn nodes_iter(&self) -> Self::NodeIt<'_> {
579        self.as_ref().nodes_iter().into()
580    }
581
582    fn num_edges(&self) -> usize {
583        self.as_ref().num_edges()
584    }
585    fn edges_iter(&self) -> Self::EdgeIt<'_> {
586        self.as_ref().edges_iter().into()
587    }
588
589    fn enodes(&self, e: Self::Edge<'_>) -> (Self::Node<'_>, Self::Node<'_>) {
590        self.as_ref().enodes(e)
591    }
592}
593
594impl<G> FiniteDigraph for Rc<G>
595where
596    G: FiniteDigraph,
597{
598    fn src(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
599        self.as_ref().src(e)
600    }
601
602    fn snk(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
603        self.as_ref().snk(e)
604    }
605}
606
607impl<G> Undirected for Rc<G>
608where
609    G: Undirected,
610{
611    type NeighIt<'a> = refs::WrapIt<G::NeighIt<'a>>
612    where
613        G: 'a;
614
615    fn neigh_iter(&self, u: Self::Node<'_>) -> Self::NeighIt<'_> {
616        self.as_ref().neigh_iter(u).into()
617    }
618}
619
620impl<G> Directed for Rc<G>
621where
622    G: Directed,
623{
624    type OutIt<'a> = refs::WrapIt<G::OutIt<'a>>
625    where
626        G: 'a;
627
628    type InIt<'a> = refs::WrapIt<G::InIt<'a>>
629    where
630        G: 'a;
631
632    type IncidentIt<'a> = refs::WrapIt<G::IncidentIt<'a>>
633    where
634        G: 'a;
635
636    type DirectedEdge<'a> = G::DirectedEdge<'a>
637    where
638        G: 'a;
639
640    fn out_iter(&self, u: Self::Node<'_>) -> Self::OutIt<'_> {
641        self.as_ref().out_iter(u).into()
642    }
643
644    fn in_iter(&self, u: Self::Node<'_>) -> Self::InIt<'_> {
645        self.as_ref().in_iter(u).into()
646    }
647
648    fn incident_iter(&self, u: Self::Node<'_>) -> Self::IncidentIt<'_> {
649        self.as_ref().incident_iter(u).into()
650    }
651}
652
653impl<G> IndexGraph for Rc<G>
654where
655    G: IndexGraph,
656{
657    fn node_id(&self, u: Self::Node<'_>) -> usize {
658        self.as_ref().node_id(u)
659    }
660
661    fn edge_id(&self, e: Self::Edge<'_>) -> usize {
662        self.as_ref().edge_id(e)
663    }
664
665    fn id2node(&self, id: usize) -> Self::Node<'_> {
666        self.as_ref().id2node(id)
667    }
668
669    fn id2edge(&self, id: usize) -> Self::Edge<'_> {
670        self.as_ref().id2edge(id)
671    }
672}