wolf_graph/traits/
visitable_graph.rs1use std::borrow::Cow;
2
3use anyhow::Result;
4
5use crate::{EdgeID, Edges, Elements, NodeID, Nodes};
6
7pub trait VisitableGraph {
8 type GData;
9 type NData: Clone;
10 type EData: Clone;
11
12 fn data(&self) -> &Self::GData;
14 fn node_data(&self, id: impl AsRef<NodeID>) -> Result<Cow<'static, Self::NData>>;
16 fn edge_data(&self, id: impl AsRef<EdgeID>) -> Result<Cow<'static, Self::EData>>;
18
19 fn is_empty(&self) -> bool;
21 fn node_count(&self) -> usize;
23 fn edge_count(&self) -> usize;
25
26 fn all_nodes(&self) -> Nodes;
28 fn all_edges(&self) -> Edges;
30
31 fn elements(&self) -> Elements {
33 Elements::new(self.all_nodes(), self.all_edges())
34 }
35
36 fn has_node(&self, id: impl AsRef<NodeID>) -> bool;
38 fn has_edge(&self, id: impl AsRef<EdgeID>) -> bool;
40 fn has_edge_from_to(&self, source: impl AsRef<NodeID>, target: impl AsRef<NodeID>) -> bool;
42 fn has_edge_between(&self, a: impl AsRef<NodeID>, b: impl AsRef<NodeID>) -> bool;
45
46 fn edges_from_to(&self, source: impl AsRef<NodeID>, target: impl AsRef<NodeID>) -> Result<Edges> {
50 Ok(self.out_edges(source)?
51 .into_iter()
52 .filter(|edge| self.target(edge).map(|id| &id == target.as_ref()).unwrap_or(false))
53 .collect())
54 }
55
56 fn edges_between(&self, a: impl AsRef<NodeID>, b: impl AsRef<NodeID>) -> Result<Edges> {
60 let a = a.as_ref();
61 let b = b.as_ref();
62 let mut edges = self.edges_from_to(a, b)?;
63 edges.extend(self.edges_from_to(b, a)?);
64 Ok(edges)
65 }
66
67 fn edges_from_to_nodes(&self, sources: &Nodes, targets: &Nodes) -> Result<Edges> {
69 let mut edges = Edges::new();
70
71 for source in sources.iter() {
72 for target in targets.iter() {
73 edges.extend(self.edges_from_to(source, target)?);
74 }
75 }
76
77 Ok(edges)
78 }
79
80 fn edges_between_nodes(&self, a: &Nodes, b: &Nodes) -> Result<Edges> {
82 let mut edges = self.edges_from_to_nodes(a, b)?;
83 edges.extend(self.edges_from_to_nodes(b, a)?);
84 Ok(edges)
85 }
86
87 fn source(&self, id: impl AsRef<EdgeID>) -> Result<NodeID>;
89 fn target(&self, id: impl AsRef<EdgeID>) -> Result<NodeID>;
91 fn endpoints(&self, id: impl AsRef<EdgeID>) -> Result<(NodeID, NodeID)>;
93
94 fn out_edges(&self, id: impl AsRef<NodeID>) -> Result<Edges>;
96 fn in_edges(&self, id: impl AsRef<NodeID>) -> Result<Edges>;
98 fn incident_edges(&self, id: impl AsRef<NodeID>) -> Result<Edges>;
100
101 fn out_degree(&self, id: impl AsRef<NodeID>) -> Result<usize>;
103 fn in_degree(&self, id: impl AsRef<NodeID>) -> Result<usize>;
105 fn degree(&self, id: impl AsRef<NodeID>) -> Result<usize>;
107
108 fn successors(&self, id: impl AsRef<NodeID>) -> Result<Nodes>;
110 fn predecessors(&self, id: impl AsRef<NodeID>) -> Result<Nodes>;
112 fn neighbors(&self, id: impl AsRef<NodeID>) -> Result<Nodes>;
114
115 fn has_successors(&self, id: impl AsRef<NodeID>) -> Result<bool>;
117 fn has_predecessors(&self, id: impl AsRef<NodeID>) -> Result<bool>;
119 fn has_neighbors(&self, id: impl AsRef<NodeID>) -> Result<bool>;
121
122 fn nodes_successors(&self, ids: &Nodes) -> Result<Nodes> {
124 let mut result = Nodes::new();
125
126 for id in ids.iter() {
127 let successors = self.successors(id)?;
128 for successor in successors.iter() {
129 result.insert(successor.clone());
130 }
131 }
132
133 Ok(result)
134 }
135
136 fn nodes_predecessors(&self, ids: &Nodes) -> Result<Nodes> {
138 let mut result = Nodes::new();
139
140 for id in ids.iter() {
141 let predecessors = self.predecessors(id)?;
142 for predecessor in predecessors.iter() {
143 result.insert(predecessor.clone());
144 }
145 }
146
147 Ok(result)
148 }
149
150 fn transitive_successors(&self, ids: &Nodes) -> Result<Nodes> {
156 let mut result = Nodes::new();
157
158 let mut ids = ids.clone();
159 while !ids.is_empty() {
160 let next_nodes = self.nodes_successors(&ids)?;
161
162 if next_nodes.is_empty() {
163 break;
164 }
165
166 let mut new_next = false;
167 for node in next_nodes.iter() {
168 if !result.contains(node) {
169 result.insert(node.clone());
170 new_next = true;
171 }
172 }
173
174 if !new_next {
175 break;
176 }
177
178 ids = next_nodes;
179 }
180
181 Ok(result)
182 }
183
184 fn transitive_predecessors(&self, ids: &Nodes) -> Result<Nodes> {
190 let mut result = Nodes::new();
191
192 let mut ids = ids.clone();
193 while !ids.is_empty() {
194 let next_nodes = self.nodes_predecessors(&ids)?;
195
196 if next_nodes.is_empty() {
197 break;
198 }
199
200 let mut new_next = false;
201 for node in next_nodes.iter() {
202 if !result.contains(node) {
203 result.insert(node.clone());
204 new_next = true;
205 }
206 }
207
208 if !new_next {
209 break;
210 }
211
212 ids = next_nodes;
213 }
214
215 Ok(result)
216 }
217
218 fn all_roots(&self) -> Nodes;
220 fn all_leaves(&self) -> Nodes;
222
223 fn non_roots(&self) -> Nodes;
225 fn non_leaves(&self) -> Nodes;
227
228 fn all_internals(&self) -> Nodes;
231
232 fn is_leaf(&self, id: impl AsRef<NodeID>) -> Result<bool>;
234 fn is_root(&self, id: impl AsRef<NodeID>) -> Result<bool>;
236 fn is_internal(&self, id: impl AsRef<NodeID>) -> Result<bool>;
239}