github.com/charypar/monobuild@v0.0.0-20211122220434-fd884ed50212/rs/src/graph/mod.rs (about) 1 use std::collections::{BTreeMap, BTreeSet}; 2 3 mod debug; 4 mod iter; 5 mod partial_eq; 6 7 use self::iter::{GraphIter, Vertices}; 8 9 pub trait Vertex: PartialEq + Clone {} 10 impl<T> Vertex for T where T: PartialEq + Clone {} 11 pub trait Edge: PartialEq + Ord + Copy {} 12 impl<T> Edge for T where T: PartialEq + Ord + Copy {} 13 14 pub struct Graph<V, E> 15 where 16 V: Vertex, 17 E: Edge, 18 { 19 vertices: Vec<V>, // vertex index -> V 20 edges: Vec<BTreeSet<(usize, E)>>, // vertex index -> {(vertex index, E)} 21 } 22 23 impl<V, E> Graph<V, E> 24 where 25 V: Vertex, 26 E: Edge, 27 { 28 pub fn new() -> Self { 29 Graph { 30 vertices: vec![], 31 edges: vec![], 32 } 33 } 34 35 // Iterate over graph or vertices 36 37 pub fn vertices<'g>(&'g self) -> Vertices<'g, '_, V> { 38 Vertices { 39 iter: self.vertices.iter().enumerate(), 40 mask: None, 41 } 42 } 43 44 pub fn iter<'g>(&'g self) -> GraphIter<'g, '_, V, E> { 45 GraphIter { 46 graph: self, 47 iter: self.vertices.iter().enumerate(), 48 masks: None, 49 } 50 } 51 52 // Scope graph 53 54 pub fn roots<'g>(&'g self) -> Subgraph<'g, V, E> { 55 let mut vertex_mask: Vec<_> = std::iter::repeat(true).take(self.vertices.len()).collect(); 56 57 // Remove all vertices with an incoming edge 58 for edgs in &self.edges { 59 for (to, _) in edgs { 60 vertex_mask[*to] = false; 61 } 62 } 63 64 // Remove edges using the mask we just made 65 let edge_mask = (0..self.vertices.len()) 66 .flat_map(|from| { 67 self.edges 68 .get(from) 69 .expect("edges to exist") 70 .iter() 71 .map(move |(to, _)| (from, *to)) 72 }) 73 .filter(|(from, to)| vertex_mask[*from] && vertex_mask[*to]) 74 .collect(); 75 76 Subgraph { 77 graph: self, 78 vertex_mask, 79 edge_mask, 80 } 81 } 82 83 // Removes vertices and associated edges 84 pub fn filter_vertices<'g, P>(&'g self, predicate: P) -> Subgraph<'g, V, E> 85 where 86 P: Fn(&V) -> bool, 87 { 88 // Remove vertices 89 let vertex_mask: Vec<bool> = self.vertices.iter().map(|v| predicate(v)).collect(); 90 91 // Remove edges using the mask we just made 92 let edge_mask = (0..self.vertices.len()) 93 .flat_map(|from| { 94 self.edges 95 .get(from) 96 .expect("edges to exist") 97 .iter() 98 .map(move |(to, _)| (from, *to)) 99 }) 100 .filter(|(from, to)| vertex_mask[*from] && vertex_mask[*to]) 101 .collect(); 102 103 Subgraph { 104 graph: self, 105 vertex_mask, 106 edge_mask, 107 } 108 } 109 110 // Removes edges but keeps vertices alone 111 pub fn filter_edges<'g, P>(&'g self, predicate: P) -> Subgraph<'g, V, E> 112 where 113 P: Fn(&E) -> bool, 114 { 115 let vertex_mask = std::iter::repeat(true).take(self.vertices.len()).collect(); 116 let edge_mask = (0..self.vertices.len()) 117 .flat_map(|from| { 118 self.edges 119 .get(from) 120 .expect("edges to exist") 121 .iter() 122 .map(move |(to, label)| (from, *to, label)) 123 }) 124 .filter_map(|(from, to, label)| { 125 if predicate(label) { 126 Some((from, to)) 127 } else { 128 None 129 } 130 }) 131 .collect(); 132 133 Subgraph { 134 graph: self, 135 vertex_mask, 136 edge_mask, 137 } 138 } 139 140 // Transform graph 141 142 pub fn reverse(&self) -> Self { 143 let vertices = self.vertices.clone(); 144 let mut edges: Vec<_> = std::iter::repeat_with(|| BTreeSet::new()) 145 .take(vertices.len()) 146 .collect(); 147 148 for (to, edgs) in self.edges.iter().enumerate() { 149 for (from, label) in edgs { 150 edges[*from].insert((to, *label)); 151 } 152 } 153 154 Graph { vertices, edges } 155 } 156 } 157 158 // Construct a graph from adjacency list 159 impl<Adj, Edg, V, E> From<Adj> for Graph<V, E> 160 where 161 Adj: IntoIterator<Item = (V, Edg)>, 162 Edg: IntoIterator<Item = (V, E)>, 163 V: Vertex + Ord, 164 E: Edge, 165 { 166 fn from(graph: Adj) -> Self { 167 // Make a local copy to allow multiple passes 168 let graph: Vec<(V, BTreeSet<_>)> = graph 169 .into_iter() 170 .map(|(v, es)| (v, es.into_iter().collect())) 171 .collect(); 172 173 // Find and insert all the vertices, sorted using Ord 174 let mut vertices: BTreeSet<V> = BTreeSet::new(); 175 for (from, edg) in &graph { 176 vertices.insert(from.clone()); 177 178 for (to, _) in edg.into_iter() { 179 vertices.insert(to.clone()); 180 } 181 } 182 183 // Index and reverse index them 184 let vertices: Vec<_> = vertices.into_iter().collect(); 185 let vertex_index: BTreeMap<V, usize> = vertices 186 .iter() 187 .enumerate() 188 .map(|(i, v)| (v.clone(), i)) 189 .collect(); 190 191 // Allocate edge mapping 192 let mut edges: Vec<_> = std::iter::repeat_with(|| BTreeSet::new()) 193 .take(vertices.len()) 194 .collect(); 195 196 // Insert all the edges 197 for (from, edg) in graph { 198 let from_idx = *vertex_index.get(&from).expect("a vertex to exist"); 199 let edges_from = edges.get_mut(from_idx).expect("an edge set to exist"); 200 201 for (to, label) in edg { 202 let to_idx = *vertex_index.get(&to).expect("a vertex to exist"); 203 204 edges_from.insert((to_idx, label)); 205 } 206 } 207 208 Graph { vertices, edges } 209 } 210 } 211 212 pub struct Subgraph<'g, V, E> 213 where 214 V: Vertex + 'g, 215 E: Edge, 216 { 217 graph: &'g Graph<V, E>, 218 vertex_mask: Vec<bool>, 219 edge_mask: BTreeSet<(usize, usize)>, 220 } 221 222 impl<'g, V, E> Subgraph<'g, V, E> 223 where 224 V: Vertex + 'g, 225 E: Edge, 226 { 227 // Inspect graph 228 229 pub fn iter<'s>(&'s self) -> GraphIter<'g, 's, V, E> { 230 GraphIter { 231 graph: self.graph, 232 iter: self.graph.vertices.iter().enumerate(), 233 masks: Some((&self.vertex_mask, &self.edge_mask)), 234 } 235 } 236 237 pub fn vertices<'s>(&'s self) -> Vertices<'g, 's, V> { 238 Vertices { 239 iter: self.graph.vertices.iter().enumerate(), 240 mask: Some(&self.vertex_mask), 241 } 242 } 243 244 pub fn roots(&self) -> Subgraph<'g, V, E> { 245 let mut vertex_mask: Vec<_> = self.vertex_mask.clone(); 246 247 // Remove all vertices with an incoming edge 248 for (from, edgs) in self.graph.edges.iter().enumerate() { 249 for (to, _) in edgs { 250 if self.edge_mask.contains(&(from, *to)) { 251 vertex_mask[*to] = false; 252 } 253 } 254 } 255 256 // Remove edges using the mask we just made, respecting the original edge mask 257 let edge_mask = (0..self.graph.vertices.len()) 258 .flat_map(|from| { 259 self.graph 260 .edges 261 .get(from) 262 .expect("edges to exist") 263 .iter() 264 .map(move |(to, _)| (from, *to)) 265 }) 266 .filter(|(from, to)| { 267 vertex_mask[*from] && vertex_mask[*to] && self.edge_mask.contains(&(*from, *to)) 268 }) 269 .collect(); 270 271 Subgraph { 272 graph: self.graph, 273 vertex_mask, 274 edge_mask, 275 } 276 } 277 278 // Removes vertices and associated edges 279 pub fn filter_vertices<P>(&self, predicate: P) -> Subgraph<'g, V, E> 280 where 281 P: Fn(&V) -> bool, 282 { 283 // Remove vertices 284 let vertex_mask: Vec<bool> = self 285 .graph 286 .vertices 287 .iter() 288 .enumerate() 289 .map(|(i, v)| self.vertex_mask[i] && predicate(v)) 290 .collect(); 291 292 // Remove edges using the mask we just made 293 let edge_mask = self 294 .graph 295 .vertices 296 .iter() 297 .enumerate() 298 .flat_map(|(from, _)| { 299 self.graph 300 .edges 301 .get(from) 302 .expect("edges to exist") 303 .iter() 304 .map(move |(to, _)| (from, *to)) 305 }) 306 .filter(|(from, to)| { 307 vertex_mask[*from] && vertex_mask[*to] && self.edge_mask.contains(&(*from, *to)) 308 }) 309 .collect(); 310 311 Subgraph { 312 graph: self.graph, 313 vertex_mask, 314 edge_mask, 315 } 316 } 317 318 // Removes edges but keeps vertices alone 319 pub fn filter_edges<P>(&self, predicate: P) -> Subgraph<'g, V, E> 320 where 321 P: Fn(&E) -> bool, 322 { 323 let edge_mask = (0..self.vertex_mask.len()) 324 .flat_map(|from| { 325 self.graph 326 .edges 327 .get(from) 328 .expect("edges to exist") 329 .iter() 330 .map(move |(to, label)| (from, *to, label)) 331 }) 332 .filter_map(|(from, to, label)| { 333 if predicate(label) && self.edge_mask.contains(&(from, to)) { 334 Some((from, to)) 335 } else { 336 None 337 } 338 }) 339 .collect(); 340 341 Subgraph { 342 graph: self.graph, 343 vertex_mask: self.vertex_mask.clone(), 344 edge_mask, 345 } 346 } 347 348 // Expand subgraph along original edges, applying a predicate to decide whether to follow an edge 349 pub fn expand_via<P>(&self, predicate: P) -> Subgraph<'g, V, E> 350 where 351 P: Fn(&E) -> bool, 352 { 353 let mut vertex_mask = self.vertex_mask.clone(); 354 let mut edge_mask = self.edge_mask.clone(); 355 356 // front is the set of vertices we're attempting to expand the graph from 357 // via edges that are *not* in the edge mask (because those are already included) 358 // and that pass the predicate test 359 let mut front: Vec<usize> = vertex_mask 360 .iter() 361 .enumerate() 362 .filter_map(|(idx, inc)| if *inc { Some(idx) } else { None }) 363 .collect(); 364 365 while front.len() > 0 { 366 front = front 367 .iter() 368 .flat_map(|from| { 369 let edges = self.graph.edges.get(*from).expect("edges to exist"); 370 371 edges.iter().map(move |(to, label)| (*from, *to, label)) 372 }) 373 .filter_map(|(from, to, label)| { 374 if !self.edge_mask.contains(&(from, to)) && predicate(label) { 375 // expand the graph 376 vertex_mask[to] = true; 377 edge_mask.insert((from, to)); 378 379 // and add the destination vertec to the next iteration front 380 Some(to) 381 } else { 382 None 383 } 384 }) 385 .collect::<Vec<_>>(); 386 } 387 388 Subgraph { 389 graph: self.graph, 390 vertex_mask, 391 edge_mask, 392 } 393 } 394 395 pub fn expand(&self) -> Self { 396 self.expand_via(|_| true) 397 } 398 } 399 400 #[cfg(test)] 401 mod test { 402 use super::*; 403 404 #[test] 405 fn new_normalizes_graph() { 406 let graph = Graph::<usize, usize>::from([(1, [(2, 0), (3, 0)])]); 407 408 let expected = vec![1, 2, 3]; 409 let actual = graph.vertices().cloned().collect::<Vec<_>>(); 410 411 assert_eq!(actual, expected); 412 } 413 414 mod filter { 415 use super::super::*; 416 417 #[test] 418 fn filters_an_empty_graph() { 419 let graph = Graph::<usize, usize>::new(); 420 421 let expected = Graph::<usize, usize>::new(); 422 let actual_v = graph.filter_vertices(|_v| true); 423 let actual_e = graph.filter_edges(|_e| true); 424 425 assert_eq!(actual_v, expected); 426 assert_eq!(actual_e, expected); 427 } 428 429 #[test] 430 fn filters_a_vertex_from_a_graph() { 431 let graph = Graph::from([(1, [(2, 0), (3, 0)])]); 432 433 let expected = Graph::from([(1, [(3, 0)])]); 434 let actual = graph.filter_vertices(|v| *v != 2); 435 436 assert_eq!(actual, expected); 437 } 438 439 #[test] 440 fn filters_an_edge_from_a_graph() { 441 let graph = Graph::from([(1, vec![(2, 0), (3, 1)]), (2, vec![(3, 0)])]); 442 443 let expected = Graph::from([(1, [(2, 0)]), (2, [(3, 0)])]); 444 let actual = graph.filter_edges(|e| *e != 1); 445 446 assert_eq!(actual, expected); 447 } 448 449 #[test] 450 fn filters_a_vertex_from_a_subgraph() { 451 let graph = Graph::from([(1, [(2, 0), (3, 0)])]); 452 453 let expected = Graph::from([(1, [])]); 454 let actual = graph 455 .filter_vertices(|v| *v != 2) 456 .filter_vertices(|v| *v != 3); 457 458 assert_eq!(actual, expected); 459 } 460 461 #[test] 462 fn filters_an_edge_from_a_subgraph() { 463 let graph = Graph::from([(1, vec![(2, 0), (3, 1)]), (2, vec![(3, 0), (1, 2)])]); 464 465 let expected = Graph::from([(1, [(2, 0)]), (2, [(3, 0)])]); 466 let actual = graph.filter_edges(|e| *e != 1).filter_edges(|e| *e != 2); 467 468 assert_eq!(actual, expected); 469 } 470 471 #[test] 472 fn filters_an_edge_from_a_vertex_filtered_subgraph() { 473 let graph = Graph::from([(1, vec![(2, 0), (3, 1)]), (2, vec![(3, 0), (1, 2)])]); 474 475 let expected = Graph::from([(1, vec![(2, 0)]), (2, vec![])]); 476 let actual = graph.filter_vertices(|v| *v != 3).filter_edges(|e| *e != 2); 477 478 assert_eq!(actual, expected); 479 } 480 } 481 482 mod expand { 483 use super::super::*; 484 485 #[test] 486 fn empty_graph() { 487 let graph = Graph::<usize, usize>::new(); 488 489 let actual = graph.filter_vertices(|v| *v == 1).expand(); 490 let expected = Graph::<usize, usize>::new(); 491 492 assert_eq!(actual, expected); 493 } 494 495 #[test] 496 fn single_vertex_graph() { 497 let graph = Graph::<_, usize>::from([(1, [])]); 498 499 let actual = graph.filter_vertices(|v| *v == 1).expand(); 500 let expected = Graph::<_, usize>::from([(1, [])]); 501 502 assert_eq!(actual, expected); 503 } 504 505 #[test] 506 fn single_child_of_one_vertex() { 507 let graph = Graph::from([(1, [(2, 0)]), (3, [(2, 0)])]); 508 509 let actual = graph.filter_vertices(|v| *v == 1).expand(); 510 let expected = Graph::from([(1, [(2, 0)])]); 511 512 assert_eq!(actual, expected); 513 } 514 515 #[test] 516 fn multiple_children_of_one_vertex() { 517 let graph = Graph::from([(1, [(2, 0), (3, 0)])]); 518 519 let actual = &graph.filter_vertices(|v| *v == 1).expand(); 520 let expected = &graph; 521 522 assert_eq!(actual, expected); 523 } 524 525 #[test] 526 fn all_descendants_of_one_vertex() { 527 let graph = Graph::from([(1, [(2, 0), (3, 0)]), (2, [(3, 0), (4, 0)])]); 528 529 let actual = &graph.filter_vertices(|v| *v == 1).expand(); 530 let expected = &graph; 531 532 assert_eq!(actual, expected); 533 } 534 535 #[test] 536 fn all_descendants_of_multiple_vertices() { 537 let graph = Graph::from([ 538 (1, vec![(4, 0), (5, 0)]), 539 (2, vec![(6, 0)]), 540 (3, vec![(8, 0), (9, 0)]), 541 (4, vec![(7, 0)]), 542 (7, vec![(8, 0)]), 543 (8, vec![(5, 0)]), 544 ]); 545 546 let actual = graph.filter_vertices(|v| *v == 1 || *v == 2).expand(); 547 let expected = Graph::from([ 548 (1, vec![(4, 0), (5, 0)]), 549 (2, vec![(6, 0)]), 550 (4, vec![(7, 0)]), 551 (7, vec![(8, 0)]), 552 (8, vec![(5, 0)]), 553 ]); 554 555 assert_eq!(actual, expected); 556 } 557 558 #[test] 559 fn all_descendants_via_edges_of_a_color() { 560 let graph = Graph::from([ 561 (1, vec![(4, 1), (5, 0)]), 562 (2, vec![(6, 1)]), 563 (3, vec![(8, 0), (9, 0)]), 564 (4, vec![(7, 1)]), 565 (7, vec![(8, 0)]), 566 (8, vec![(5, 0)]), 567 ]); 568 569 let actual = graph 570 .filter_vertices(|v| *v == 1 || *v == 2 || *v == 5) 571 .expand_via(|e| *e == 1); 572 let expected = Graph::from([ 573 (1, vec![(4, 1), (5, 0)]), 574 (2, vec![(6, 1)]), 575 (4, vec![(7, 1)]), 576 (5, vec![]), 577 (7, vec![]), 578 ]); 579 580 assert_eq!(actual, expected); 581 } 582 } 583 584 mod reverse { 585 use super::super::*; 586 587 #[test] 588 fn reverses_empty_graph() { 589 let graph = Graph::<usize, usize>::new(); 590 591 let expected = Graph::<usize, usize>::new(); 592 let actual = graph.reverse(); 593 594 assert_eq!(actual, expected); 595 } 596 597 #[test] 598 fn reverses_single_edge() { 599 let graph = Graph::<usize, usize>::from([(1, [(2, 0)])]); 600 601 let expected = Graph::<usize, usize>::from([(2, [(1, 0)])]); 602 let actual = graph.reverse(); 603 604 assert_eq!(actual, expected); 605 } 606 607 #[test] 608 fn reverses_a_fan() { 609 let graph = Graph::<usize, usize>::from([(1, [(2, 0), (3, 1), (4, 0)])]); 610 611 let expected = 612 Graph::<usize, usize>::from([(2, [(1, 0)]), (3, [(1, 1)]), (4, [(1, 0)])]); 613 let actual = graph.reverse(); 614 615 assert_eq!(actual, expected); 616 } 617 618 #[test] 619 fn reverses_a_complex_graph() { 620 let graph = Graph::<usize, usize>::from([ 621 (1, vec![(2, 0), (3, 1)]), 622 (2, vec![(3, 0)]), 623 (3, vec![(4, 0)]), 624 ]); 625 626 let expected = Graph::<usize, usize>::from([ 627 (2, vec![(1, 0)]), 628 (3, vec![(1, 1), (2, 0)]), 629 (4, vec![(3, 0)]), 630 ]); 631 let actual = graph.reverse(); 632 633 assert_eq!(actual, expected); 634 } 635 } 636 637 mod roots { 638 use super::super::*; 639 640 #[test] 641 fn of_an_empty_graph() { 642 let graph = Graph::<usize, usize>::new(); 643 644 let actual = graph.roots(); 645 let expected = Graph::<usize, usize>::new(); 646 647 assert_eq!(actual, expected); 648 } 649 650 #[test] 651 fn of_a_single_edge() { 652 let graph = Graph::from([(1, [(2, 0)])]); 653 654 let actual = graph.roots(); 655 let expected = Graph::from([(1, [])]); 656 657 assert_eq!(actual, expected); 658 } 659 660 #[test] 661 fn of_a_complex_graph() { 662 let graph = Graph::from([ 663 (1, vec![(2, 0), (3, 0)]), 664 (2, vec![(3, 0)]), 665 (4, vec![(5, 0)]), 666 (5, vec![(6, 0)]), 667 (7, vec![(2, 0)]), 668 ]); 669 670 let actual = graph.roots(); 671 let expected = Graph::from([(1, vec![]), (4, vec![]), (7, vec![])]); 672 673 assert_eq!(actual, expected); 674 } 675 676 #[test] 677 fn of_a_subgraph() { 678 let graph = Graph::from([ 679 (1, vec![(2, 0), (3, 1)]), 680 (2, vec![(3, 1)]), 681 (4, vec![(5, 0)]), 682 (5, vec![(6, 0)]), 683 (7, vec![(2, 0)]), 684 ]); 685 686 let actual = graph 687 .filter_edges(|e| *e != 1) 688 .filter_vertices(|v| *v != 7) 689 .roots(); 690 let expected = Graph::from([(1, vec![]), (3, vec![]), (4, vec![])]); 691 692 assert_eq!(actual, expected); 693 } 694 } 695 }