diff options
Diffstat (limited to 'vendor/petgraph/src/visit')
-rw-r--r-- | vendor/petgraph/src/visit/dfsvisit.rs | 314 | ||||
-rw-r--r-- | vendor/petgraph/src/visit/filter.rs | 505 | ||||
-rw-r--r-- | vendor/petgraph/src/visit/macros.rs | 135 | ||||
-rw-r--r-- | vendor/petgraph/src/visit/mod.rs | 755 | ||||
-rw-r--r-- | vendor/petgraph/src/visit/reversed.rs | 170 | ||||
-rw-r--r-- | vendor/petgraph/src/visit/traversal.rs | 519 |
6 files changed, 2398 insertions, 0 deletions
diff --git a/vendor/petgraph/src/visit/dfsvisit.rs b/vendor/petgraph/src/visit/dfsvisit.rs new file mode 100644 index 000000000..b14dad5dd --- /dev/null +++ b/vendor/petgraph/src/visit/dfsvisit.rs @@ -0,0 +1,314 @@ +use crate::visit::IntoNeighbors; +use crate::visit::{VisitMap, Visitable}; + +/// Strictly monotonically increasing event time for a depth first search. +#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Default, Hash)] +pub struct Time(pub usize); + +/// A depth first search (DFS) visitor event. +#[derive(Copy, Clone, Debug)] +pub enum DfsEvent<N> { + Discover(N, Time), + /// An edge of the tree formed by the traversal. + TreeEdge(N, N), + /// An edge to an already visited node. + BackEdge(N, N), + /// A cross or forward edge. + /// + /// For an edge *(u, v)*, if the discover time of *v* is greater than *u*, + /// then it is a forward edge, else a cross edge. + CrossForwardEdge(N, N), + /// All edges from a node have been reported. + Finish(N, Time), +} + +/// Return if the expression is a break value, execute the provided statement +/// if it is a prune value. +macro_rules! try_control { + ($e:expr, $p:stmt) => { + try_control!($e, $p, ()); + }; + ($e:expr, $p:stmt, $q:stmt) => { + match $e { + x => { + if x.should_break() { + return x; + } else if x.should_prune() { + $p + } else { + $q + } + } + } + }; +} + +/// Control flow for `depth_first_search` callbacks. +#[derive(Copy, Clone, Debug)] +pub enum Control<B> { + /// Continue the DFS traversal as normal. + Continue, + /// Prune the current node from the DFS traversal. No more edges from this + /// node will be reported to the callback. A `DfsEvent::Finish` for this + /// node will still be reported. This can be returned in response to any + /// `DfsEvent`, except `Finish`, which will panic. + Prune, + /// Stop the DFS traversal and return the provided value. + Break(B), +} + +impl<B> Control<B> { + pub fn breaking() -> Control<()> { + Control::Break(()) + } + /// Get the value in `Control::Break(_)`, if present. + pub fn break_value(self) -> Option<B> { + match self { + Control::Continue | Control::Prune => None, + Control::Break(b) => Some(b), + } + } +} + +/// Control flow for callbacks. +/// +/// The empty return value `()` is equivalent to continue. +pub trait ControlFlow { + fn continuing() -> Self; + fn should_break(&self) -> bool; + fn should_prune(&self) -> bool; +} + +impl ControlFlow for () { + fn continuing() {} + #[inline] + fn should_break(&self) -> bool { + false + } + #[inline] + fn should_prune(&self) -> bool { + false + } +} + +impl<B> ControlFlow for Control<B> { + fn continuing() -> Self { + Control::Continue + } + fn should_break(&self) -> bool { + if let Control::Break(_) = *self { + true + } else { + false + } + } + fn should_prune(&self) -> bool { + match *self { + Control::Prune => true, + Control::Continue | Control::Break(_) => false, + } + } +} + +impl<C: ControlFlow, E> ControlFlow for Result<C, E> { + fn continuing() -> Self { + Ok(C::continuing()) + } + fn should_break(&self) -> bool { + if let Ok(ref c) = *self { + c.should_break() + } else { + true + } + } + fn should_prune(&self) -> bool { + if let Ok(ref c) = *self { + c.should_prune() + } else { + false + } + } +} + +/// The default is `Continue`. +impl<B> Default for Control<B> { + fn default() -> Self { + Control::Continue + } +} + +/// A recursive depth first search. +/// +/// Starting points are the nodes in the iterator `starts` (specify just one +/// start vertex *x* by using `Some(x)`). +/// +/// The traversal emits discovery and finish events for each reachable vertex, +/// and edge classification of each reachable edge. `visitor` is called for each +/// event, see [`DfsEvent`][de] for possible values. +/// +/// The return value should implement the trait `ControlFlow`, and can be used to change +/// the control flow of the search. +/// +/// `Control` Implements `ControlFlow` such that `Control::Continue` resumes the search. +/// `Control::Break` will stop the visit early, returning the contained value. +/// `Control::Prune` will stop traversing any additional edges from the current +/// node and proceed immediately to the `Finish` event. +/// +/// There are implementations of `ControlFlow` for `()`, and `Result<C, E>` where +/// `C: ControlFlow`. The implementation for `()` will continue until finished. +/// For `Result`, upon encountering an `E` it will break, otherwise acting the same as `C`. +/// +/// ***Panics** if you attempt to prune a node from its `Finish` event. +/// +/// [de]: enum.DfsEvent.html +/// +/// # Example returning `Control`. +/// +/// Find a path from vertex 0 to 5, and exit the visit as soon as we reach +/// the goal vertex. +/// +/// ``` +/// use petgraph::prelude::*; +/// use petgraph::graph::node_index as n; +/// use petgraph::visit::depth_first_search; +/// use petgraph::visit::{DfsEvent, Control}; +/// +/// let gr: Graph<(), ()> = Graph::from_edges(&[ +/// (0, 1), (0, 2), (0, 3), +/// (1, 3), +/// (2, 3), (2, 4), +/// (4, 0), (4, 5), +/// ]); +/// +/// // record each predecessor, mapping node → node +/// let mut predecessor = vec![NodeIndex::end(); gr.node_count()]; +/// let start = n(0); +/// let goal = n(5); +/// depth_first_search(&gr, Some(start), |event| { +/// if let DfsEvent::TreeEdge(u, v) = event { +/// predecessor[v.index()] = u; +/// if v == goal { +/// return Control::Break(v); +/// } +/// } +/// Control::Continue +/// }); +/// +/// let mut next = goal; +/// let mut path = vec![next]; +/// while next != start { +/// let pred = predecessor[next.index()]; +/// path.push(pred); +/// next = pred; +/// } +/// path.reverse(); +/// assert_eq!(&path, &[n(0), n(2), n(4), n(5)]); +/// ``` +/// +/// # Example returning a `Result`. +/// ``` +/// use petgraph::graph::node_index as n; +/// use petgraph::prelude::*; +/// use petgraph::visit::depth_first_search; +/// use petgraph::visit::{DfsEvent, Time}; +/// +/// let gr: Graph<(), ()> = Graph::from_edges(&[(0, 1), (1, 2), (1, 1), (2, 1)]); +/// let start = n(0); +/// let mut back_edges = 0; +/// let mut discover_time = 0; +/// // Stop the search, the first time a BackEdge is encountered. +/// let result = depth_first_search(&gr, Some(start), |event| { +/// match event { +/// // In the cases where Ok(()) is returned, +/// // Result falls back to the implementation of Control on the value (). +/// // In the case of (), this is to always return Control::Continue. +/// // continuing the search. +/// DfsEvent::Discover(_, Time(t)) => { +/// discover_time = t; +/// Ok(()) +/// } +/// DfsEvent::BackEdge(_, _) => { +/// back_edges += 1; +/// // the implementation of ControlFlow for Result, +/// // treats this Err value as Continue::Break +/// Err(event) +/// } +/// _ => Ok(()), +/// } +/// }); +/// +/// // Even though the graph has more than one cycle, +/// // The number of back_edges visited by the search should always be 1. +/// assert_eq!(back_edges, 1); +/// println!("discover time:{:?}", discover_time); +/// println!("number of backedges encountered: {}", back_edges); +/// println!("back edge: {:?}", result); +/// ``` +pub fn depth_first_search<G, I, F, C>(graph: G, starts: I, mut visitor: F) -> C +where + G: IntoNeighbors + Visitable, + I: IntoIterator<Item = G::NodeId>, + F: FnMut(DfsEvent<G::NodeId>) -> C, + C: ControlFlow, +{ + let time = &mut Time(0); + let discovered = &mut graph.visit_map(); + let finished = &mut graph.visit_map(); + + for start in starts { + try_control!( + dfs_visitor(graph, start, &mut visitor, discovered, finished, time), + unreachable!() + ); + } + C::continuing() +} + +fn dfs_visitor<G, F, C>( + graph: G, + u: G::NodeId, + visitor: &mut F, + discovered: &mut G::Map, + finished: &mut G::Map, + time: &mut Time, +) -> C +where + G: IntoNeighbors + Visitable, + F: FnMut(DfsEvent<G::NodeId>) -> C, + C: ControlFlow, +{ + if !discovered.visit(u) { + return C::continuing(); + } + + try_control!( + visitor(DfsEvent::Discover(u, time_post_inc(time))), + {}, + for v in graph.neighbors(u) { + if !discovered.is_visited(&v) { + try_control!(visitor(DfsEvent::TreeEdge(u, v)), continue); + try_control!( + dfs_visitor(graph, v, visitor, discovered, finished, time), + unreachable!() + ); + } else if !finished.is_visited(&v) { + try_control!(visitor(DfsEvent::BackEdge(u, v)), continue); + } else { + try_control!(visitor(DfsEvent::CrossForwardEdge(u, v)), continue); + } + } + ); + let first_finish = finished.visit(u); + debug_assert!(first_finish); + try_control!( + visitor(DfsEvent::Finish(u, time_post_inc(time))), + panic!("Pruning on the `DfsEvent::Finish` is not supported!") + ); + C::continuing() +} + +fn time_post_inc(x: &mut Time) -> Time { + let v = *x; + x.0 += 1; + v +} diff --git a/vendor/petgraph/src/visit/filter.rs b/vendor/petgraph/src/visit/filter.rs new file mode 100644 index 000000000..110ebea25 --- /dev/null +++ b/vendor/petgraph/src/visit/filter.rs @@ -0,0 +1,505 @@ +use crate::prelude::*; + +use fixedbitset::FixedBitSet; +use std::collections::HashSet; +use std::marker::PhantomData; + +use crate::data::DataMap; +use crate::visit::{Data, NodeCompactIndexable, NodeCount}; +use crate::visit::{ + GraphBase, GraphProp, IntoEdgeReferences, IntoEdges, IntoEdgesDirected, IntoNeighbors, + IntoNeighborsDirected, IntoNodeIdentifiers, IntoNodeReferences, NodeIndexable, NodeRef, + VisitMap, Visitable, +}; + +/// A graph filter for nodes. +pub trait FilterNode<N> { + /// Return true to have the node be part of the graph + fn include_node(&self, node: N) -> bool; +} + +impl<F, N> FilterNode<N> for F +where + F: Fn(N) -> bool, +{ + fn include_node(&self, n: N) -> bool { + (*self)(n) + } +} + +/// This filter includes the nodes that are contained in the set. +impl<N> FilterNode<N> for FixedBitSet +where + FixedBitSet: VisitMap<N>, +{ + fn include_node(&self, n: N) -> bool { + self.is_visited(&n) + } +} + +/// This filter includes the nodes that are contained in the set. +impl<N, S> FilterNode<N> for HashSet<N, S> +where + HashSet<N, S>: VisitMap<N>, +{ + fn include_node(&self, n: N) -> bool { + self.is_visited(&n) + } +} + +// Can't express these as a generic impl over all references since that would conflict with the +// impl for Fn. +impl<N> FilterNode<N> for &FixedBitSet +where + FixedBitSet: VisitMap<N>, +{ + fn include_node(&self, n: N) -> bool { + self.is_visited(&n) + } +} + +impl<N, S> FilterNode<N> for &HashSet<N, S> +where + HashSet<N, S>: VisitMap<N>, +{ + fn include_node(&self, n: N) -> bool { + self.is_visited(&n) + } +} + +/// A node-filtering graph adaptor. +#[derive(Copy, Clone, Debug)] +pub struct NodeFiltered<G, F>(pub G, pub F); + +impl<F, G> NodeFiltered<G, F> +where + G: GraphBase, + F: Fn(G::NodeId) -> bool, +{ + /// Create an `NodeFiltered` adaptor from the closure `filter`. + pub fn from_fn(graph: G, filter: F) -> Self { + NodeFiltered(graph, filter) + } +} + +impl<G, F> GraphBase for NodeFiltered<G, F> +where + G: GraphBase, +{ + type NodeId = G::NodeId; + type EdgeId = G::EdgeId; +} + +impl<'a, G, F> IntoNeighbors for &'a NodeFiltered<G, F> +where + G: IntoNeighbors, + F: FilterNode<G::NodeId>, +{ + type Neighbors = NodeFilteredNeighbors<'a, G::Neighbors, F>; + fn neighbors(self, n: G::NodeId) -> Self::Neighbors { + NodeFilteredNeighbors { + include_source: self.1.include_node(n), + iter: self.0.neighbors(n), + f: &self.1, + } + } +} + +/// A filtered neighbors iterator. +pub struct NodeFilteredNeighbors<'a, I, F: 'a> { + include_source: bool, + iter: I, + f: &'a F, +} + +impl<'a, I, F> Iterator for NodeFilteredNeighbors<'a, I, F> +where + I: Iterator, + I::Item: Copy, + F: FilterNode<I::Item>, +{ + type Item = I::Item; + fn next(&mut self) -> Option<Self::Item> { + let f = self.f; + if !self.include_source { + None + } else { + self.iter.find(move |&target| f.include_node(target)) + } + } +} + +impl<'a, G, F> IntoNeighborsDirected for &'a NodeFiltered<G, F> +where + G: IntoNeighborsDirected, + F: FilterNode<G::NodeId>, +{ + type NeighborsDirected = NodeFilteredNeighbors<'a, G::NeighborsDirected, F>; + fn neighbors_directed(self, n: G::NodeId, dir: Direction) -> Self::NeighborsDirected { + NodeFilteredNeighbors { + include_source: self.1.include_node(n), + iter: self.0.neighbors_directed(n, dir), + f: &self.1, + } + } +} + +impl<'a, G, F> IntoNodeIdentifiers for &'a NodeFiltered<G, F> +where + G: IntoNodeIdentifiers, + F: FilterNode<G::NodeId>, +{ + type NodeIdentifiers = NodeFilteredNeighbors<'a, G::NodeIdentifiers, F>; + fn node_identifiers(self) -> Self::NodeIdentifiers { + NodeFilteredNeighbors { + include_source: true, + iter: self.0.node_identifiers(), + f: &self.1, + } + } +} + +impl<'a, G, F> IntoNodeReferences for &'a NodeFiltered<G, F> +where + G: IntoNodeReferences, + F: FilterNode<G::NodeId>, +{ + type NodeRef = G::NodeRef; + type NodeReferences = NodeFilteredNodes<'a, G::NodeReferences, F>; + fn node_references(self) -> Self::NodeReferences { + NodeFilteredNodes { + include_source: true, + iter: self.0.node_references(), + f: &self.1, + } + } +} + +/// A filtered node references iterator. +pub struct NodeFilteredNodes<'a, I, F: 'a> { + include_source: bool, + iter: I, + f: &'a F, +} + +impl<'a, I, F> Iterator for NodeFilteredNodes<'a, I, F> +where + I: Iterator, + I::Item: Copy + NodeRef, + F: FilterNode<<I::Item as NodeRef>::NodeId>, +{ + type Item = I::Item; + fn next(&mut self) -> Option<Self::Item> { + let f = self.f; + if !self.include_source { + None + } else { + self.iter.find(move |&target| f.include_node(target.id())) + } + } +} + +impl<'a, G, F> IntoEdgeReferences for &'a NodeFiltered<G, F> +where + G: IntoEdgeReferences, + F: FilterNode<G::NodeId>, +{ + type EdgeRef = G::EdgeRef; + type EdgeReferences = NodeFilteredEdgeReferences<'a, G, G::EdgeReferences, F>; + fn edge_references(self) -> Self::EdgeReferences { + NodeFilteredEdgeReferences { + graph: PhantomData, + iter: self.0.edge_references(), + f: &self.1, + } + } +} + +/// A filtered edges iterator. +pub struct NodeFilteredEdgeReferences<'a, G, I, F: 'a> { + graph: PhantomData<G>, + iter: I, + f: &'a F, +} + +impl<'a, G, I, F> Iterator for NodeFilteredEdgeReferences<'a, G, I, F> +where + F: FilterNode<G::NodeId>, + G: IntoEdgeReferences, + I: Iterator<Item = G::EdgeRef>, +{ + type Item = I::Item; + fn next(&mut self) -> Option<Self::Item> { + let f = self.f; + self.iter + .find(move |&edge| f.include_node(edge.source()) && f.include_node(edge.target())) + } +} + +impl<'a, G, F> IntoEdges for &'a NodeFiltered<G, F> +where + G: IntoEdges, + F: FilterNode<G::NodeId>, +{ + type Edges = NodeFilteredEdges<'a, G, G::Edges, F>; + fn edges(self, a: G::NodeId) -> Self::Edges { + NodeFilteredEdges { + graph: PhantomData, + include_source: self.1.include_node(a), + iter: self.0.edges(a), + f: &self.1, + } + } +} + +/// A filtered edges iterator. +pub struct NodeFilteredEdges<'a, G, I, F: 'a> { + graph: PhantomData<G>, + include_source: bool, + iter: I, + f: &'a F, +} + +impl<'a, G, I, F> Iterator for NodeFilteredEdges<'a, G, I, F> +where + F: FilterNode<G::NodeId>, + G: IntoEdges, + I: Iterator<Item = G::EdgeRef>, +{ + type Item = I::Item; + fn next(&mut self) -> Option<Self::Item> { + if !self.include_source { + None + } else { + let f = self.f; + self.iter.find(move |&edge| f.include_node(edge.target())) + } + } +} + +impl<G, F> DataMap for NodeFiltered<G, F> +where + G: DataMap, + F: FilterNode<G::NodeId>, +{ + fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> { + if self.1.include_node(id) { + self.0.node_weight(id) + } else { + None + } + } + + fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> { + self.0.edge_weight(id) + } +} + +macro_rules! access0 { + ($e:expr) => { + $e.0 + }; +} + +Data! {delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]} +NodeIndexable! {delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]} +GraphProp! {delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]} +Visitable! {delegate_impl [[G, F], G, NodeFiltered<G, F>, access0]} + +/// A graph filter for edges +pub trait FilterEdge<Edge> { + /// Return true to have the edge be part of the graph + fn include_edge(&self, edge: Edge) -> bool; +} + +impl<F, N> FilterEdge<N> for F +where + F: Fn(N) -> bool, +{ + fn include_edge(&self, n: N) -> bool { + (*self)(n) + } +} + +/// An edge-filtering graph adaptor. +/// +/// The adaptor may filter out edges. The filter implements the trait +/// `FilterEdge`. Closures of type `Fn(G::EdgeRef) -> bool` already +/// implement this trait. +/// +/// The filter may use edge source, target, id, and weight to select whether to +/// include the edge or not. +#[derive(Copy, Clone, Debug)] +pub struct EdgeFiltered<G, F>(pub G, pub F); + +impl<F, G> EdgeFiltered<G, F> +where + G: IntoEdgeReferences, + F: Fn(G::EdgeRef) -> bool, +{ + /// Create an `EdgeFiltered` adaptor from the closure `filter`. + pub fn from_fn(graph: G, filter: F) -> Self { + EdgeFiltered(graph, filter) + } +} + +impl<G, F> GraphBase for EdgeFiltered<G, F> +where + G: GraphBase, +{ + type NodeId = G::NodeId; + type EdgeId = G::EdgeId; +} + +impl<'a, G, F> IntoNeighbors for &'a EdgeFiltered<G, F> +where + G: IntoEdges, + F: FilterEdge<G::EdgeRef>, +{ + type Neighbors = EdgeFilteredNeighbors<'a, G, F>; + fn neighbors(self, n: G::NodeId) -> Self::Neighbors { + EdgeFilteredNeighbors { + iter: self.0.edges(n), + f: &self.1, + } + } +} + +impl<'a, G, F> IntoNeighborsDirected for &'a EdgeFiltered<G, F> +where + G: IntoEdgesDirected, + F: FilterEdge<G::EdgeRef>, +{ + type NeighborsDirected = EdgeFilteredNeighborsDirected<'a, G, F>; + fn neighbors_directed(self, n: G::NodeId, dir: Direction) -> Self::NeighborsDirected { + EdgeFilteredNeighborsDirected { + iter: self.0.edges_directed(n, dir), + f: &self.1, + from: n, + } + } +} + +/// A filtered neighbors iterator. +pub struct EdgeFilteredNeighbors<'a, G, F: 'a> +where + G: IntoEdges, +{ + iter: G::Edges, + f: &'a F, +} + +impl<'a, G, F> Iterator for EdgeFilteredNeighbors<'a, G, F> +where + F: FilterEdge<G::EdgeRef>, + G: IntoEdges, +{ + type Item = G::NodeId; + fn next(&mut self) -> Option<Self::Item> { + let f = self.f; + (&mut self.iter) + .filter_map(move |edge| { + if f.include_edge(edge) { + Some(edge.target()) + } else { + None + } + }) + .next() + } +} + +impl<'a, G, F> IntoEdgeReferences for &'a EdgeFiltered<G, F> +where + G: IntoEdgeReferences, + F: FilterEdge<G::EdgeRef>, +{ + type EdgeRef = G::EdgeRef; + type EdgeReferences = EdgeFilteredEdges<'a, G, G::EdgeReferences, F>; + fn edge_references(self) -> Self::EdgeReferences { + EdgeFilteredEdges { + graph: PhantomData, + iter: self.0.edge_references(), + f: &self.1, + } + } +} + +impl<'a, G, F> IntoEdges for &'a EdgeFiltered<G, F> +where + G: IntoEdges, + F: FilterEdge<G::EdgeRef>, +{ + type Edges = EdgeFilteredEdges<'a, G, G::Edges, F>; + fn edges(self, n: G::NodeId) -> Self::Edges { + EdgeFilteredEdges { + graph: PhantomData, + iter: self.0.edges(n), + f: &self.1, + } + } +} + +/// A filtered edges iterator. +pub struct EdgeFilteredEdges<'a, G, I, F: 'a> { + graph: PhantomData<G>, + iter: I, + f: &'a F, +} + +impl<'a, G, I, F> Iterator for EdgeFilteredEdges<'a, G, I, F> +where + F: FilterEdge<G::EdgeRef>, + G: IntoEdgeReferences, + I: Iterator<Item = G::EdgeRef>, +{ + type Item = I::Item; + fn next(&mut self) -> Option<Self::Item> { + let f = self.f; + self.iter.find(move |&edge| f.include_edge(edge)) + } +} + +/// A filtered neighbors-directed iterator. +pub struct EdgeFilteredNeighborsDirected<'a, G, F: 'a> +where + G: IntoEdgesDirected, +{ + iter: G::EdgesDirected, + f: &'a F, + from: G::NodeId, +} + +impl<'a, G, F> Iterator for EdgeFilteredNeighborsDirected<'a, G, F> +where + F: FilterEdge<G::EdgeRef>, + G: IntoEdgesDirected, +{ + type Item = G::NodeId; + fn next(&mut self) -> Option<Self::Item> { + let f = self.f; + let from = self.from; + (&mut self.iter) + .filter_map(move |edge| { + if f.include_edge(edge) { + if edge.source() != from { + Some(edge.source()) + } else { + Some(edge.target()) // includes case where from == source == target + } + } else { + None + } + }) + .next() + } +} + +Data! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]} +GraphProp! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]} +IntoNodeIdentifiers! {delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]} +IntoNodeReferences! {delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]} +NodeCompactIndexable! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]} +NodeCount! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]} +NodeIndexable! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]} +Visitable! {delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]} diff --git a/vendor/petgraph/src/visit/macros.rs b/vendor/petgraph/src/visit/macros.rs new file mode 100644 index 000000000..1b36030de --- /dev/null +++ b/vendor/petgraph/src/visit/macros.rs @@ -0,0 +1,135 @@ +/// Define a trait as usual, and a macro that can be used to instantiate +/// implementations of it. +/// +/// There *must* be section markers in the trait definition: +/// @section type for associated types +/// @section self for methods +/// @section nodelegate for arbitrary tail that is not forwarded. +macro_rules! trait_template { + ($(#[$doc:meta])* pub trait $name:ident $($methods:tt)*) => { + macro_rules! $name { + ($m:ident $extra:tt) => { + $m! { + $extra + pub trait $name $($methods)* + } + } + } + + remove_sections! { [] + $(#[$doc])* + pub trait $name $($methods)* + + // This is where the trait definition is reproduced by the macro. + // It makes the source links point to this place! + // + // I'm sorry, you'll have to find the source by looking at the + // source of the module the trait is defined in. + // + // We use this nifty macro so that we can automatically generate + // delegation trait impls and implement the graph traits for more + // types and combinators. + } + } +} + +macro_rules! remove_sections_inner { + ([$($stack:tt)*]) => { + $($stack)* + }; + // escape the following tt + ([$($stack:tt)*] @escape $_x:tt $($t:tt)*) => { + remove_sections_inner!([$($stack)*] $($t)*); + }; + ([$($stack:tt)*] @section $x:ident $($t:tt)*) => { + remove_sections_inner!([$($stack)*] $($t)*); + }; + ([$($stack:tt)*] $t:tt $($tail:tt)*) => { + remove_sections_inner!([$($stack)* $t] $($tail)*); + }; +} + +// This is the outer layer, just find the { } of the actual trait definition +// recurse once into { }, but not more. +macro_rules! remove_sections { + ([$($stack:tt)*]) => { + $($stack)* + }; + ([$($stack:tt)*] { $($tail:tt)* }) => { + $($stack)* { + remove_sections_inner!([] $($tail)*); + } + }; + ([$($stack:tt)*] $t:tt $($tail:tt)*) => { + remove_sections!([$($stack)* $t] $($tail)*); + }; +} + +macro_rules! deref { + ($e:expr) => { + *$e + }; +} +macro_rules! deref_twice { + ($e:expr) => { + **$e + }; +} + +/// Implement a trait by delegation. By default as if we are delegating +/// from &G to G. +macro_rules! delegate_impl { + ([] $($rest:tt)*) => { + delegate_impl! { [['a, G], G, &'a G, deref] $($rest)* } + }; + ([[$($param:tt)*], $self_type:ident, $self_wrap:ty, $self_map:ident] + pub trait $name:ident $(: $sup:ident)* $(+ $more_sup:ident)* { + + // "Escaped" associated types. Stripped before making the `trait` + // itself, but forwarded when delegating impls. + $( + @escape [type $assoc_name_ext:ident] + // Associated types. Forwarded. + )* + $( + @section type + $( + $(#[$_assoc_attr:meta])* + type $assoc_name:ident $(: $assoc_bound:ty)*; + )+ + )* + // Methods. Forwarded. Using $self_map!(self) around the self argument. + // Methods must use receiver `self` or explicit type like `self: &Self` + // &self and &mut self are _not_ supported. + $( + @section self + $( + $(#[$_method_attr:meta])* + fn $method_name:ident(self $(: $self_selftype:ty)* $(,$marg:ident : $marg_ty:ty)*) $(-> $mret:ty)?; + )+ + )* + // Arbitrary tail that is ignored when forwarding. + $( + @section nodelegate + $($tail:tt)* + )* + }) => { + impl<$($param)*> $name for $self_wrap where $self_type: $name { + $( + $( + type $assoc_name = $self_type::$assoc_name; + )* + )* + $( + type $assoc_name_ext = $self_type::$assoc_name_ext; + )* + $( + $( + fn $method_name(self $(: $self_selftype)* $(,$marg: $marg_ty)*) $(-> $mret)? { + $self_map!(self).$method_name($($marg),*) + } + )* + )* + } + } +} diff --git a/vendor/petgraph/src/visit/mod.rs b/vendor/petgraph/src/visit/mod.rs new file mode 100644 index 000000000..d34979aa3 --- /dev/null +++ b/vendor/petgraph/src/visit/mod.rs @@ -0,0 +1,755 @@ +//! Graph traits and graph traversals. +//! +//! ### The `Into-` Traits +//! +//! Graph traits like [`IntoNeighbors`][in] create iterators and use the same +//! pattern that `IntoIterator` does: the trait takes a reference to a graph, +//! and produces an iterator. These traits are quite composable, but with the +//! limitation that they only use shared references to graphs. +//! +//! ### Graph Traversal +//! +//! [`Dfs`](struct.Dfs.html), [`Bfs`][bfs], [`DfsPostOrder`][dfspo] and +//! [`Topo`][topo] are basic visitors and they use “walker” methods: the +//! visitors don't hold the graph as borrowed during traversal, only for the +//! `.next()` call on the walker. They can be converted to iterators +//! through the [`Walker`][w] trait. +//! +//! There is also the callback based traversal [`depth_first_search`][dfs]. +//! +//! [bfs]: struct.Bfs.html +//! [dfspo]: struct.DfsPostOrder.html +//! [topo]: struct.Topo.html +//! [dfs]: fn.depth_first_search.html +//! [w]: trait.Walker.html +//! +//! ### Other Graph Traits +//! +//! The traits are rather loosely coupled at the moment (which is intentional, +//! but will develop a bit), and there are traits missing that could be added. +//! +//! Not much is needed to be able to use the visitors on a graph. A graph +//! needs to define [`GraphBase`][gb], [`IntoNeighbors`][in] and +//! [`Visitable`][vis] as a minimum. +//! +//! [gb]: trait.GraphBase.html +//! [in]: trait.IntoNeighbors.html +//! [vis]: trait.Visitable.html +//! + +// filter, reversed have their `mod` lines at the end, +// so that they can use the trait template macros +pub use self::filter::*; +pub use self::reversed::*; + +#[macro_use] +mod macros; + +mod dfsvisit; +mod traversal; +pub use self::dfsvisit::*; +pub use self::traversal::*; + +use fixedbitset::FixedBitSet; +use std::collections::HashSet; +use std::hash::{BuildHasher, Hash}; + +use super::{graph, EdgeType}; +use crate::graph::NodeIndex; +#[cfg(feature = "graphmap")] +use crate::prelude::GraphMap; +#[cfg(feature = "stable_graph")] +use crate::prelude::StableGraph; +use crate::prelude::{Direction, Graph}; + +use crate::graph::Frozen; +use crate::graph::IndexType; +#[cfg(feature = "stable_graph")] +use crate::stable_graph; + +#[cfg(feature = "graphmap")] +use crate::graphmap::{self, NodeTrait}; + +trait_template! { +/// Base graph trait: defines the associated node identifier and +/// edge identifier types. +pub trait GraphBase { + // FIXME: We can drop this escape/nodelegate stuff in Rust 1.18 + @escape [type NodeId] + @escape [type EdgeId] + @section nodelegate + /// edge identifier + type EdgeId: Copy + PartialEq; + /// node identifier + type NodeId: Copy + PartialEq; +} +} + +GraphBase! {delegate_impl []} +GraphBase! {delegate_impl [['a, G], G, &'a mut G, deref]} + +/// A copyable reference to a graph. +pub trait GraphRef: Copy + GraphBase {} + +impl<'a, G> GraphRef for &'a G where G: GraphBase {} + +impl<'a, G> GraphBase for Frozen<'a, G> +where + G: GraphBase, +{ + type NodeId = G::NodeId; + type EdgeId = G::EdgeId; +} + +#[cfg(feature = "stable_graph")] +impl<'a, N, E: 'a, Ty, Ix> IntoNeighbors for &'a StableGraph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type Neighbors = stable_graph::Neighbors<'a, E, Ix>; + fn neighbors(self, n: Self::NodeId) -> Self::Neighbors { + (*self).neighbors(n) + } +} + +#[cfg(feature = "graphmap")] +impl<'a, N: 'a, E, Ty> IntoNeighbors for &'a GraphMap<N, E, Ty> +where + N: Copy + Ord + Hash, + Ty: EdgeType, +{ + type Neighbors = graphmap::Neighbors<'a, N, Ty>; + fn neighbors(self, n: Self::NodeId) -> Self::Neighbors { + self.neighbors(n) + } +} + +trait_template! { +/// Access to the neighbors of each node +/// +/// The neighbors are, depending on the graph’s edge type: +/// +/// - `Directed`: All targets of edges from `a`. +/// - `Undirected`: All other endpoints of edges connected to `a`. +pub trait IntoNeighbors : GraphRef { + @section type + type Neighbors: Iterator<Item=Self::NodeId>; + @section self + /// Return an iterator of the neighbors of node `a`. + fn neighbors(self: Self, a: Self::NodeId) -> Self::Neighbors; +} +} + +IntoNeighbors! {delegate_impl []} + +trait_template! { +/// Access to the neighbors of each node, through incoming or outgoing edges. +/// +/// Depending on the graph’s edge type, the neighbors of a given directionality +/// are: +/// +/// - `Directed`, `Outgoing`: All targets of edges from `a`. +/// - `Directed`, `Incoming`: All sources of edges to `a`. +/// - `Undirected`: All other endpoints of edges connected to `a`. +pub trait IntoNeighborsDirected : IntoNeighbors { + @section type + type NeighborsDirected: Iterator<Item=Self::NodeId>; + @section self + fn neighbors_directed(self, n: Self::NodeId, d: Direction) + -> Self::NeighborsDirected; +} +} + +impl<'a, N, E: 'a, Ty, Ix> IntoNeighbors for &'a Graph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type Neighbors = graph::Neighbors<'a, E, Ix>; + fn neighbors(self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix> { + Graph::neighbors(self, n) + } +} + +impl<'a, N, E: 'a, Ty, Ix> IntoNeighborsDirected for &'a Graph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type NeighborsDirected = graph::Neighbors<'a, E, Ix>; + fn neighbors_directed( + self, + n: graph::NodeIndex<Ix>, + d: Direction, + ) -> graph::Neighbors<'a, E, Ix> { + Graph::neighbors_directed(self, n, d) + } +} + +#[cfg(feature = "stable_graph")] +impl<'a, N, E: 'a, Ty, Ix> IntoNeighborsDirected for &'a StableGraph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type NeighborsDirected = stable_graph::Neighbors<'a, E, Ix>; + fn neighbors_directed(self, n: graph::NodeIndex<Ix>, d: Direction) -> Self::NeighborsDirected { + StableGraph::neighbors_directed(self, n, d) + } +} + +#[cfg(feature = "graphmap")] +impl<'a, N: 'a, E, Ty> IntoNeighborsDirected for &'a GraphMap<N, E, Ty> +where + N: Copy + Ord + Hash, + Ty: EdgeType, +{ + type NeighborsDirected = graphmap::NeighborsDirected<'a, N, Ty>; + fn neighbors_directed(self, n: N, dir: Direction) -> Self::NeighborsDirected { + self.neighbors_directed(n, dir) + } +} + +trait_template! { +/// Access to the edges of each node. +/// +/// The edges are, depending on the graph’s edge type: +/// +/// - `Directed`: All edges from `a`. +/// - `Undirected`: All edges connected to `a`. +/// +/// This is an extended version of the trait `IntoNeighbors`; the former +/// only iterates over the target node identifiers, while this trait +/// yields edge references (trait [`EdgeRef`][er]). +/// +/// [er]: trait.EdgeRef.html +pub trait IntoEdges : IntoEdgeReferences + IntoNeighbors { + @section type + type Edges: Iterator<Item=Self::EdgeRef>; + @section self + fn edges(self, a: Self::NodeId) -> Self::Edges; +} +} + +IntoEdges! {delegate_impl []} + +trait_template! { +/// Access to all edges of each node, in the specified direction. +/// +/// The edges are, depending on the direction and the graph’s edge type: +/// +/// +/// - `Directed`, `Outgoing`: All edges from `a`. +/// - `Directed`, `Incoming`: All edges to `a`. +/// - `Undirected`, `Outgoing`: All edges connected to `a`, with `a` being the source of each edge. +/// - `Undirected`, `Incoming`: All edges connected to `a`, with `a` being the target of each edge. +/// +/// This is an extended version of the trait `IntoNeighborsDirected`; the former +/// only iterates over the target node identifiers, while this trait +/// yields edge references (trait [`EdgeRef`][er]). +/// +/// [er]: trait.EdgeRef.html +pub trait IntoEdgesDirected : IntoEdges + IntoNeighborsDirected { + @section type + type EdgesDirected: Iterator<Item=Self::EdgeRef>; + @section self + fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected; +} +} + +IntoEdgesDirected! {delegate_impl []} + +trait_template! { +/// Access to the sequence of the graph’s `NodeId`s. +pub trait IntoNodeIdentifiers : GraphRef { + @section type + type NodeIdentifiers: Iterator<Item=Self::NodeId>; + @section self + fn node_identifiers(self) -> Self::NodeIdentifiers; +} +} + +IntoNodeIdentifiers! {delegate_impl []} + +impl<'a, N, E: 'a, Ty, Ix> IntoNodeIdentifiers for &'a Graph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type NodeIdentifiers = graph::NodeIndices<Ix>; + fn node_identifiers(self) -> graph::NodeIndices<Ix> { + Graph::node_indices(self) + } +} + +impl<N, E, Ty, Ix> NodeCount for Graph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + fn node_count(&self) -> usize { + self.node_count() + } +} + +#[cfg(feature = "stable_graph")] +impl<'a, N, E: 'a, Ty, Ix> IntoNodeIdentifiers for &'a StableGraph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type NodeIdentifiers = stable_graph::NodeIndices<'a, N, Ix>; + fn node_identifiers(self) -> Self::NodeIdentifiers { + StableGraph::node_indices(self) + } +} + +#[cfg(feature = "stable_graph")] +impl<N, E, Ty, Ix> NodeCount for StableGraph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + fn node_count(&self) -> usize { + self.node_count() + } +} + +IntoNeighborsDirected! {delegate_impl []} + +trait_template! { +/// Define associated data for nodes and edges +pub trait Data : GraphBase { + @section type + type NodeWeight; + type EdgeWeight; +} +} + +Data! {delegate_impl []} +Data! {delegate_impl [['a, G], G, &'a mut G, deref]} + +/// An edge reference. +/// +/// Edge references are used by traits `IntoEdges` and `IntoEdgeReferences`. +pub trait EdgeRef: Copy { + type NodeId; + type EdgeId; + type Weight; + /// The source node of the edge. + fn source(&self) -> Self::NodeId; + /// The target node of the edge. + fn target(&self) -> Self::NodeId; + /// A reference to the weight of the edge. + fn weight(&self) -> &Self::Weight; + /// The edge’s identifier. + fn id(&self) -> Self::EdgeId; +} + +impl<'a, N, E> EdgeRef for (N, N, &'a E) +where + N: Copy, +{ + type NodeId = N; + type EdgeId = (N, N); + type Weight = E; + + fn source(&self) -> N { + self.0 + } + fn target(&self) -> N { + self.1 + } + fn weight(&self) -> &E { + self.2 + } + fn id(&self) -> (N, N) { + (self.0, self.1) + } +} + +/// A node reference. +pub trait NodeRef: Copy { + type NodeId; + type Weight; + fn id(&self) -> Self::NodeId; + fn weight(&self) -> &Self::Weight; +} + +trait_template! { +/// Access to the sequence of the graph’s nodes +pub trait IntoNodeReferences : Data + IntoNodeIdentifiers { + @section type + type NodeRef: NodeRef<NodeId=Self::NodeId, Weight=Self::NodeWeight>; + type NodeReferences: Iterator<Item=Self::NodeRef>; + @section self + fn node_references(self) -> Self::NodeReferences; +} +} + +IntoNodeReferences! {delegate_impl []} + +impl<Id> NodeRef for (Id, ()) +where + Id: Copy, +{ + type NodeId = Id; + type Weight = (); + fn id(&self) -> Self::NodeId { + self.0 + } + fn weight(&self) -> &Self::Weight { + static DUMMY: () = (); + &DUMMY + } +} + +impl<'a, Id, W> NodeRef for (Id, &'a W) +where + Id: Copy, +{ + type NodeId = Id; + type Weight = W; + fn id(&self) -> Self::NodeId { + self.0 + } + fn weight(&self) -> &Self::Weight { + self.1 + } +} + +trait_template! { +/// Access to the sequence of the graph’s edges +pub trait IntoEdgeReferences : Data + GraphRef { + @section type + type EdgeRef: EdgeRef<NodeId=Self::NodeId, EdgeId=Self::EdgeId, + Weight=Self::EdgeWeight>; + type EdgeReferences: Iterator<Item=Self::EdgeRef>; + @section self + fn edge_references(self) -> Self::EdgeReferences; +} +} + +IntoEdgeReferences! {delegate_impl [] } + +#[cfg(feature = "graphmap")] +impl<N, E, Ty> Data for GraphMap<N, E, Ty> +where + N: Copy + PartialEq, + Ty: EdgeType, +{ + type NodeWeight = N; + type EdgeWeight = E; +} + +trait_template! { + /// Edge kind property (directed or undirected edges) +pub trait GraphProp : GraphBase { + @section type + /// The kind edges in the graph. + type EdgeType: EdgeType; + + @section nodelegate + fn is_directed(&self) -> bool { + <Self::EdgeType>::is_directed() + } +} +} + +GraphProp! {delegate_impl []} + +impl<N, E, Ty, Ix> GraphProp for Graph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type EdgeType = Ty; +} + +#[cfg(feature = "stable_graph")] +impl<N, E, Ty, Ix> GraphProp for StableGraph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type EdgeType = Ty; +} + +#[cfg(feature = "graphmap")] +impl<N, E, Ty> GraphProp for GraphMap<N, E, Ty> +where + N: NodeTrait, + Ty: EdgeType, +{ + type EdgeType = Ty; +} + +impl<'a, N: 'a, E: 'a, Ty, Ix> IntoEdgeReferences for &'a Graph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type EdgeRef = graph::EdgeReference<'a, E, Ix>; + type EdgeReferences = graph::EdgeReferences<'a, E, Ix>; + fn edge_references(self) -> Self::EdgeReferences { + (*self).edge_references() + } +} + +trait_template! { + /// The graph’s `NodeId`s map to indices + pub trait NodeIndexable : GraphBase { + @section self + /// Return an upper bound of the node indices in the graph + /// (suitable for the size of a bitmap). + fn node_bound(self: &Self) -> usize; + /// Convert `a` to an integer index. + fn to_index(self: &Self, a: Self::NodeId) -> usize; + /// Convert `i` to a node index + fn from_index(self: &Self, i: usize) -> Self::NodeId; + } +} + +NodeIndexable! {delegate_impl []} + +trait_template! { +/// A graph with a known node count. +pub trait NodeCount : GraphBase { + @section self + fn node_count(self: &Self) -> usize; +} +} + +NodeCount! {delegate_impl []} + +trait_template! { +/// The graph’s `NodeId`s map to indices, in a range without holes. +/// +/// The graph's node identifiers correspond to exactly the indices +/// `0..self.node_bound()`. +pub trait NodeCompactIndexable : NodeIndexable + NodeCount { } +} + +NodeCompactIndexable! {delegate_impl []} + +impl<N, E, Ty, Ix> NodeIndexable for Graph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + fn node_bound(&self) -> usize { + self.node_count() + } + fn to_index(&self, ix: NodeIndex<Ix>) -> usize { + ix.index() + } + fn from_index(&self, ix: usize) -> Self::NodeId { + NodeIndex::new(ix) + } +} + +impl<N, E, Ty, Ix> NodeCompactIndexable for Graph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ +} + +/// A mapping for storing the visited status for NodeId `N`. +pub trait VisitMap<N> { + /// Mark `a` as visited. + /// + /// Return **true** if this is the first visit, false otherwise. + fn visit(&mut self, a: N) -> bool; + + /// Return whether `a` has been visited before. + fn is_visited(&self, a: &N) -> bool; +} + +impl<Ix> VisitMap<graph::NodeIndex<Ix>> for FixedBitSet +where + Ix: IndexType, +{ + fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool { + !self.put(x.index()) + } + fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool { + self.contains(x.index()) + } +} + +impl<Ix> VisitMap<graph::EdgeIndex<Ix>> for FixedBitSet +where + Ix: IndexType, +{ + fn visit(&mut self, x: graph::EdgeIndex<Ix>) -> bool { + !self.put(x.index()) + } + fn is_visited(&self, x: &graph::EdgeIndex<Ix>) -> bool { + self.contains(x.index()) + } +} + +impl<Ix> VisitMap<Ix> for FixedBitSet +where + Ix: IndexType, +{ + fn visit(&mut self, x: Ix) -> bool { + !self.put(x.index()) + } + fn is_visited(&self, x: &Ix) -> bool { + self.contains(x.index()) + } +} + +impl<N, S> VisitMap<N> for HashSet<N, S> +where + N: Hash + Eq, + S: BuildHasher, +{ + fn visit(&mut self, x: N) -> bool { + self.insert(x) + } + fn is_visited(&self, x: &N) -> bool { + self.contains(x) + } +} + +trait_template! { +/// A graph that can create a map that tracks the visited status of its nodes. +pub trait Visitable : GraphBase { + @section type + /// The associated map type + type Map: VisitMap<Self::NodeId>; + @section self + /// Create a new visitor map + fn visit_map(self: &Self) -> Self::Map; + /// Reset the visitor map (and resize to new size of graph if needed) + fn reset_map(self: &Self, map: &mut Self::Map); +} +} +Visitable! {delegate_impl []} + +impl<N, E, Ty, Ix> GraphBase for Graph<N, E, Ty, Ix> +where + Ix: IndexType, +{ + type NodeId = graph::NodeIndex<Ix>; + type EdgeId = graph::EdgeIndex<Ix>; +} + +impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type Map = FixedBitSet; + fn visit_map(&self) -> FixedBitSet { + FixedBitSet::with_capacity(self.node_count()) + } + + fn reset_map(&self, map: &mut Self::Map) { + map.clear(); + map.grow(self.node_count()); + } +} + +#[cfg(feature = "stable_graph")] +impl<N, E, Ty, Ix> GraphBase for StableGraph<N, E, Ty, Ix> +where + Ix: IndexType, +{ + type NodeId = graph::NodeIndex<Ix>; + type EdgeId = graph::EdgeIndex<Ix>; +} + +#[cfg(feature = "stable_graph")] +impl<N, E, Ty, Ix> Visitable for StableGraph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type Map = FixedBitSet; + fn visit_map(&self) -> FixedBitSet { + FixedBitSet::with_capacity(self.node_bound()) + } + fn reset_map(&self, map: &mut Self::Map) { + map.clear(); + map.grow(self.node_bound()); + } +} + +#[cfg(feature = "stable_graph")] +impl<N, E, Ty, Ix> Data for StableGraph<N, E, Ty, Ix> +where + Ty: EdgeType, + Ix: IndexType, +{ + type NodeWeight = N; + type EdgeWeight = E; +} + +#[cfg(feature = "graphmap")] +impl<N, E, Ty> GraphBase for GraphMap<N, E, Ty> +where + N: Copy + PartialEq, +{ + type NodeId = N; + type EdgeId = (N, N); +} + +#[cfg(feature = "graphmap")] +impl<N, E, Ty> Visitable for GraphMap<N, E, Ty> +where + N: Copy + Ord + Hash, + Ty: EdgeType, +{ + type Map = HashSet<N>; + fn visit_map(&self) -> HashSet<N> { + HashSet::with_capacity(self.node_count()) + } + fn reset_map(&self, map: &mut Self::Map) { + map.clear(); + } +} + +trait_template! { +/// Create or access the adjacency matrix of a graph. +/// +/// The implementor can either create an adjacency matrix, or it can return +/// a placeholder if it has the needed representation internally. +pub trait GetAdjacencyMatrix : GraphBase { + @section type + /// The associated adjacency matrix type + type AdjMatrix; + @section self + /// Create the adjacency matrix + fn adjacency_matrix(self: &Self) -> Self::AdjMatrix; + /// Return true if there is an edge from `a` to `b`, false otherwise. + /// + /// Computes in O(1) time. + fn is_adjacent(self: &Self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool; +} +} + +GetAdjacencyMatrix! {delegate_impl []} + +#[cfg(feature = "graphmap")] +/// The `GraphMap` keeps an adjacency matrix internally. +impl<N, E, Ty> GetAdjacencyMatrix for GraphMap<N, E, Ty> +where + N: Copy + Ord + Hash, + Ty: EdgeType, +{ + type AdjMatrix = (); + #[inline] + fn adjacency_matrix(&self) {} + #[inline] + fn is_adjacent(&self, _: &(), a: N, b: N) -> bool { + self.contains_edge(a, b) + } +} + +mod filter; +mod reversed; diff --git a/vendor/petgraph/src/visit/reversed.rs b/vendor/petgraph/src/visit/reversed.rs new file mode 100644 index 000000000..70a6f578f --- /dev/null +++ b/vendor/petgraph/src/visit/reversed.rs @@ -0,0 +1,170 @@ +use crate::{Direction, Incoming}; + +use crate::visit::{ + Data, EdgeRef, GraphBase, GraphProp, GraphRef, IntoEdgeReferences, IntoEdges, + IntoEdgesDirected, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers, + IntoNodeReferences, NodeCompactIndexable, NodeCount, NodeIndexable, Visitable, +}; + +/// An edge-reversing graph adaptor. +/// +/// All edges have the opposite direction with `Reversed`. +#[derive(Copy, Clone, Debug)] +pub struct Reversed<G>(pub G); + +impl<G: GraphBase> GraphBase for Reversed<G> { + type NodeId = G::NodeId; + type EdgeId = G::EdgeId; +} + +impl<G: GraphRef> GraphRef for Reversed<G> {} + +Data! {delegate_impl [[G], G, Reversed<G>, access0]} + +impl<G> IntoNeighbors for Reversed<G> +where + G: IntoNeighborsDirected, +{ + type Neighbors = G::NeighborsDirected; + fn neighbors(self, n: G::NodeId) -> G::NeighborsDirected { + self.0.neighbors_directed(n, Incoming) + } +} + +impl<G> IntoNeighborsDirected for Reversed<G> +where + G: IntoNeighborsDirected, +{ + type NeighborsDirected = G::NeighborsDirected; + fn neighbors_directed(self, n: G::NodeId, d: Direction) -> G::NeighborsDirected { + self.0.neighbors_directed(n, d.opposite()) + } +} + +impl<G> IntoEdges for Reversed<G> +where + G: IntoEdgesDirected, +{ + type Edges = ReversedEdges<G::EdgesDirected>; + fn edges(self, a: Self::NodeId) -> Self::Edges { + ReversedEdges { + iter: self.0.edges_directed(a, Incoming), + } + } +} + +impl<G> IntoEdgesDirected for Reversed<G> +where + G: IntoEdgesDirected, +{ + type EdgesDirected = ReversedEdges<G::EdgesDirected>; + fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::Edges { + ReversedEdges { + iter: self.0.edges_directed(a, dir.opposite()), + } + } +} + +impl<G: Visitable> Visitable for Reversed<G> { + type Map = G::Map; + fn visit_map(&self) -> G::Map { + self.0.visit_map() + } + fn reset_map(&self, map: &mut Self::Map) { + self.0.reset_map(map); + } +} + +/// A reversed edges iterator. +pub struct ReversedEdges<I> { + iter: I, +} + +impl<I> Iterator for ReversedEdges<I> +where + I: Iterator, + I::Item: EdgeRef, +{ + type Item = ReversedEdgeReference<I::Item>; + fn next(&mut self) -> Option<Self::Item> { + self.iter.next().map(ReversedEdgeReference) + } +} + +/// A reversed edge reference +#[derive(Copy, Clone, Debug)] +pub struct ReversedEdgeReference<R>(R); + +impl<R> ReversedEdgeReference<R> { + /// Return the original, unreversed edge reference. + pub fn as_unreversed(&self) -> &R { &self.0 } + + /// Consume `self` and return the original, unreversed edge reference. + pub fn into_unreversed(self) -> R { + self.0 + } +} + +/// An edge reference +impl<R> EdgeRef for ReversedEdgeReference<R> +where + R: EdgeRef, +{ + type NodeId = R::NodeId; + type EdgeId = R::EdgeId; + type Weight = R::Weight; + fn source(&self) -> Self::NodeId { + self.0.target() + } + fn target(&self) -> Self::NodeId { + self.0.source() + } + fn weight(&self) -> &Self::Weight { + self.0.weight() + } + fn id(&self) -> Self::EdgeId { + self.0.id() + } +} + +impl<G> IntoEdgeReferences for Reversed<G> +where + G: IntoEdgeReferences, +{ + type EdgeRef = ReversedEdgeReference<G::EdgeRef>; + type EdgeReferences = ReversedEdgeReferences<G::EdgeReferences>; + fn edge_references(self) -> Self::EdgeReferences { + ReversedEdgeReferences { + iter: self.0.edge_references(), + } + } +} + +/// A reversed edge references iterator. +pub struct ReversedEdgeReferences<I> { + iter: I, +} + +impl<I> Iterator for ReversedEdgeReferences<I> +where + I: Iterator, + I::Item: EdgeRef, +{ + type Item = ReversedEdgeReference<I::Item>; + fn next(&mut self) -> Option<Self::Item> { + self.iter.next().map(ReversedEdgeReference) + } +} + +macro_rules! access0 { + ($e:expr) => { + $e.0 + }; +} + +NodeIndexable! {delegate_impl [[G], G, Reversed<G>, access0]} +NodeCompactIndexable! {delegate_impl [[G], G, Reversed<G>, access0]} +IntoNodeIdentifiers! {delegate_impl [[G], G, Reversed<G>, access0]} +IntoNodeReferences! {delegate_impl [[G], G, Reversed<G>, access0]} +GraphProp! {delegate_impl [[G], G, Reversed<G>, access0]} +NodeCount! {delegate_impl [[G], G, Reversed<G>, access0]} diff --git a/vendor/petgraph/src/visit/traversal.rs b/vendor/petgraph/src/visit/traversal.rs new file mode 100644 index 000000000..88782fa24 --- /dev/null +++ b/vendor/petgraph/src/visit/traversal.rs @@ -0,0 +1,519 @@ +use super::{GraphRef, IntoNodeIdentifiers, Reversed}; +use super::{IntoNeighbors, IntoNeighborsDirected, VisitMap, Visitable}; +use crate::Incoming; +use std::collections::VecDeque; + +/// Visit nodes of a graph in a depth-first-search (DFS) emitting nodes in +/// preorder (when they are first discovered). +/// +/// The traversal starts at a given node and only traverses nodes reachable +/// from it. +/// +/// `Dfs` is not recursive. +/// +/// `Dfs` does not itself borrow the graph, and because of this you can run +/// a traversal over a graph while still retaining mutable access to it, if you +/// use it like the following example: +/// +/// ``` +/// use petgraph::Graph; +/// use petgraph::visit::Dfs; +/// +/// let mut graph = Graph::<_,()>::new(); +/// let a = graph.add_node(0); +/// +/// let mut dfs = Dfs::new(&graph, a); +/// while let Some(nx) = dfs.next(&graph) { +/// // we can access `graph` mutably here still +/// graph[nx] += 1; +/// } +/// +/// assert_eq!(graph[a], 1); +/// ``` +/// +/// **Note:** The algorithm may not behave correctly if nodes are removed +/// during iteration. It may not necessarily visit added nodes or edges. +#[derive(Clone, Debug)] +pub struct Dfs<N, VM> { + /// The stack of nodes to visit + pub stack: Vec<N>, + /// The map of discovered nodes + pub discovered: VM, +} + +impl<N, VM> Default for Dfs<N, VM> +where + VM: Default, +{ + fn default() -> Self { + Dfs { + stack: Vec::new(), + discovered: VM::default(), + } + } +} + +impl<N, VM> Dfs<N, VM> +where + N: Copy + PartialEq, + VM: VisitMap<N>, +{ + /// Create a new **Dfs**, using the graph's visitor map, and put **start** + /// in the stack of nodes to visit. + pub fn new<G>(graph: G, start: N) -> Self + where + G: GraphRef + Visitable<NodeId = N, Map = VM>, + { + let mut dfs = Dfs::empty(graph); + dfs.move_to(start); + dfs + } + + /// Create a `Dfs` from a vector and a visit map + pub fn from_parts(stack: Vec<N>, discovered: VM) -> Self { + Dfs { stack, discovered } + } + + /// Clear the visit state + pub fn reset<G>(&mut self, graph: G) + where + G: GraphRef + Visitable<NodeId = N, Map = VM>, + { + graph.reset_map(&mut self.discovered); + self.stack.clear(); + } + + /// Create a new **Dfs** using the graph's visitor map, and no stack. + pub fn empty<G>(graph: G) -> Self + where + G: GraphRef + Visitable<NodeId = N, Map = VM>, + { + Dfs { + stack: Vec::new(), + discovered: graph.visit_map(), + } + } + + /// Keep the discovered map, but clear the visit stack and restart + /// the dfs from a particular node. + pub fn move_to(&mut self, start: N) { + self.stack.clear(); + self.stack.push(start); + } + + /// Return the next node in the dfs, or **None** if the traversal is done. + pub fn next<G>(&mut self, graph: G) -> Option<N> + where + G: IntoNeighbors<NodeId = N>, + { + while let Some(node) = self.stack.pop() { + if self.discovered.visit(node) { + for succ in graph.neighbors(node) { + if !self.discovered.is_visited(&succ) { + self.stack.push(succ); + } + } + return Some(node); + } + } + None + } +} + +/// Visit nodes in a depth-first-search (DFS) emitting nodes in postorder +/// (each node after all its descendants have been emitted). +/// +/// `DfsPostOrder` is not recursive. +/// +/// The traversal starts at a given node and only traverses nodes reachable +/// from it. +#[derive(Clone, Debug)] +pub struct DfsPostOrder<N, VM> { + /// The stack of nodes to visit + pub stack: Vec<N>, + /// The map of discovered nodes + pub discovered: VM, + /// The map of finished nodes + pub finished: VM, +} + +impl<N, VM> Default for DfsPostOrder<N, VM> +where + VM: Default, +{ + fn default() -> Self { + DfsPostOrder { + stack: Vec::new(), + discovered: VM::default(), + finished: VM::default(), + } + } +} + +impl<N, VM> DfsPostOrder<N, VM> +where + N: Copy + PartialEq, + VM: VisitMap<N>, +{ + /// Create a new `DfsPostOrder` using the graph's visitor map, and put + /// `start` in the stack of nodes to visit. + pub fn new<G>(graph: G, start: N) -> Self + where + G: GraphRef + Visitable<NodeId = N, Map = VM>, + { + let mut dfs = Self::empty(graph); + dfs.move_to(start); + dfs + } + + /// Create a new `DfsPostOrder` using the graph's visitor map, and no stack. + pub fn empty<G>(graph: G) -> Self + where + G: GraphRef + Visitable<NodeId = N, Map = VM>, + { + DfsPostOrder { + stack: Vec::new(), + discovered: graph.visit_map(), + finished: graph.visit_map(), + } + } + + /// Clear the visit state + pub fn reset<G>(&mut self, graph: G) + where + G: GraphRef + Visitable<NodeId = N, Map = VM>, + { + graph.reset_map(&mut self.discovered); + graph.reset_map(&mut self.finished); + self.stack.clear(); + } + + /// Keep the discovered and finished map, but clear the visit stack and restart + /// the dfs from a particular node. + pub fn move_to(&mut self, start: N) { + self.stack.clear(); + self.stack.push(start); + } + + /// Return the next node in the traversal, or `None` if the traversal is done. + pub fn next<G>(&mut self, graph: G) -> Option<N> + where + G: IntoNeighbors<NodeId = N>, + { + while let Some(&nx) = self.stack.last() { + if self.discovered.visit(nx) { + // First time visiting `nx`: Push neighbors, don't pop `nx` + for succ in graph.neighbors(nx) { + if !self.discovered.is_visited(&succ) { + self.stack.push(succ); + } + } + } else { + self.stack.pop(); + if self.finished.visit(nx) { + // Second time: All reachable nodes must have been finished + return Some(nx); + } + } + } + None + } +} + +/// A breadth first search (BFS) of a graph. +/// +/// The traversal starts at a given node and only traverses nodes reachable +/// from it. +/// +/// `Bfs` is not recursive. +/// +/// `Bfs` does not itself borrow the graph, and because of this you can run +/// a traversal over a graph while still retaining mutable access to it, if you +/// use it like the following example: +/// +/// ``` +/// use petgraph::Graph; +/// use petgraph::visit::Bfs; +/// +/// let mut graph = Graph::<_,()>::new(); +/// let a = graph.add_node(0); +/// +/// let mut bfs = Bfs::new(&graph, a); +/// while let Some(nx) = bfs.next(&graph) { +/// // we can access `graph` mutably here still +/// graph[nx] += 1; +/// } +/// +/// assert_eq!(graph[a], 1); +/// ``` +/// +/// **Note:** The algorithm may not behave correctly if nodes are removed +/// during iteration. It may not necessarily visit added nodes or edges. +#[derive(Clone)] +pub struct Bfs<N, VM> { + /// The queue of nodes to visit + pub stack: VecDeque<N>, + /// The map of discovered nodes + pub discovered: VM, +} + +impl<N, VM> Default for Bfs<N, VM> +where + VM: Default, +{ + fn default() -> Self { + Bfs { + stack: VecDeque::new(), + discovered: VM::default(), + } + } +} + +impl<N, VM> Bfs<N, VM> +where + N: Copy + PartialEq, + VM: VisitMap<N>, +{ + /// Create a new **Bfs**, using the graph's visitor map, and put **start** + /// in the stack of nodes to visit. + pub fn new<G>(graph: G, start: N) -> Self + where + G: GraphRef + Visitable<NodeId = N, Map = VM>, + { + let mut discovered = graph.visit_map(); + discovered.visit(start); + let mut stack = VecDeque::new(); + stack.push_front(start); + Bfs { stack, discovered } + } + + /// Return the next node in the bfs, or **None** if the traversal is done. + pub fn next<G>(&mut self, graph: G) -> Option<N> + where + G: IntoNeighbors<NodeId = N>, + { + if let Some(node) = self.stack.pop_front() { + for succ in graph.neighbors(node) { + if self.discovered.visit(succ) { + self.stack.push_back(succ); + } + } + + return Some(node); + } + None + } +} + +/// A topological order traversal for a graph. +/// +/// **Note** that `Topo` only visits nodes that are not part of cycles, +/// i.e. nodes in a true DAG. Use other visitors like `DfsPostOrder` or +/// algorithms like kosaraju_scc to handle graphs with possible cycles. +#[derive(Clone)] +pub struct Topo<N, VM> { + tovisit: Vec<N>, + ordered: VM, +} + +impl<N, VM> Default for Topo<N, VM> +where + VM: Default, +{ + fn default() -> Self { + Topo { + tovisit: Vec::new(), + ordered: VM::default(), + } + } +} + +impl<N, VM> Topo<N, VM> +where + N: Copy + PartialEq, + VM: VisitMap<N>, +{ + /// Create a new `Topo`, using the graph's visitor map, and put all + /// initial nodes in the to visit list. + pub fn new<G>(graph: G) -> Self + where + G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>, + { + let mut topo = Self::empty(graph); + topo.extend_with_initials(graph); + topo + } + + fn extend_with_initials<G>(&mut self, g: G) + where + G: IntoNodeIdentifiers + IntoNeighborsDirected<NodeId = N>, + { + // find all initial nodes (nodes without incoming edges) + self.tovisit.extend( + g.node_identifiers() + .filter(move |&a| g.neighbors_directed(a, Incoming).next().is_none()), + ); + } + + /* Private until it has a use */ + /// Create a new `Topo`, using the graph's visitor map with *no* starting + /// index specified. + fn empty<G>(graph: G) -> Self + where + G: GraphRef + Visitable<NodeId = N, Map = VM>, + { + Topo { + ordered: graph.visit_map(), + tovisit: Vec::new(), + } + } + + /// Clear visited state, and put all initial nodes in the to visit list. + pub fn reset<G>(&mut self, graph: G) + where + G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>, + { + graph.reset_map(&mut self.ordered); + self.tovisit.clear(); + self.extend_with_initials(graph); + } + + /// Return the next node in the current topological order traversal, or + /// `None` if the traversal is at the end. + /// + /// *Note:* The graph may not have a complete topological order, and the only + /// way to know is to run the whole traversal and make sure it visits every node. + pub fn next<G>(&mut self, g: G) -> Option<N> + where + G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>, + { + // Take an unvisited element and find which of its neighbors are next + while let Some(nix) = self.tovisit.pop() { + if self.ordered.is_visited(&nix) { + continue; + } + self.ordered.visit(nix); + for neigh in g.neighbors(nix) { + // Look at each neighbor, and those that only have incoming edges + // from the already ordered list, they are the next to visit. + if Reversed(g) + .neighbors(neigh) + .all(|b| self.ordered.is_visited(&b)) + { + self.tovisit.push(neigh); + } + } + return Some(nix); + } + None + } +} + +/// A walker is a traversal state, but where part of the traversal +/// information is supplied manually to each next call. +/// +/// This for example allows graph traversals that don't hold a borrow of the +/// graph they are traversing. +pub trait Walker<Context> { + type Item; + /// Advance to the next item + fn walk_next(&mut self, context: Context) -> Option<Self::Item>; + + /// Create an iterator out of the walker and given `context`. + fn iter(self, context: Context) -> WalkerIter<Self, Context> + where + Self: Sized, + Context: Clone, + { + WalkerIter { + walker: self, + context, + } + } +} + +/// A walker and its context wrapped into an iterator. +#[derive(Clone, Debug)] +pub struct WalkerIter<W, C> { + walker: W, + context: C, +} + +impl<W, C> WalkerIter<W, C> +where + W: Walker<C>, + C: Clone, +{ + pub fn context(&self) -> C { + self.context.clone() + } + + pub fn inner_ref(&self) -> &W { + &self.walker + } + + pub fn inner_mut(&mut self) -> &mut W { + &mut self.walker + } +} + +impl<W, C> Iterator for WalkerIter<W, C> +where + W: Walker<C>, + C: Clone, +{ + type Item = W::Item; + fn next(&mut self) -> Option<Self::Item> { + self.walker.walk_next(self.context.clone()) + } +} + +impl<'a, C, W: ?Sized> Walker<C> for &'a mut W +where + W: Walker<C>, +{ + type Item = W::Item; + fn walk_next(&mut self, context: C) -> Option<Self::Item> { + (**self).walk_next(context) + } +} + +impl<G> Walker<G> for Dfs<G::NodeId, G::Map> +where + G: IntoNeighbors + Visitable, +{ + type Item = G::NodeId; + fn walk_next(&mut self, context: G) -> Option<Self::Item> { + self.next(context) + } +} + +impl<G> Walker<G> for DfsPostOrder<G::NodeId, G::Map> +where + G: IntoNeighbors + Visitable, +{ + type Item = G::NodeId; + fn walk_next(&mut self, context: G) -> Option<Self::Item> { + self.next(context) + } +} + +impl<G> Walker<G> for Bfs<G::NodeId, G::Map> +where + G: IntoNeighbors + Visitable, +{ + type Item = G::NodeId; + fn walk_next(&mut self, context: G) -> Option<Self::Item> { + self.next(context) + } +} + +impl<G> Walker<G> for Topo<G::NodeId, G::Map> +where + G: IntoNeighborsDirected + Visitable, +{ + type Item = G::NodeId; + fn walk_next(&mut self, context: G) -> Option<Self::Item> { + self.next(context) + } +} |