1use alloc::vec::Vec;
18
19pub struct Node<V> {
21 pub value: V,
23 pub children: Vec<usize>, pub parents: Vec<usize>, }
28
29pub struct Dag<V> {
31 nodes: Vec<Node<V>>,
32}
33
34impl<V> Default for Dag<V> {
35 fn default() -> Self {
36 Self { nodes: Vec::new() }
37 }
38}
39
40impl<V> Dag<V> {
41 pub fn new() -> Self {
43 Self::default()
44 }
45
46 pub fn add_node(&mut self, value: V) -> usize {
48 let idx = self.nodes.len();
49 self.nodes.push(Node {
50 value,
51 children: Vec::new(),
52 parents: Vec::new(),
53 });
54 idx
55 }
56
57 pub fn add_edge(&mut self, from: usize, to: usize) {
61 assert!(from != to, "self-loop detected");
62 assert!(
63 from < self.nodes.len() && to < self.nodes.len(),
64 "invalid node index"
65 );
66 if !self.nodes[from].children.contains(&to) {
68 self.nodes[from].children.push(to);
69 }
70 if !self.nodes[to].parents.contains(&from) {
71 self.nodes[to].parents.push(from);
72 }
73 }
75
76 pub fn node(&self, idx: usize) -> &Node<V> {
78 &self.nodes[idx]
79 }
80
81 pub fn node_mut(&mut self, idx: usize) -> &mut Node<V> {
83 &mut self.nodes[idx]
84 }
85
86 pub fn len(&self) -> usize {
88 self.nodes.len()
89 }
90
91 pub fn is_empty(&self) -> bool {
93 self.nodes.is_empty()
94 }
95
96 pub fn topological_sort(&self) -> Vec<usize> {
99 let mut in_degree = alloc::vec![0; self.nodes.len()];
100 for node in &self.nodes {
101 for &child in &node.children {
102 in_degree[child] += 1;
103 }
104 }
105
106 let mut stack = Vec::new();
107 for (i, °) in in_degree.iter().enumerate() {
108 if deg == 0 {
109 stack.push(i);
110 }
111 }
112
113 let mut order = Vec::with_capacity(self.nodes.len());
114 let mut remaining_in_degree = in_degree.clone();
115
116 while let Some(n) = stack.pop() {
117 order.push(n);
118 for &child in &self.nodes[n].children {
119 remaining_in_degree[child] -= 1;
120 if remaining_in_degree[child] == 0 {
121 stack.push(child);
122 }
123 }
124 }
125
126 assert!(
127 order.len() == self.nodes.len(),
128 "cycle detected in DAG (not acyclic)"
129 );
130 order
131 }
132}
133
134impl<V> IntoIterator for Dag<V> {
135 type Item = Node<V>;
136 type IntoIter = alloc::vec::IntoIter<Node<V>>;
137
138 fn into_iter(self) -> Self::IntoIter {
139 self.nodes.into_iter()
140 }
141}
142
143#[cfg(test)]
144mod tests {
145 use alloc::vec;
146
147 use super::*;
148
149 #[test]
150 fn test_empty_dag() {
151 let dag: Dag<i32> = Dag { nodes: Vec::new() };
152 assert_eq!(dag.len(), 0);
153 assert!(dag.is_empty());
154 assert_eq!(dag.topological_sort(), Vec::<usize>::new());
155 }
156
157 #[test]
158 fn test_single_node() {
159 let node = Node {
160 value: 42,
161 parents: Vec::new(),
162 children: Vec::new(),
163 };
164 let dag = Dag { nodes: vec![node] };
165 assert_eq!(dag.len(), 1);
166 assert!(!dag.is_empty());
167 assert_eq!(dag.topological_sort(), vec![0]);
168 }
169
170 #[test]
171 fn test_chain() {
172 let n2 = Node {
174 value: 2,
175 children: Vec::new(),
176 parents: Vec::new(),
177 };
178 let n1 = Node {
179 value: 1,
180 children: vec![2],
181 parents: Vec::new(),
182 };
183 let n0 = Node {
184 value: 0,
185 children: vec![1],
186 parents: Vec::new(),
187 };
188 let dag = Dag {
189 nodes: vec![n0, n1, n2],
190 };
191 let order = dag.topological_sort();
192 assert_eq!(order, vec![0, 1, 2]);
194 }
195
196 #[test]
197 fn test_branch() {
198 let n3 = Node {
204 value: 3,
205 children: Vec::new(),
206 parents: Vec::new(),
207 };
208 let n2 = Node {
209 value: 2,
210 children: vec![3],
211 parents: Vec::new(),
212 };
213 let n1 = Node {
214 value: 1,
215 children: vec![3],
216 parents: Vec::new(),
217 };
218 let n0 = Node {
219 value: 0,
220 children: vec![1, 2],
221 parents: Vec::new(),
222 };
223 let dag = Dag {
224 nodes: vec![n0, n1, n2, n3],
225 };
226 let order = dag.topological_sort();
227 let pos = |n| order.iter().position(|&x| x == n).unwrap();
229 assert!(pos(0) < pos(1) && pos(0) < pos(2));
230 assert!(pos(1) < pos(3));
231 assert!(pos(2) < pos(3));
232 }
233
234 #[test]
235 #[should_panic(expected = "cycle detected in DAG")]
236 fn test_cycle_panics() {
237 let n0 = Node {
239 value: 0,
240 children: vec![1],
241 parents: Vec::new(),
242 };
243 let n1 = Node {
244 value: 1,
245 children: vec![2],
246 parents: Vec::new(),
247 };
248 let n2 = Node {
249 value: 2,
250 children: vec![0],
251 parents: Vec::new(),
252 };
253 let dag = Dag {
254 nodes: vec![n0, n1, n2],
255 };
256 let _ = dag.topological_sort(); }
258}