1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use prelude::*;
use props::Color;
use traverse::*;
pub trait Cycles: Incidence {
fn is_acyclic(&self) -> bool
where
Self: VertexList + WithVertexProp<Color>,
{
let mut acyclic = true;
self.dfs(IsAcyclic(&mut acyclic)).run();
acyclic
}
fn is_dag(&self) -> bool
where
Self: VertexList + WithVertexProp<Color>,
{
let mut dag = true;
self.dfs(IsDag(&mut dag)).run();
dag
}
}
impl<G: Incidence> Cycles for G {}
pub struct IsAcyclic<'a>(pub &'a mut bool);
impl<'a, G: WithEdge> Visitor<G> for IsAcyclic<'a> {
fn start(&mut self, _g: &G) -> Control {
*self.0 = true;
Control::Continue
}
fn discover_back_edge(&mut self, _g: &G, _e: Edge<G>) -> Control {
*self.0 = false;
Control::Break
}
}
pub struct IsDag<'a>(pub &'a mut bool);
impl<'a, G: WithEdge> Visitor<G> for IsDag<'a> {
fn start(&mut self, _g: &G) -> Control {
*self.0 = true;
Control::Continue
}
fn discover_edge(&mut self, g: &G, e: Edge<G>) -> Control {
*self.0 &= g.orientation(e).is_directed();
continue_if(*self.0)
}
fn discover_back_edge(&mut self, _g: &G, _e: Edge<G>) -> Control {
*self.0 = false;
Control::Break
}
}