algograph/graph/
trait.rs

1use crate::graph::*;
2
3/// A trait for low-level growable graphs.
4pub trait GrowableGraph {
5    /// Generate a new and empty graph.
6    fn new() -> Self;
7    /// Add a new vertex into the graph.
8    fn add_vertex(&mut self) -> VertexId;
9    /// Add a new edge from `source` to `sink` for directed graphs or between them for undirected graphs.
10    fn add_edge(&mut self, source: VertexId, sink: VertexId) -> EdgeId;
11}
12
13/// A trait for low-level graphs whose edges can be removed.
14pub trait EdgeShrinkableGraph {
15    /// Remove an edge from the graph.
16    ///
17    /// If the edge ID is not in the graph, `None` is returned;
18    /// otherwise, it returns complete information about the edge.
19    fn remove_edge(&mut self, edge: &EdgeId) -> Option<Edge>;
20}
21
22/// A trait for low-level graphs whose vertices can be removed.
23pub trait VertexShrinkableGraph: EdgeShrinkableGraph {
24    /// Removes a vertex from the graph and all edges connected to this vertex.
25    ///
26    /// It returns an iterator over all edges connected to the vertex.
27    /// Each edge will occur exactly once during the iteration.
28    /// Thus, self-loops will occur once as well.
29    ///
30    /// * For undirected graphs, the removed vertex can be either the sources or the sinks of returned edges.
31    ///   It is implementation-specific.
32    /// * If the vertex is not in the graph, it returns an empty iterator.
33    fn remove_vertex(&mut self, vertex: &VertexId) -> Box<dyn Iterator<Item = Edge> + 'static>;
34}
35
36/// A trait for querying vertices and edges about low-level graphs.
37pub trait QueryableGraph {
38    /// Number of vertices in the graph.
39    fn vertex_size(&self) -> usize;
40    /// Iteration over all vertices in the graph.
41    fn iter_vertices(&self) -> Box<dyn Iterator<Item = VertexId> + '_>;
42    /// Whether a vertex is in the graph or not.
43    fn contains_vertex(&self, v: &VertexId) -> bool;
44
45    /// Number of edges in the graph.
46    fn edge_size(&self) -> usize;
47    /// Iteration over all edges in the graph.
48    fn iter_edges(&self) -> Box<dyn Iterator<Item = Edge> + '_>;
49    /// Whether an edge is in the graph or not.
50    fn contains_edge(&self, e: &EdgeId) -> bool;
51    /// Returns information about a specified edge in the graph.
52    fn find_edge(&self, e: &EdgeId) -> Option<Edge>;
53    /// Iteration over all edges between two vertices in undirected graphs
54    /// or those from `source` to `sink` in directed graphs.
55    fn edges_connecting(
56        &self,
57        source: &VertexId,
58        sink: &VertexId,
59    ) -> Box<dyn Iterator<Item = Edge> + '_>;
60    /// Iteration over all edges going into the vertex `v`.
61    ///
62    /// For undirected graphs, the sinks of returned edges must be `v`.
63    fn in_edges(&self, v: &VertexId) -> Box<dyn Iterator<Item = Edge> + '_>;
64    /// Iteration over all edges going out of `v`.
65    ///
66    /// For undirected graphs, the sources of returned edges must be `v`.
67    fn out_edges(&self, v: &VertexId) -> Box<dyn Iterator<Item = Edge> + '_>;
68
69    /// Returns something can inspect into the graph.
70    fn debug(&self) -> Box<dyn std::fmt::Debug + '_>
71    where
72        Self: Sized,
73    {
74        self.debug_with_indent(0, 2)
75    }
76
77    /// Returns something can inspect into the graph, with customzied indentation.
78    fn debug_with_indent(
79        &self,
80        init_indent: usize,
81        indent_step: usize,
82    ) -> Box<dyn std::fmt::Debug + '_>
83    where
84        Self: Sized,
85    {
86        Box::new(super::graph_debug::GraphDebug::new(
87            self,
88            init_indent,
89            indent_step,
90        ))
91    }
92}
93
94/// Whether a graph is directed or not.
95pub trait DirectedOrNot {
96    /// When the graph is directed, it is true; otherwise, it is false.
97    const DIRECTED_OR_NOT: bool;
98}
99
100/// A trait for subgraphs.
101///
102/// New vertices and edges are disallowed to add into subgraphs.
103/// But those from the underlying graph can be uncovered.
104pub trait Subgraph {
105    type LowerGraph;
106
107    fn new(lower_graph: Self::LowerGraph) -> Self;
108    /// Discloses a vertex.
109    ///
110    /// * Shadowed edges connecting to this vertex will not automatically be disclosed.
111    /// * It takes no effect at all to disclose an already disclosed vertex.
112    fn disclose_vertex(&mut self, v: VertexId) -> &mut Self;
113    /// Discloses an edge, and both endpoints of this edge as well.
114    ///
115    /// * It takes no effect at all to disclose an already disclosed edge.
116    fn disclose_edge(&mut self, v: EdgeId) -> &mut Self;
117}
118
119/// A trait with default implementation for dumping a (directed or not) graph in graphviz format.
120pub trait DumpInGraphviz: QueryableGraph + DirectedOrNot {
121    fn dump_in_graphviz<W>(&self, out: &mut W, graph_name: &str) -> std::io::Result<()>
122    where
123        W: std::io::Write,
124    {
125        if Self::DIRECTED_OR_NOT {
126            writeln!(out, "digraph {} {{", graph_name)?;
127        } else {
128            writeln!(out, "graph {} {{", graph_name)?;
129        }
130        for v in self.iter_vertices() {
131            writeln!(out, "  {} ;", v.0)?;
132        }
133        for e in self.iter_edges() {
134            if Self::DIRECTED_OR_NOT {
135                writeln!(out, "  {} -> {} ;", e.source.0, e.sink.0)?;
136            } else {
137                writeln!(out, "  {} -- {} ;", e.source.0, e.sink.0)?;
138            }
139        }
140        writeln!(out, "}}")?;
141        Ok(())
142    }
143}
144
145impl<G: QueryableGraph + DirectedOrNot> DumpInGraphviz for G {}