1use params::*;
6use prelude::*;
7use props::{Color, IgnoreWriteProp};
8use traverse::*;
9
10use std::iter;
11
12pub trait Dfs: WithEdge {
13 fn dfs<V>(
14 &self,
15 vis: V,
16 ) -> DfsAlg<&Self, V, AllVertices<Self>, NewVertexProp<Self, Color>, Owned<DfsStack<Self>>>
17 where
18 V: Visitor<Self>,
19 {
20 DfsAlg(
21 self,
22 vis,
23 AllVertices(self),
24 NewVertexProp(self, Color::White),
25 Owned(DfsStack::<Self>::new()),
26 )
27 }
28}
29
30impl<G: WithEdge> Dfs for G {}
31
32generic_struct! {
33 #[must_use = "call .run() to execute the algorithm"]
34 pub struct DfsAlg(graph, visitor, roots, color, stack)
35}
36
37impl<'a, G, V, R, C, S> DfsAlg<&'a G, V, R, C, S> {
38 pub fn run(self) -> Control
39 where
40 G: Incidence,
41 V: Visitor<G>,
42 R: IntoIterator<Item = Vertex<G>>,
43 C: ParamDerefMut,
44 C::Target: VertexPropMut<G, Color>,
45 S: ParamDerefMut<Target = DfsStack<'a, G>>,
46 {
47 let DfsAlg(g, mut vis, roots, color, stack) = self;
48 return_unless!(vis.start(g));
49 let mut color = color.build();
50 let mut stack = stack.build();
51 for v in roots {
52 if color[v] == Color::White {
53 color[v] = Color::Gray;
54 stack.push((G::edge_none(), v, g.out_edges(v)));
55 return_unless!(vis.discover_root_vertex(g, v));
56 return_unless!(vis.discover_vertex(g, v));
57 return_unless!(dfs_visit(g, &mut *color, &mut *stack, &mut vis));
58 return_unless!(vis.finish_root_vertex(g, v));
59 }
60 }
61 vis.finish(g)
62 }
63
64 pub fn root(self, root: Vertex<G>) -> DfsAlg<&'a G, V, iter::Once<Vertex<G>>, C, S>
65 where
66 G: WithVertex,
67 {
68 self.roots(iter::once(root))
69 }
70
71 pub fn ignore_color_changes(self) -> DfsAlg<&'a G, V, R, Owned<IgnoreWriteProp<Color>>, S>
72 where
73 G: WithVertex,
74 {
75 let color = Owned(self.0.vertex_prop(Color::White));
76 self.color(color)
77 }
78}
79
80pub fn dfs_visit<'a, G, C, V>(
81 g: &'a G,
82 color: &mut C,
83 stack: &mut DfsStack<'a, G>,
84 vis: &mut V,
85) -> Control
86where
87 G: Incidence,
88 C: VertexPropMut<G, Color>,
89 V: Visitor<G>,
90{
91 'out: while let Some((from, u, mut inc)) = stack.pop() {
92 while let Some(e) = inc.next() {
93 let v = g.target(e);
94 if g.orientation(e).is_undirected() && color[v] == Color::Black
95 || G::edge_some(e) == from
96 {
97 continue;
98 }
99 return_unless!(vis.discover_edge(g, e));
100 match color[v] {
101 Color::White => {
102 color[v] = Color::Gray;
103 stack.push((from, u, inc));
104 stack.push((e.into(), v, g.out_edges(v)));
105 return_unless!(vis.discover_tree_edge(g, e));
106 return_unless!(vis.discover_vertex(g, v));
107 continue 'out;
108 }
109 Color::Gray => {
110 return_unless!(vis.discover_back_edge(g, e));
111 }
112 Color::Black => {
113 return_unless!(vis.discover_cross_or_forward_edge(g, e));
114 }
115 }
116 return_unless!(vis.finish_edge(g, e));
117 }
118 color[u] = Color::Black;
119 return_unless!(vis.finish_vertex(g, u));
120 if let Some(from) = from.into_option() {
121 return_unless!(vis.finish_tree_edge(g, from));
122 return_unless!(vis.finish_edge(g, from));
123 }
124 }
125 Control::Continue
126}
127
128pub type DfsStack<'a, G> = Vec<(OptionEdge<G>, Vertex<G>, OutEdgeIter<'a, G>)>;
129
130#[cfg(test)]
133mod tests {
134 use fera_fun::vec;
135 use prelude::*;
136 use traverse::TraverseEvent::*;
137 use traverse::*;
138
139 fn new() -> StaticGraph {
140 graph!(
146 7,
147 (0, 1),
148 (0, 2),
149 (1, 2),
150 (1, 3),
151 (2, 3),
152 (4, 5),
153 (4, 6),
154 (5, 6)
155 )
156 }
157
158 #[test]
159 fn events() {
160 let g = new();
161 let v = vec(g.vertices());
162 let e = |x: usize, y: usize| g.edge_by_ends(v[x], v[y]);
163 let expected = vec![
164 Start,
165 DiscoverRootVertex(0),
166 DiscoverVertex(0),
167 DiscoverEdge(e(0, 1)),
168 DiscoverTreeEdge(e(0, 1)),
169 DiscoverVertex(1),
170 DiscoverEdge(e(1, 2)),
171 DiscoverTreeEdge(e(1, 2)),
172 DiscoverVertex(2),
173 DiscoverEdge(e(2, 0)),
174 DiscoverBackEdge(e(2, 0)),
175 FinishEdge(e(2, 0)),
176 DiscoverEdge(e(2, 3)),
177 DiscoverTreeEdge(e(2, 3)),
178 DiscoverVertex(3),
179 DiscoverEdge(e(3, 1)),
180 DiscoverBackEdge(e(3, 1)),
181 FinishEdge(e(3, 1)),
182 FinishVertex(3),
183 FinishTreeEdge(e(2, 3)),
184 FinishEdge(e(2, 3)),
185 FinishVertex(2),
186 FinishTreeEdge(e(1, 2)),
187 FinishEdge(e(1, 2)),
188 FinishVertex(1),
189 FinishTreeEdge(e(0, 1)),
190 FinishEdge(e(0, 1)),
191 FinishVertex(0),
192 FinishRootVertex(0),
193 DiscoverRootVertex(4),
194 DiscoverVertex(4),
195 DiscoverEdge(e(4, 5)),
196 DiscoverTreeEdge(e(4, 5)),
197 DiscoverVertex(5),
198 DiscoverEdge(e(5, 6)),
199 DiscoverTreeEdge(e(5, 6)),
200 DiscoverVertex(6),
201 DiscoverEdge(e(6, 4)),
202 DiscoverBackEdge(e(6, 4)),
203 FinishEdge(e(6, 4)),
204 FinishVertex(6),
205 FinishTreeEdge(e(5, 6)),
206 FinishEdge(e(5, 6)),
207 FinishVertex(5),
208 FinishTreeEdge(e(4, 5)),
209 FinishEdge(e(4, 5)),
210 FinishVertex(4),
211 FinishRootVertex(4),
212 Finish,
213 ];
214
215 let mut v = vec![];
216 g.recursive_dfs(OnTraverseEvent(|evt| v.push(evt))).run();
217 assert_eq!(expected, v);
218
219 v.clear();
220 g.dfs(OnTraverseEvent(|evt| v.push(evt))).run();
221 assert_eq!(expected, v);
222 }
223}