1use params::IntoOwned;
8use prelude::*;
9use props::Color;
10use traverse::*;
11
12pub trait Paths: Incidence {
13 fn find_path(&self, u: Vertex<Self>, v: Vertex<Self>) -> Option<Vec<Edge<Self>>>
14 where
15 Self: WithVertexProp<Color>,
16 {
17 if u == v {
18 return None;
19 }
20 let mut path = vec![];
21 self.dfs(RecordPath(&mut path, v)).root(u).run();
22 if path.is_empty() {
23 None
24 } else {
25 Some(path)
26 }
27 }
28
29 fn is_walk<I>(&self, edges: I) -> bool
30 where
31 I: IntoIterator,
32 I::Item: IntoOwned<Edge<Self>>,
33 {
34 let mut edges = edges.into_iter();
35 let mut last = if let Some(e) = edges.next() {
36 self.target(e.into_owned())
37 } else {
38 return true;
39 };
40
41 edges.all(|e| {
42 let (u, v) = self.ends(e.into_owned());
43 if last == u {
44 last = v;
45 true
46 } else {
47 false
48 }
49 })
50 }
51
52 fn is_path<I>(&self, edges: I) -> bool
53 where
54 Self: WithVertexProp<bool>,
55 I: IntoIterator,
56 I::Item: IntoOwned<Edge<Self>>,
57 {
58 let mut visited = self.default_vertex_prop(false);
59 let mut edges = edges.into_iter();
60
61 let mut last = if let Some(e) = edges.next() {
62 let (u, v) = self.ends(e.into_owned());
63 if u == v {
64 return false;
65 }
66 visited[u] = true;
67 visited[v] = true;
68 v
69 } else {
70 return true;
71 };
72
73 edges.all(|e| {
74 let (u, v) = self.ends(e.into_owned());
75
76 if last != u || visited[v] {
77 false
78 } else {
79 visited[v] = true;
80 last = v;
81 true
82 }
83 })
84 }
85}
86
87impl<G> Paths for G
88where
89 G: Incidence,
90{
91}
92
93pub struct RecordPath<'a, G: WithEdge> {
94 path: &'a mut Vec<Edge<G>>,
95 target: Vertex<G>,
96}
97
98#[allow(non_snake_case)]
99pub fn RecordPath<G>(path: &mut Vec<Edge<G>>, target: Vertex<G>) -> RecordPath<G>
100where
101 G: WithEdge,
102{
103 RecordPath {
104 path: path,
105 target: target,
106 }
107}
108
109impl<'a, G: WithEdge> Visitor<G> for RecordPath<'a, G> {
110 fn discover_tree_edge(&mut self, g: &G, e: Edge<G>) -> Control {
111 self.path.push(e);
112 break_if(g.target(e) == self.target)
113 }
114
115 fn finish_tree_edge(&mut self, _g: &G, e: Edge<G>) -> Control {
116 let r = self.path.pop();
117 debug_assert_eq!(Some(e), r);
118 Control::Continue
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::Paths;
125 use fera_fun::vec;
126 use prelude::*;
127
128 #[test]
129 fn find_path() {
130 let g: StaticGraph = graph!(6, (0, 1), (0, 2), (1, 4), (2, 3), (2, 4));
131 let e = vec(g.edges());
132
133 assert_eq!(None, g.find_path(0, 0));
134
135 assert_eq!(None, g.find_path(0, 5));
136
137 assert_eq!(vec![e[0]], g.find_path(0, 1).unwrap());
138
139 assert_eq!(vec![e[0], e[1], e[4]], g.find_path(1, 4).unwrap());
140 }
141}