daggy/lib.rs
1//! **daggy** is a directed acyclic graph data structure library.
2//!
3//! The most prominent type is [**Dag**][1] - a wrapper around [petgraph][2]'s [**Graph**][3]
4//! data structure, exposing a refined API targeted towards directed acyclic graph related
5//! functionality.
6//!
7//! The [`Walker`] trait defines a variety of useful methods for traversing any graph type. Its
8//! methods behave similarly to iterator types, however **Walker**s do not require borrowing the
9//! graph. This means that we can still safely mutably borrow from the graph whilst we traverse it.
10//!
11//! [1]: Dag
12//! [2]: petgraph
13//! [3]: petgraph::graph::Graph
14//!
15//!
16//! ## Usage
17//!
18//! Use daggy in your project by adding it to your `Cargo.toml` dependencies:
19//!
20//! ```toml
21//! [dependencies]
22//! daggy = "0.9.0"
23//!
24//! # Enables the `StableDag` type.
25//! daggy = { version = "0.9.0", features = ["stable_dag"] }
26//!
27//! # Allows the `Dag` to be serialized and deserialized.
28//! daggy = { version = "0.9.0", features = ["serde-1"] }
29//! ```
30//!
31//! # Examples
32//!
33//! > Please see the [tests directory][4] for some basic usage examples.
34//!
35//! Transitive reduction:
36//!
37//! ```rust
38//! use daggy::Dag;
39//!
40//! let mut dag = Dag::<&str, &str>::new();
41//!
42//! // Reduce edges:
43//! //
44//! // ```text
45//! // # Before: | # After:
46//! // |
47//! // a -> b ----. | a -> b ----.
48//! // | | | | |
49//! // |-> c ----|----. | '-> c |
50//! // | \ | | | \ |
51//! // | \ v | | \ v
52//! // |------>> d | | '> d
53//! // | \ v | \
54//! // '----------->> e | '> e
55//! // ```
56//!
57//! let a = dag.add_node("a");
58//!
59//! let (_, b) = dag.add_child(a, "a->b", "b");
60//! let (_, c) = dag.add_child(a, "a->c", "c");
61//! let (_, d) = dag.add_child(a, "a->d", "d");
62//! let (_, e) = dag.add_child(a, "a->e", "e");
63//!
64//! dag.add_edge(b, d, "b->d").unwrap();
65//!
66//! dag.add_edge(c, d, "c->d").unwrap();
67//! dag.add_edge(c, e, "c->e").unwrap();
68//!
69//! dag.add_edge(d, e, "d->e").unwrap();
70//!
71//! assert_eq!(dag.edge_count(), 8);
72//!
73//! dag.transitive_reduce(vec![a]);
74//!
75//! let mut edges = dag.graph().edge_weights().copied().collect::<Vec<_>>();
76//! edges.sort();
77//! assert_eq!(dag.edge_count(), 5);
78//! assert_eq!(&edges, &["a->b", "a->c", "b->d", "c->d", "d->e"]);
79//! ```
80//!
81//! [4]: https://github.com/mitchmindtree/daggy/tree/master/tests
82
83#![forbid(unsafe_code)]
84#![warn(missing_docs)]
85
86pub use petgraph;
87use petgraph as pg;
88use petgraph::algo::{has_path_connecting, DfsSpace};
89use petgraph::graph::{DefaultIx, DiGraph, GraphIndex, IndexType};
90use petgraph::visit::{
91 GetAdjacencyMatrix, GraphBase, GraphProp, IntoEdgeReferences, IntoEdges, IntoEdgesDirected,
92 IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers, IntoNodeReferences,
93 NodeCompactIndexable, NodeCount, NodeIndexable, Visitable,
94};
95use petgraph::IntoWeightedEdge;
96use std::marker::PhantomData;
97use std::ops::{Index, IndexMut};
98
99// Petgraph re-exports.
100pub use petgraph::graph::{EdgeIndex, EdgeWeightsMut, NodeIndex, NodeWeightsMut};
101pub use petgraph::visit::Walker;
102
103#[cfg(feature = "serde-1")]
104mod serde;
105#[cfg(feature = "stable_dag")]
106pub mod stable_dag;
107pub mod walker;
108
109/// Read only access into a **Dag**'s internal node array.
110pub type RawNodes<'a, N, Ix> = &'a [pg::graph::Node<N, Ix>];
111/// Read only access into a **Dag**'s internal edge array.
112pub type RawEdges<'a, E, Ix> = &'a [pg::graph::Edge<E, Ix>];
113/// An iterator yielding all edges to/from some node.
114pub type Edges<'a, E, Ix> = pg::graph::Edges<'a, E, pg::Directed, Ix>;
115
116/// A Directed acyclic graph (DAG) data structure.
117///
118/// Dag is a thin wrapper around petgraph's `Graph` data structure, providing a refined API for
119/// dealing specifically with DAGs.
120///
121/// Note: The following documentation is adapted from petgraph's [**Graph** documentation][1]
122///
123/// **Dag** is parameterized over the node weight **N**, edge weight **E** and index type **Ix**.
124///
125/// **NodeIndex** is a type that acts as a reference to nodes, but these are only stable across
126/// certain operations. **Removing nodes may shift other indices.** Adding kids to the **Dag**
127/// keeps all indices stable, but removing a node will force the last node to shift its index to
128/// take its place.
129///
130/// The fact that the node indices in the **Dag** are numbered in a compact interval from 0 to *n*-1
131/// simplifies some graph algorithms.
132///
133/// The **Ix** parameter is u32 by default. The goal is that you can ignore this parameter
134/// completely unless you need a very large **Dag** -- then you can use usize.
135///
136/// The **Dag** also offers methods for accessing the underlying **Graph**, which can be useful
137/// for taking advantage of petgraph's various graph-related algorithms.
138///
139///
140/// [1]: petgraph::graph::Graph
141#[derive(Clone, Debug)]
142pub struct Dag<N, E, Ix: IndexType = DefaultIx> {
143 graph: DiGraph<N, E, Ix>,
144 cycle_state: DfsSpace<NodeIndex<Ix>, <DiGraph<N, E, Ix> as Visitable>::Map>,
145}
146
147/// A **Walker** type that can be used to step through the children of some parent node.
148pub struct Children<N, E, Ix: IndexType> {
149 walk_edges: pg::graph::WalkNeighbors<Ix>,
150 _node: PhantomData<N>,
151 _edge: PhantomData<E>,
152}
153
154/// A **Walker** type that can be used to step through the parents of some child node.
155pub struct Parents<N, E, Ix: IndexType> {
156 walk_edges: pg::graph::WalkNeighbors<Ix>,
157 _node: PhantomData<N>,
158 _edge: PhantomData<E>,
159}
160
161/// An iterator yielding multiple `EdgeIndex`s, returned by the `Graph::add_edges` method.
162pub struct EdgeIndices<Ix: IndexType> {
163 indices: std::ops::Range<usize>,
164 _phantom: PhantomData<Ix>,
165}
166
167/// An alias to simplify the **Recursive** **Walker** type returned by **Dag**.
168pub type RecursiveWalk<N, E, Ix, F> = walker::Recursive<Dag<N, E, Ix>, F>;
169
170/// An error returned by the `Dag::add_edge` method in the case that adding an edge would have
171/// caused the graph to cycle.
172#[derive(Copy, Clone)]
173pub struct WouldCycle<E>(pub E);
174
175impl<N, E, Ix> Dag<N, E, Ix>
176where
177 Ix: IndexType,
178{
179 /// Create a new, empty `Dag`.
180 pub fn new() -> Self {
181 Self::with_capacity(1, 1)
182 }
183
184 /// Create a new `Dag` with estimated capacity for its node and edge Vecs.
185 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
186 Dag {
187 graph: DiGraph::with_capacity(nodes, edges),
188 cycle_state: DfsSpace::default(),
189 }
190 }
191
192 /// Create a `Dag` from an iterator yielding edges.
193 ///
194 /// Node weights `N` are set to default values.
195 ///
196 /// `Edge` weights `E` may either be specified in the list, or they are filled with default
197 /// values.
198 ///
199 /// Nodes are inserted automatically to match the edges.
200 ///
201 /// Returns an `Err` if adding any of the edges would cause a cycle.
202 pub fn from_edges<I>(edges: I) -> Result<Self, WouldCycle<E>>
203 where
204 I: IntoIterator,
205 I::Item: IntoWeightedEdge<E>,
206 <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
207 N: Default,
208 {
209 let mut dag = Self::default();
210 dag.extend_with_edges(edges)?;
211 Ok(dag)
212 }
213
214 /// Extend the `Dag` with the given edges.
215 ///
216 /// Node weights `N` are set to default values.
217 ///
218 /// Edge weights `E` may either be specified in the list, or they are filled with default
219 /// values.
220 ///
221 /// Nodes are inserted automatically to match the edges.
222 ///
223 /// Returns an `Err` if adding an edge would cause a cycle.
224 pub fn extend_with_edges<I>(&mut self, edges: I) -> Result<(), WouldCycle<E>>
225 where
226 I: IntoIterator,
227 I::Item: IntoWeightedEdge<E>,
228 <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
229 N: Default,
230 {
231 for edge in edges {
232 let (source, target, weight) = edge.into_weighted_edge();
233 let (source, target) = (source.into(), target.into());
234 let nx = std::cmp::max(source, target);
235 while nx.index() >= self.node_count() {
236 self.add_node(N::default());
237 }
238 self.add_edge(source, target, weight)?;
239 }
240 Ok(())
241 }
242
243 /// Create a `Dag` from an iterator yielding elements.
244 ///
245 /// Returns an `Err` if an edge would cause a cycle within the graph.
246 pub fn from_elements<I>(elements: I) -> Result<Self, WouldCycle<E>>
247 where
248 Self: Sized,
249 I: IntoIterator<Item = pg::data::Element<N, E>>,
250 {
251 let mut dag = Self::default();
252 for elem in elements {
253 match elem {
254 pg::data::Element::Node { weight } => {
255 dag.add_node(weight);
256 }
257 pg::data::Element::Edge {
258 source,
259 target,
260 weight,
261 } => {
262 let n = NodeIndex::new(source);
263 let e = NodeIndex::new(target);
264 dag.update_edge(n, e, weight)?;
265 }
266 }
267 }
268 Ok(dag)
269 }
270
271 /// Create a new `Graph` by mapping node and edge weights to new values.
272 ///
273 /// The resulting graph has the same structure and the same graph indices as `self`.
274 pub fn map<'a, F, G, N2, E2>(&'a self, node_map: F, edge_map: G) -> Dag<N2, E2, Ix>
275 where
276 F: FnMut(NodeIndex<Ix>, &'a N) -> N2,
277 G: FnMut(EdgeIndex<Ix>, &'a E) -> E2,
278 {
279 let graph = self.graph.map(node_map, edge_map);
280 let cycle_state = self.cycle_state.clone();
281 Dag { graph, cycle_state }
282 }
283
284 /// Create a new `Dag` by mapping node and edge weights. A node or edge may be mapped to `None`
285 /// to exclude it from the resulting `Dag`.
286 ///
287 /// Nodes are mapped first with the `node_map` closure, then `edge_map` is called for the edges
288 /// that have not had any endpoint removed.
289 ///
290 /// The resulting graph has the structure of a subgraph of the original graph. If no nodes are
291 /// removed, the resulting graph has compatible node indices.
292 ///
293 /// If neither nodes nor edges are removed, the resulting graph has compatible node indices. If
294 /// neither nodes nor edges are removed the result has the same graph indices as `self`.
295 ///
296 /// The resulting graph has the same structure and the same graph indices as `self`.
297 pub fn filter_map<'a, F, G, N2, E2>(&'a self, node_map: F, edge_map: G) -> Dag<N2, E2, Ix>
298 where
299 F: FnMut(NodeIndex<Ix>, &'a N) -> Option<N2>,
300 G: FnMut(EdgeIndex<Ix>, &'a E) -> Option<E2>,
301 {
302 let graph = self.graph.filter_map(node_map, edge_map);
303 let cycle_state = DfsSpace::new(&graph);
304 Dag { graph, cycle_state }
305 }
306
307 /// Removes all nodes and edges from the **Dag**.
308 pub fn clear(&mut self) {
309 self.graph.clear();
310 }
311
312 /// The total number of nodes in the **Dag**.
313 pub fn node_count(&self) -> usize {
314 self.graph.node_count()
315 }
316
317 /// The total number of edges in the **Dag**.
318 pub fn edge_count(&self) -> usize {
319 self.graph.edge_count()
320 }
321
322 /// Reserves capacity for at least `additional` more nodes to be inserted in
323 /// the graph. Graph may reserve more space to avoid frequent reallocations.
324 ///
325 /// **Panics** if the new capacity overflows `usize`.
326 pub fn reserve_nodes(&mut self, additional: usize) {
327 self.graph.reserve_nodes(additional)
328 }
329
330 /// Reserves the minimum capacity for exactly `additional` more nodes to be
331 /// inserted in the graph. Does nothing if the capacity is already
332 /// sufficient.
333 ///
334 /// Prefer `reserve_nodes` if future insertions are expected.
335 ///
336 /// **Panics** if the new capacity overflows `usize`.
337 pub fn reserve_exact_nodes(&mut self, additional: usize) {
338 self.graph.reserve_exact_nodes(additional)
339 }
340
341 /// Reserves capacity for at least `additional` more edges to be inserted in
342 /// the graph. Graph may reserve more space to avoid frequent reallocations.
343 ///
344 /// **Panics** if the new capacity overflows `usize`.
345 pub fn reserve_edges(&mut self, additional: usize) {
346 self.graph.reserve_edges(additional)
347 }
348
349 /// Reserves the minimum capacity for exactly `additional` more edges to be
350 /// inserted in the graph.
351 /// Does nothing if the capacity is already sufficient.
352 ///
353 /// Prefer `reserve_edges` if future insertions are expected.
354 ///
355 /// **Panics** if the new capacity overflows `usize`.
356 pub fn reserve_exact_edges(&mut self, additional: usize) {
357 self.graph.reserve_exact_edges(additional)
358 }
359
360 /// Shrinks the capacity of the graph as much as possible.
361 pub fn shrink_to_fit(&mut self) {
362 self.graph.shrink_to_fit();
363 }
364
365 /// Shrinks the capacity of the underlying nodes collection as much as possible.
366 pub fn shrink_to_fit_nodes(&mut self) {
367 self.graph.shrink_to_fit_nodes();
368 }
369
370 /// Shrinks the capacity of the underlying edges collection as much as possible.
371 pub fn shrink_to_fit_edges(&mut self) {
372 self.graph.shrink_to_fit_edges();
373 }
374
375 /// Borrow the `Dag`'s underlying `DiGraph<N, Ix>`.
376 ///
377 /// All existing indices may be used to index into this `DiGraph` the same way they may be
378 /// used to index into the `Dag`.
379 pub fn graph(&self) -> &DiGraph<N, E, Ix> {
380 &self.graph
381 }
382
383 /// Take ownership of the `Dag` and return the internal `DiGraph`.
384 ///
385 /// All existing indices may be used to index into this `DiGraph` the same way they may be
386 /// used to index into the `Dag`.
387 pub fn into_graph(self) -> DiGraph<N, E, Ix> {
388 let Dag { graph, .. } = self;
389 graph
390 }
391
392 /// Add a new node to the `Dag` with the given weight.
393 ///
394 /// Computes in **O(1)** time.
395 ///
396 /// Returns the index of the new node.
397 ///
398 /// **Note:** If you're adding a new node and immediately adding a single edge to that node from
399 /// some other node, consider using the [add_child](Dag::add_child) or
400 /// [add_parent](Dag::add_parent) methods instead for better performance.
401 ///
402 /// **Panics** if the Graph is at the maximum number of nodes for its index type.
403 pub fn add_node(&mut self, weight: N) -> NodeIndex<Ix> {
404 self.graph.add_node(weight)
405 }
406
407 /// Add a new directed edge to the `Dag` with the given weight.
408 ///
409 /// The added edge will be in the direction `a` -> `b`
410 ///
411 /// Checks if the edge would create a cycle in the Graph.
412 ///
413 /// If adding the edge **would not** cause the graph to cycle, the edge will be added and its
414 /// `EdgeIndex` returned.
415 ///
416 /// If adding the edge **would** cause the graph to cycle, the edge will not be added and
417 /// instead a `WouldCycle<E>` error with the given weight will be returned.
418 ///
419 /// In the worst case, petgraph's [`is_cyclic_directed`][1]
420 /// function is used to check whether or not adding the edge would create a cycle.
421 ///
422 /// **Note:** Dag allows adding parallel ("duplicate") edges. If you want to avoid this, use
423 /// [`update_edge`][2] instead.
424 ///
425 /// **Note:** If you're adding a new node and immediately adding a single edge to that node from
426 /// some other node, consider using the [add_child][3] or
427 /// [add_parent][4] methods instead for better performance.
428 ///
429 /// **Panics** if either `a` or `b` do not exist within the **Dag**.
430 ///
431 /// **Panics** if the Graph is at the maximum number of edges for its index type.
432 ///
433 ///
434 /// [1]: petgraph::algo::is_cyclic_directed
435 /// [2]: Dag::update_edge
436 /// [3]: Dag::add_child
437 /// [4]: Dag::add_parent
438 pub fn add_edge(
439 &mut self,
440 a: NodeIndex<Ix>,
441 b: NodeIndex<Ix>,
442 weight: E,
443 ) -> Result<EdgeIndex<Ix>, WouldCycle<E>> {
444 let should_check_for_cycle = must_check_for_cycle(self, a, b);
445 let state = Some(&mut self.cycle_state);
446 if should_check_for_cycle && has_path_connecting(&self.graph, b, a, state) {
447 return Err(WouldCycle(weight));
448 }
449
450 Ok(self.graph.add_edge(a, b, weight))
451 }
452
453 /// Adds the given directed edges to the `Dag`, each with their own given weight.
454 ///
455 /// The given iterator should yield a `NodeIndex` pair along with a weight for each Edge to be
456 /// added in a tuple.
457 ///
458 /// If we were to describe the tuple as *(a, b, weight)*, the connection would be directed as
459 /// follows:
460 ///
461 /// *a -> b*
462 ///
463 /// This method behaves similarly to the [`add_edge`][1]
464 /// method, however rather than checking whether or not a cycle has been created after adding
465 /// each edge, it only checks after all edges have been added. This makes it a slightly more
466 /// performant and ergonomic option that repeatedly calling `add_edge`.
467 ///
468 /// If adding the edges **would not** cause the graph to cycle, the edges will be added and
469 /// their indices returned in an `EdgeIndices` iterator, yielding indices for each edge in the
470 /// same order that they were given.
471 ///
472 /// If adding the edges **would** cause the graph to cycle, the edges will not be added and
473 /// instead a `WouldCycle<Vec<E>>` error with the unused weights will be returned. The order of
474 /// the returned `Vec` will be the reverse of the given order.
475 ///
476 /// **Note:** Dag allows adding parallel ("duplicate") edges. If you want to avoid this, use
477 /// [`update_edge`][2] instead.
478 ///
479 /// **Note:** If you're adding a series of new nodes and edges to a single node, consider using
480 /// the [add_child][3] or [add_parent][4] methods instead for greater convenience.
481 ///
482 /// **Panics** if the Graph is at the maximum number of nodes for its index type.
483 ///
484 ///
485 /// [1]: Dag::add_edge
486 /// [2]: Dag::update_edge
487 /// [3]: Dag::add_child
488 /// [4]: Dag::add_parent
489 pub fn add_edges<I>(&mut self, edges: I) -> Result<EdgeIndices<Ix>, WouldCycle<Vec<E>>>
490 where
491 I: IntoIterator<Item = (NodeIndex<Ix>, NodeIndex<Ix>, E)>,
492 {
493 let mut num_edges = 0;
494 let mut should_check_for_cycle = false;
495
496 for (a, b, weight) in edges {
497 // Check whether or not we'll need to check for cycles.
498 if !should_check_for_cycle && must_check_for_cycle(self, a, b) {
499 should_check_for_cycle = true;
500 }
501
502 self.graph.add_edge(a, b, weight);
503 num_edges += 1;
504 }
505
506 let total_edges = self.edge_count();
507 let new_edges_range = total_edges - num_edges..total_edges;
508
509 // Check if adding the edges has created a cycle.
510 if should_check_for_cycle && pg::algo::is_cyclic_directed(&self.graph) {
511 let removed_edges = new_edges_range.rev().filter_map(|i| {
512 let idx = EdgeIndex::new(i);
513 self.graph.remove_edge(idx)
514 });
515 Err(WouldCycle(removed_edges.collect()))
516 } else {
517 Ok(EdgeIndices {
518 indices: new_edges_range,
519 _phantom: std::marker::PhantomData,
520 })
521 }
522 }
523
524 /// Update the edge from nodes `a` -> `b` with the given weight.
525 ///
526 /// If the edge doesn't already exist, it will be added using the `add_edge` method.
527 ///
528 /// Please read the [`add_edge`](Dag::add_edge) method documentation for more important details.
529 ///
530 /// Checks if the edge would create a cycle in the Graph.
531 ///
532 /// Computes in **O(t + e)** time where "t" is the complexity of `add_edge` and e is the number
533 /// of edges connected to the nodes a and b.
534 ///
535 /// Returns the index of the edge, or a `WouldCycle` error if adding the edge would create a
536 /// cycle.
537 ///
538 /// **Note:** If you're adding a new node and immediately adding a single edge to that node from
539 /// some parent node, consider using the [`add_child`](Dag::add_child)
540 /// method instead for greater convenience.
541 ///
542 /// **Panics** if the Graph is at the maximum number of nodes for its index type.
543 pub fn update_edge(
544 &mut self,
545 a: NodeIndex<Ix>,
546 b: NodeIndex<Ix>,
547 weight: E,
548 ) -> Result<EdgeIndex<Ix>, WouldCycle<E>> {
549 if let Some(edge_idx) = self.find_edge(a, b) {
550 if let Some(edge) = self.edge_weight_mut(edge_idx) {
551 *edge = weight;
552 return Ok(edge_idx);
553 }
554 }
555 self.add_edge(a, b, weight)
556 }
557
558 /// Find and return the index to the edge that describes `a` -> `b` if there is one.
559 ///
560 /// Computes in **O(e')** time, where **e'** is the number of edges connected to the nodes `a`
561 /// and `b`.
562 pub fn find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>> {
563 self.graph.find_edge(a, b)
564 }
565
566 /// Access the parent and child nodes for the given `EdgeIndex`.
567 pub fn edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)> {
568 self.graph.edge_endpoints(e)
569 }
570
571 /// Remove all edges.
572 pub fn clear_edges(&mut self) {
573 self.graph.clear_edges()
574 }
575
576 /// Add a new edge and parent node to the node at the given `NodeIndex`.
577 ///
578 /// Returns both the edge's `EdgeIndex` and the node's `NodeIndex`.
579 ///
580 /// node -> edge -> child
581 ///
582 /// Computes in **O(1)** time.
583 ///
584 /// This is faster than using `add_node` and `add_edge`. This is because we don't have to check
585 /// if the graph would cycle when adding an edge to the new node, as we know it it will be the
586 /// only edge connected to that node.
587 ///
588 /// **Panics** if the given child node doesn't exist.
589 ///
590 /// **Panics** if the Graph is at the maximum number of edges for its index.
591 pub fn add_parent(
592 &mut self,
593 child: NodeIndex<Ix>,
594 edge: E,
595 node: N,
596 ) -> (EdgeIndex<Ix>, NodeIndex<Ix>) {
597 let parent_node = self.graph.add_node(node);
598 let parent_edge = self.graph.add_edge(parent_node, child, edge);
599 (parent_edge, parent_node)
600 }
601
602 /// Add a new edge and child node to the node at the given `NodeIndex`.
603 /// Returns both the edge's `EdgeIndex` and the node's `NodeIndex`.
604 ///
605 /// child -> edge -> node
606 ///
607 /// Computes in **O(1)** time.
608 ///
609 /// This is faster than using `add_node` and `add_edge`. This is because we don't have to check
610 /// if the graph would cycle when adding an edge to the new node, as we know it it will be the
611 /// only edge connected to that node.
612 ///
613 /// **Panics** if the given parent node doesn't exist.
614 ///
615 /// **Panics** if the Graph is at the maximum number of edges for its index.
616 pub fn add_child(
617 &mut self,
618 parent: NodeIndex<Ix>,
619 edge: E,
620 node: N,
621 ) -> (EdgeIndex<Ix>, NodeIndex<Ix>) {
622 let child_node = self.graph.add_node(node);
623 let child_edge = self.graph.add_edge(parent, child_node, edge);
624 (child_edge, child_node)
625 }
626
627 /// Borrow the weight from the node at the given index.
628 pub fn node_weight(&self, node: NodeIndex<Ix>) -> Option<&N> {
629 self.graph.node_weight(node)
630 }
631
632 /// Mutably borrow the weight from the node at the given index.
633 pub fn node_weight_mut(&mut self, node: NodeIndex<Ix>) -> Option<&mut N> {
634 self.graph.node_weight_mut(node)
635 }
636
637 /// Read from the internal node array.
638 pub fn raw_nodes(&self) -> RawNodes<N, Ix> {
639 self.graph.raw_nodes()
640 }
641
642 /// An iterator yielding mutable access to all node weights.
643 ///
644 /// The order in which weights are yielded matches the order of their node indices.
645 pub fn node_weights_mut(&mut self) -> NodeWeightsMut<N, Ix> {
646 self.graph.node_weights_mut()
647 }
648
649 /// Borrow the weight from the edge at the given index.
650 pub fn edge_weight(&self, edge: EdgeIndex<Ix>) -> Option<&E> {
651 self.graph.edge_weight(edge)
652 }
653
654 /// Mutably borrow the weight from the edge at the given index.
655 pub fn edge_weight_mut(&mut self, edge: EdgeIndex<Ix>) -> Option<&mut E> {
656 self.graph.edge_weight_mut(edge)
657 }
658
659 /// Read from the internal edge array.
660 pub fn raw_edges(&self) -> RawEdges<E, Ix> {
661 self.graph.raw_edges()
662 }
663
664 /// An iterator yielding mutable access to all edge weights.
665 ///
666 /// The order in which weights are yielded matches the order of their edge indices.
667 pub fn edge_weights_mut(&mut self) -> EdgeWeightsMut<E, Ix> {
668 self.graph.edge_weights_mut()
669 }
670
671 /// Index the `Dag` by two indices.
672 ///
673 /// Both indices can be either `NodeIndex`s, `EdgeIndex`s or a combination of the two.
674 ///
675 /// **Panics** if the indices are equal or if they are out of bounds.
676 #[allow(clippy::type_complexity)]
677 pub fn index_twice_mut<A, B>(
678 &mut self,
679 a: A,
680 b: B,
681 ) -> (
682 &mut <DiGraph<N, E, Ix> as Index<A>>::Output,
683 &mut <DiGraph<N, E, Ix> as Index<B>>::Output,
684 )
685 where
686 DiGraph<N, E, Ix>: IndexMut<A> + IndexMut<B>,
687 A: GraphIndex,
688 B: GraphIndex,
689 {
690 self.graph.index_twice_mut(a, b)
691 }
692
693 /// Remove the node at the given index from the `Dag` and return it if it exists.
694 ///
695 /// Note: Calling this may shift (and in turn invalidate) previously returned node indices!
696 pub fn remove_node(&mut self, node: NodeIndex<Ix>) -> Option<N> {
697 self.graph.remove_node(node)
698 }
699
700 /// Remove an edge and return its weight, or `None` if it didn't exist.
701 ///
702 /// Computes in **O(e')** time, where **e'** is the size of four particular edge lists, for the
703 /// nodes of **e** and the nodes of another affected edge.
704 pub fn remove_edge(&mut self, e: EdgeIndex<Ix>) -> Option<E> {
705 self.graph.remove_edge(e)
706 }
707
708 /// A **Walker** type that may be used to step through the parents of the given child node.
709 ///
710 /// Unlike iterator types, **Walker**s do not require borrowing the internal **Graph**. This
711 /// makes them useful for traversing the **Graph** while still being able to mutably borrow it.
712 ///
713 /// If you require an iterator, use one of the **Walker** methods for converting this
714 /// **Walker** into a similarly behaving **Iterator** type.
715 ///
716 /// See the [**Walker**](Walker) trait for more useful methods.
717 pub fn parents(&self, child: NodeIndex<Ix>) -> Parents<N, E, Ix> {
718 let walk_edges = self.graph.neighbors_directed(child, pg::Incoming).detach();
719 Parents {
720 walk_edges,
721 _node: PhantomData,
722 _edge: PhantomData,
723 }
724 }
725
726 /// A "walker" object that may be used to step through the children of the given parent node.
727 ///
728 /// Unlike iterator types, **Walker**s do not require borrowing the internal **Graph**. This
729 /// makes them useful for traversing the **Graph** while still being able to mutably borrow it.
730 ///
731 /// If you require an iterator, use one of the **Walker** methods for converting this
732 /// **Walker** into a similarly behaving **Iterator** type.
733 ///
734 /// See the [**Walker**](Walker) trait for more useful methods.
735 pub fn children(&self, parent: NodeIndex<Ix>) -> Children<N, E, Ix> {
736 let walk_edges = self.graph.neighbors_directed(parent, pg::Outgoing).detach();
737 Children {
738 walk_edges,
739 _node: PhantomData,
740 _edge: PhantomData,
741 }
742 }
743
744 /// A **Walker** type that recursively walks the **Dag** using the given `recursive_fn`.
745 ///
746 /// See the [**Walker**](Walker) trait for more useful methods.
747 pub fn recursive_walk<F>(
748 &self,
749 start: NodeIndex<Ix>,
750 recursive_fn: F,
751 ) -> RecursiveWalk<N, E, Ix, F>
752 where
753 F: FnMut(&Self, NodeIndex<Ix>) -> Option<(EdgeIndex<Ix>, NodeIndex<Ix>)>,
754 {
755 walker::Recursive::new(start, recursive_fn)
756 }
757
758 fn transitive_reduce_iter(
759 &mut self,
760 curr_node: NodeIndex<Ix>,
761 ancestors: &mut Vec<NodeIndex<Ix>>,
762 ) {
763 let mut redundant_edges = Vec::new();
764 for (_, child) in self.children(curr_node).iter(self) {
765 for (edge, coparent) in self.parents(child).iter(self) {
766 if ancestors.contains(&coparent) {
767 redundant_edges.push(edge);
768 }
769 }
770 }
771 for edge in redundant_edges {
772 self.remove_edge(edge);
773 }
774
775 ancestors.push(curr_node);
776
777 let mut children = self.children(curr_node);
778 while let Some((_, child)) = children.walk_next(self) {
779 self.transitive_reduce_iter(child, ancestors)
780 }
781
782 ancestors.pop();
783 }
784
785 /// Mutates the DAG into its [transitive reduction](https://en.wikipedia.org/wiki/Directed_acyclic_graph#Transitive_closure_and_transitive_reduction)
786 pub fn transitive_reduce(&mut self, roots: Vec<NodeIndex<Ix>>) {
787 for root in roots {
788 self.transitive_reduce_iter(root, &mut Vec::new())
789 }
790 }
791}
792
793/// After adding a new edge to the graph, we use this function immediately after to check whether
794/// or not we need to check for a cycle.
795///
796/// If our parent *a* has no parents or our child *b* has no children, or if there was already an
797/// edge connecting *a* to *b*, we know that adding this edge has not caused the graph to cycle.
798fn must_check_for_cycle<N, E, Ix>(dag: &Dag<N, E, Ix>, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool
799where
800 Ix: IndexType,
801{
802 if a == b {
803 return true;
804 }
805 dag.parents(a).walk_next(dag).is_some()
806 && dag.children(b).walk_next(dag).is_some()
807 && dag.find_edge(a, b).is_none()
808}
809
810// Dag implementations.
811
812impl<N, E, Ix> From<Dag<N, E, Ix>> for DiGraph<N, E, Ix>
813where
814 Ix: IndexType,
815{
816 fn from(val: Dag<N, E, Ix>) -> Self {
817 val.into_graph()
818 }
819}
820
821impl<N, E, Ix> Default for Dag<N, E, Ix>
822where
823 Ix: IndexType,
824{
825 fn default() -> Self {
826 Dag::new()
827 }
828}
829
830impl<N, E, Ix> GraphBase for Dag<N, E, Ix>
831where
832 Ix: IndexType,
833{
834 type NodeId = NodeIndex<Ix>;
835 type EdgeId = EdgeIndex<Ix>;
836}
837
838impl<N, E, Ix> NodeCount for Dag<N, E, Ix>
839where
840 Ix: IndexType,
841{
842 fn node_count(&self) -> usize {
843 Dag::node_count(self)
844 }
845}
846
847impl<N, E, Ix> GraphProp for Dag<N, E, Ix>
848where
849 Ix: IndexType,
850{
851 type EdgeType = pg::Directed;
852 fn is_directed(&self) -> bool {
853 true
854 }
855}
856
857impl<N, E, Ix> pg::visit::Visitable for Dag<N, E, Ix>
858where
859 Ix: IndexType,
860{
861 type Map = <DiGraph<N, E, Ix> as Visitable>::Map;
862 fn visit_map(&self) -> Self::Map {
863 self.graph.visit_map()
864 }
865 fn reset_map(&self, map: &mut Self::Map) {
866 self.graph.reset_map(map)
867 }
868}
869
870impl<N, E, Ix> pg::visit::Data for Dag<N, E, Ix>
871where
872 Ix: IndexType,
873{
874 type NodeWeight = N;
875 type EdgeWeight = E;
876}
877
878impl<N, E, Ix> pg::data::DataMap for Dag<N, E, Ix>
879where
880 Ix: IndexType,
881{
882 fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
883 self.graph.node_weight(id)
884 }
885 fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
886 self.graph.edge_weight(id)
887 }
888}
889
890impl<N, E, Ix> pg::data::DataMapMut for Dag<N, E, Ix>
891where
892 Ix: IndexType,
893{
894 fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
895 self.graph.node_weight_mut(id)
896 }
897 fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
898 self.graph.edge_weight_mut(id)
899 }
900}
901
902impl<'a, N, E, Ix> IntoNeighbors for &'a Dag<N, E, Ix>
903where
904 Ix: IndexType,
905{
906 type Neighbors = pg::graph::Neighbors<'a, E, Ix>;
907 fn neighbors(self, n: NodeIndex<Ix>) -> Self::Neighbors {
908 self.graph.neighbors(n)
909 }
910}
911
912impl<'a, N, E, Ix> IntoNeighborsDirected for &'a Dag<N, E, Ix>
913where
914 Ix: IndexType,
915{
916 type NeighborsDirected = pg::graph::Neighbors<'a, E, Ix>;
917 fn neighbors_directed(self, n: NodeIndex<Ix>, d: pg::Direction) -> Self::Neighbors {
918 self.graph.neighbors_directed(n, d)
919 }
920}
921
922impl<'a, N, E, Ix> IntoEdgeReferences for &'a Dag<N, E, Ix>
923where
924 Ix: IndexType,
925{
926 type EdgeRef = pg::graph::EdgeReference<'a, E, Ix>;
927 type EdgeReferences = pg::graph::EdgeReferences<'a, E, Ix>;
928 fn edge_references(self) -> Self::EdgeReferences {
929 self.graph.edge_references()
930 }
931}
932
933impl<'a, N, E, Ix> IntoEdges for &'a Dag<N, E, Ix>
934where
935 Ix: IndexType,
936{
937 type Edges = Edges<'a, E, Ix>;
938 fn edges(self, a: Self::NodeId) -> Self::Edges {
939 self.graph.edges(a)
940 }
941}
942
943impl<'a, N, E, Ix> IntoEdgesDirected for &'a Dag<N, E, Ix>
944where
945 Ix: IndexType,
946{
947 type EdgesDirected = Edges<'a, E, Ix>;
948 fn edges_directed(self, a: Self::NodeId, dir: pg::Direction) -> Self::EdgesDirected {
949 self.graph.edges_directed(a, dir)
950 }
951}
952
953impl<N, E, Ix> IntoNodeIdentifiers for &Dag<N, E, Ix>
954where
955 Ix: IndexType,
956{
957 type NodeIdentifiers = pg::graph::NodeIndices<Ix>;
958 fn node_identifiers(self) -> Self::NodeIdentifiers {
959 self.graph.node_identifiers()
960 }
961}
962
963impl<'a, N, E, Ix> IntoNodeReferences for &'a Dag<N, E, Ix>
964where
965 Ix: IndexType,
966{
967 type NodeRef = (NodeIndex<Ix>, &'a N);
968 type NodeReferences = pg::graph::NodeReferences<'a, N, Ix>;
969 fn node_references(self) -> Self::NodeReferences {
970 self.graph.node_references()
971 }
972}
973
974impl<N, E, Ix> NodeIndexable for Dag<N, E, Ix>
975where
976 Ix: IndexType,
977{
978 fn node_bound(&self) -> usize {
979 self.graph.node_bound()
980 }
981 fn to_index(&self, ix: NodeIndex<Ix>) -> usize {
982 self.graph.to_index(ix)
983 }
984 fn from_index(&self, ix: usize) -> Self::NodeId {
985 self.graph.from_index(ix)
986 }
987}
988
989impl<N, E, Ix> NodeCompactIndexable for Dag<N, E, Ix> where Ix: IndexType {}
990
991impl<N, E, Ix> Index<NodeIndex<Ix>> for Dag<N, E, Ix>
992where
993 Ix: IndexType,
994{
995 type Output = N;
996 fn index(&self, index: NodeIndex<Ix>) -> &N {
997 &self.graph[index]
998 }
999}
1000
1001impl<N, E, Ix> IndexMut<NodeIndex<Ix>> for Dag<N, E, Ix>
1002where
1003 Ix: IndexType,
1004{
1005 fn index_mut(&mut self, index: NodeIndex<Ix>) -> &mut N {
1006 &mut self.graph[index]
1007 }
1008}
1009
1010impl<N, E, Ix> Index<EdgeIndex<Ix>> for Dag<N, E, Ix>
1011where
1012 Ix: IndexType,
1013{
1014 type Output = E;
1015 fn index(&self, index: EdgeIndex<Ix>) -> &E {
1016 &self.graph[index]
1017 }
1018}
1019
1020impl<N, E, Ix> IndexMut<EdgeIndex<Ix>> for Dag<N, E, Ix>
1021where
1022 Ix: IndexType,
1023{
1024 fn index_mut(&mut self, index: EdgeIndex<Ix>) -> &mut E {
1025 &mut self.graph[index]
1026 }
1027}
1028
1029impl<N, E, Ix> GetAdjacencyMatrix for Dag<N, E, Ix>
1030where
1031 Ix: IndexType,
1032{
1033 type AdjMatrix = <DiGraph<N, E, Ix> as GetAdjacencyMatrix>::AdjMatrix;
1034 fn adjacency_matrix(&self) -> Self::AdjMatrix {
1035 self.graph.adjacency_matrix()
1036 }
1037 fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
1038 self.graph.is_adjacent(matrix, a, b)
1039 }
1040}
1041
1042impl<'a, N, E, Ix> Walker<&'a Dag<N, E, Ix>> for Children<N, E, Ix>
1043where
1044 Ix: IndexType,
1045{
1046 type Item = (EdgeIndex<Ix>, NodeIndex<Ix>);
1047 #[inline]
1048 fn walk_next(&mut self, dag: &'a Dag<N, E, Ix>) -> Option<Self::Item> {
1049 self.walk_edges.next(&dag.graph)
1050 }
1051}
1052
1053impl<'a, N, E, Ix> Walker<&'a Dag<N, E, Ix>> for Parents<N, E, Ix>
1054where
1055 Ix: IndexType,
1056{
1057 type Item = (EdgeIndex<Ix>, NodeIndex<Ix>);
1058 #[inline]
1059 fn walk_next(&mut self, dag: &'a Dag<N, E, Ix>) -> Option<Self::Item> {
1060 self.walk_edges.next(&dag.graph)
1061 }
1062}
1063
1064impl<Ix> Iterator for EdgeIndices<Ix>
1065where
1066 Ix: IndexType,
1067{
1068 type Item = EdgeIndex<Ix>;
1069 fn next(&mut self) -> Option<EdgeIndex<Ix>> {
1070 self.indices.next().map(|i| EdgeIndex::new(i))
1071 }
1072}
1073
1074impl<E> std::fmt::Debug for WouldCycle<E> {
1075 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1076 writeln!(f, "WouldCycle")
1077 }
1078}
1079
1080impl<E> std::fmt::Display for WouldCycle<E> {
1081 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
1082 writeln!(f, "{:?}", self)
1083 }
1084}
1085
1086impl<E> std::error::Error for WouldCycle<E> {
1087 fn description(&self) -> &str {
1088 "Adding this edge would have created a cycle"
1089 }
1090}