1use super::hanan_grid::UnitHananGrid;
8use super::iterator_set_operations::{intersection, symmetric_difference};
9use super::marker_types::*;
10use super::rectangle::Rect;
11use super::wirelength_vector::*;
12use super::{HananCoord, Point};
13
14use std::collections::HashSet;
15use std::marker::PhantomData;
16
17use bitvec::prelude::BitVec;
18use itertools::Itertools;
19use std::cmp::Ordering;
20use std::hash::{Hash, Hasher};
21
22#[derive(Clone, Debug)]
35pub struct Tree<C: CanonicalMarker = NonCanonical> {
36 edges: Vec<TreeEdge>,
37 _is_canonical: PhantomData<C>,
38}
39
40impl PartialEq for Tree<Canonical> {
41 fn eq(&self, other: &Self) -> bool {
42 self.edges.eq(&other.edges)
43 }
44}
45
46impl Eq for Tree<Canonical> {}
47
48impl PartialOrd for Tree<Canonical> {
49 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
50 self.edges.partial_cmp(&other.edges)
51 }
52}
53
54impl Ord for Tree<Canonical> {
55 fn cmp(&self, other: &Self) -> Ordering {
56 self.edges.cmp(&other.edges)
57 }
58}
59
60impl Hash for Tree<Canonical> {
61 fn hash<H: Hasher>(&self, state: &mut H) {
62 self.edges.hash(state)
63 }
64}
65
66impl Tree {
67 pub fn empty_non_canonical() -> Self {
69 Self {
70 edges: Default::default(),
71 _is_canonical: Default::default(),
72 }
73 }
74}
75
76impl Tree<Canonical> {
77 pub fn empty_canonical() -> Self {
79 Self {
80 edges: Default::default(),
81 _is_canonical: Default::default(),
82 }
83 }
84
85 pub fn from_edges(mut edges: Vec<TreeEdge>) -> Result<Self, ()> {
88 edges.sort_unstable();
89
90 let maybe_tree = Tree {
91 edges,
92 _is_canonical: Default::default(),
93 };
94
95 if maybe_tree.is_tree() {
96 Ok(maybe_tree)
97 } else {
98 Err(())
100 }
101 }
102
103 pub(crate) fn symmetric_difference<'a>(
106 &'a self,
107 other: &'a Self,
108 ) -> impl Iterator<Item = TreeEdge> + 'a {
109 symmetric_difference(self.all_edges(), other.all_edges())
110 }
111}
112
113#[test]
114fn test_tree_from_valid_edges() {
115 let edges = vec![
116 TreeEdge::new((0, 0).into(), EdgeDirection::Right),
117 TreeEdge::new((1, 0).into(), EdgeDirection::Right),
118 TreeEdge::new((1, 0).into(), EdgeDirection::Up),
119 TreeEdge::new((2, 0).into(), EdgeDirection::Right),
120 ];
121
122 let tree = Tree::from_edges(edges);
123 assert!(tree.is_ok())
124}
125
126#[test]
127fn test_tree_from_invalid_edges() {
128 let edges = vec![
130 TreeEdge::new((0, 0).into(), EdgeDirection::Right),
131 TreeEdge::new((0, 0).into(), EdgeDirection::Up),
132 TreeEdge::new((1, 0).into(), EdgeDirection::Up),
133 TreeEdge::new((0, 1).into(), EdgeDirection::Right),
134 ];
135
136 let tree = Tree::from_edges(edges);
137 assert!(tree.is_err())
138}
139
140impl<C: CanonicalMarker> Tree<C> {
141 pub fn empty() -> Self {
143 Self {
144 edges: vec![],
145 _is_canonical: Default::default(),
146 }
147 }
148
149 pub fn is_empty(&self) -> bool {
150 self.edges.is_empty()
151 }
152
153 pub(crate) fn num_edges(&self) -> usize {
154 self.edges.len()
155 }
156
157 pub(crate) fn is_tree(&self) -> bool {
160 if self.edges.len() <= 1 {
161 true
162 } else {
163 let mut visited_edges = vec![false; self.edges.len()];
164 let mut front = vec![self.edges[0].start()];
165
166 while let Some(current_node) = front.pop() {
167 let mut num_second_visits = 0;
169 for (idx, adjacent_edge) in self.adjacent_edges_with_index(current_node) {
170 if visited_edges[idx] {
171 num_second_visits += 1;
172 if num_second_visits > 1 {
173 return false;
176 }
177 } else {
178 visited_edges[idx] = true;
180
181 if adjacent_edge.start() != current_node {
183 front.push(adjacent_edge.start());
184 }
185 if adjacent_edge.end() != current_node {
186 front.push(adjacent_edge.end());
187 }
188 }
189 }
190 }
191
192 true
193 }
194 }
195
196 fn all_nodes(&self) -> impl Iterator<Item = Point<HananCoord>> + '_ {
198 self.edges
199 .iter()
200 .map(|e| e.start())
201 .chain(self.edges.iter().map(|e| e.end()))
202 }
203
204 pub fn all_edges(&self) -> impl Iterator<Item = TreeEdge> + '_ {
205 self.edges.iter().copied()
206 }
207
208 pub fn adjacent_edges(&self, p: Point<HananCoord>) -> impl Iterator<Item = TreeEdge> + '_ {
210 self.adjacent_edges_with_index(p).map(|(_, e)| e)
211 }
212
213 fn adjacent_edges_with_index(
215 &self,
216 p: Point<HananCoord>,
217 ) -> impl Iterator<Item = (usize, TreeEdge)> + '_ {
218 self.edges
220 .iter()
221 .copied()
222 .enumerate()
223 .filter(move |(_, e)| e.start() == p || e.end() == p)
224 }
225
226 pub fn contains_node(&self, p: Point<HananCoord>) -> bool {
228 self.adjacent_edges(p).next().is_some()
229 }
230
231 pub fn contains_edge(&self, edge: &TreeEdge) -> bool {
233 if C::is_canonical() {
234 self.edges.binary_search(edge).is_ok()
235 } else {
236 self.edges.iter().find(|e| *e == edge).is_some()
237 }
238 }
239
240 pub fn add_edge(&mut self, edge: TreeEdge) -> &mut Self {
241 {
242 let a = edge.start();
254 let b = edge.end();
255
256 let mut existing_points = self.all_nodes();
257
258 let contains_a_or_b = existing_points.find(|&p| p == a || p == b);
259 if let Some(found_point) = contains_a_or_b {
260 let other = if found_point == a { b } else { a };
261 let contains_other = existing_points.find(|&p| p == other).is_some();
262 assert!(!contains_other, "insertion of this edge creates a cycle");
263 }
264
265 assert!(
266 contains_a_or_b.is_some() || self.is_empty(),
267 "insertion of this edge creates an unconnected component"
268 );
269 }
270
271 self.add_edge_unchecked(edge)
272 }
273
274 pub(crate) fn add_edge_unchecked(&mut self, edge: TreeEdge) -> &mut Self {
276 if C::is_canonical() {
277 match self.edges.binary_search(&edge) {
279 Ok(_) => {
280 panic!("edge already exists");
281 }
282 Err(pos) => self.edges.insert(pos, edge),
283 }
284
285 debug_assert!(
286 self.edges
287 .iter()
288 .zip(self.edges.iter().skip(1))
289 .all(|(a, b)| a <= b),
290 "edges must remain sorted"
291 );
292 } else {
293 self.edges.push(edge)
294 }
295
296 self
297 }
298
299 pub fn remove_edge(&mut self, edge: TreeEdge) -> &mut Self {
300 let a = edge.start();
301 let b = edge.end();
302
303 dbg!(a, b);
304 let num_adj_a = self.adjacent_edges(a).take(2).count();
305 let num_adj_b = self.adjacent_edges(b).take(2).count();
306 dbg!(num_adj_a, num_adj_b);
307
308 let will_disconnect_tree = num_adj_a > 1 && num_adj_b > 1;
309 assert!(
310 !will_disconnect_tree,
311 "removing this edge disconnects the tree"
312 );
313
314 if C::is_canonical() {
316 self.edges.retain(|e| e != &edge);
318 } else {
319 if let Some((index, _)) = self.edges.iter().enumerate().find(|(_, e)| e == &&edge) {
321 self.edges.swap_remove(index);
322 }
323 }
324
325 self
326 }
327
328 pub fn into_canonical_form(mut self) -> Tree<Canonical> {
329 if !C::is_canonical() {
330 self.edges.sort_unstable();
331 }
332 Tree {
333 edges: self.edges,
334 _is_canonical: Default::default(),
335 }
336 }
337
338 pub fn into_non_canonical_form(self) -> Tree<NonCanonical> {
339 Tree {
340 edges: self.edges,
341 _is_canonical: Default::default(),
342 }
343 }
344
345 pub fn translate(&mut self, (dx, dy): (HananCoord, HananCoord)) {
347 self.edges
348 .iter_mut()
349 .for_each(|e| *e = e.translate((dx, dy)))
350 }
351
352 pub fn rotate_90ccw(mut self) -> Tree<NonCanonical> {
354 self.edges.iter_mut().for_each(|e| *e = e.rotate_ccw90());
355
356 self.into_non_canonical_form()
357 }
358
359 pub fn mirror_at_y_axis(mut self) -> Tree<NonCanonical> {
361 self.edges
362 .iter_mut()
363 .for_each(|e| *e = e.mirror_at_y_axis());
364
365 self.into_non_canonical_form()
366 }
367
368 pub fn merge(&mut self, other: &Self) -> Result<(), ()> {
372 if self.is_empty() {
373 self.edges = other.edges.clone();
374 return Ok(());
375 }
376
377 if other.is_empty() {
378 return Ok(());
379 }
380
381 let nodes_a: HashSet<_> = self.all_nodes().collect();
385 let num_node_intersections = other.all_nodes().filter(|n| nodes_a.contains(n)).count();
386
387 let intersection_edges: Vec<_> = if C::is_canonical() {
388 intersection(self.all_edges(), other.all_edges()).collect()
390 } else {
391 self.all_edges()
392 .filter(|e| other.contains_edge(e))
393 .collect()
394 };
395
396 let intersection_tree = Tree::from_edges(intersection_edges)?; let additional_edges = other
399 .all_edges()
400 .filter(|e| !intersection_tree.contains_edge(e));
401
402 if num_node_intersections > 0 {
403 if C::is_canonical() {
404 let new_edges = self.all_edges().merge(additional_edges).collect();
407 self.edges = new_edges;
408
409 Ok(())
410 } else {
411 self.edges.extend(additional_edges);
413 Ok(())
414 }
415 } else {
416 dbg!(num_node_intersections);
417 Err(())
418 }
419 }
420
421 pub(crate) fn compute_wirelength_vector(&self, w: &mut WirelenghtVector) {
424 let (horizontal_edge_count, vertical_edge_count) = w.hv_vectors_mut();
425
426 debug_assert!(self
433 .all_edges()
434 .all(|e| e.start().x >= 0 && e.start().x as usize <= horizontal_edge_count.len()));
435 debug_assert!(self
436 .all_edges()
437 .all(|e| e.start().y >= 0 && e.start().y as usize <= vertical_edge_count.len()));
438
439 self.all_edges().for_each(|e| match e.direction {
440 EdgeDirection::Right => {
441 horizontal_edge_count[e.start().x as usize] += 1;
442 }
443 EdgeDirection::Up => {
444 vertical_edge_count[e.start().y as usize] += 1;
445 }
446 });
447 }
448
449 pub fn bounding_box(&self) -> Option<Rect<HananCoord>> {
452 let mut nodes = self.all_nodes();
453 nodes.next().map(|first_node| {
454 let mut lower_left = first_node;
455 let mut upper_right = first_node;
456
457 for n in nodes {
458 lower_left.x = lower_left.x.min(n.x);
459 lower_left.y = lower_left.y.min(n.y);
460 upper_right.x = upper_right.x.max(n.x);
461 upper_right.y = upper_right.y.max(n.y);
462 }
463
464 Rect::new(lower_left, upper_right)
465 })
466 }
467
468 pub fn translate_to_origin(mut self) -> Self {
470 if let Some(r) = self.bounding_box() {
471 self.translate((-r.lower_left().x, -r.lower_left().y))
472 }
473 self
474 }
475
476 pub fn to_bitvec(&self) -> BitVec {
480 let bbox = self
481 .bounding_box()
482 .unwrap_or(Rect::new(Point::new(0, 0), Point::new(0, 0)));
483 let ll = bbox.lower_left();
484 let ur = bbox.upper_right();
485 assert!(
486 ll.x >= 0 && ll.y >= 0,
487 "tree must be in upper right quadrant"
488 );
489
490 let bbox = Rect::new(Point::new(0, 0), ur);
491 let grid = UnitHananGrid::new(bbox);
492
493 let mut bits = BitVec::new();
494
495 for p in grid.all_points_spiral() {
496 let horizontal_edge = TreeEdge::new(p, EdgeDirection::Right);
497 let vertical_edge = TreeEdge::new(p, EdgeDirection::Up);
498 bits.push(self.contains_edge(&horizontal_edge));
499 bits.push(self.contains_edge(&vertical_edge));
500 }
501
502 bits
503 }
504}
505
506#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
510pub struct TreeEdge {
511 start: Point<HananCoord>,
512 direction: EdgeDirection,
513}
514
515impl TreeEdge {
516 pub fn new(start: Point<HananCoord>, direction: EdgeDirection) -> Self {
517 Self { start, direction }
518 }
519
520 pub fn from_points(a: Point<HananCoord>, b: Point<HananCoord>) -> Result<Self, ()> {
522 let dx = b.x - a.x;
523 let dy = b.y - a.y;
524
525 if dx.abs() + dy.abs() != 1 {
526 Err(())
527 } else {
528 let edge = match (dx, dy) {
529 (1, _) => TreeEdge::new(a, EdgeDirection::Right),
530 (-1, _) => TreeEdge::new(b, EdgeDirection::Right),
531 (_, 1) => TreeEdge::new(a, EdgeDirection::Up),
532 (_, -1) => TreeEdge::new(b, EdgeDirection::Up),
533 _ => unreachable!(),
534 };
535
536 debug_assert!(edge.start() == a || edge.start() == b);
537 debug_assert!(edge.end() == a || edge.end() == b);
538
539 Ok(edge)
540 }
541 }
542
543 pub fn is_vertical(&self) -> bool {
544 self.direction == EdgeDirection::Up
545 }
546
547 pub fn is_horizontal(&self) -> bool {
548 self.direction == EdgeDirection::Right
549 }
550
551 pub fn start(&self) -> Point<HananCoord> {
553 self.start
554 }
555
556 pub fn end(&self) -> Point<HananCoord> {
558 match self.direction {
559 EdgeDirection::Right => Point::new(self.start.x + 1, self.start.y),
560 EdgeDirection::Up => Point::new(self.start.x, self.start.y + 1),
561 }
562 }
563
564 fn translate(mut self, (dx, dy): (HananCoord, HananCoord)) -> Self {
566 self.start.x += dx;
567 self.start.y += dy;
568 self
569 }
570
571 fn mirror_at_y_axis(mut self) -> Self {
573 match self.direction {
574 EdgeDirection::Right => {
575 self.start.x = -self.end().x;
576 }
577 EdgeDirection::Up => {
578 self.start.x = -self.start.x;
579 }
580 }
581 self
582 }
583
584 fn rotate_ccw90(&self) -> Self {
586 match self.direction {
587 EdgeDirection::Right => Self {
588 start: self.start().rotate_ccw90(),
589 direction: EdgeDirection::Up,
590 },
591 EdgeDirection::Up => Self {
592 start: self.end().rotate_ccw90(),
593 direction: EdgeDirection::Right,
594 },
595 }
596 }
597}
598
599#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
601pub enum EdgeDirection {
602 Right,
604 Up,
606}
607
608#[test]
609fn test_mirror_edge() {
610 let e = TreeEdge::new((1, 2).into(), EdgeDirection::Right);
611 let mirrored = e.mirror_at_y_axis();
612
613 let expected = TreeEdge::new((-2, 2).into(), EdgeDirection::Right);
614 assert_eq!(mirrored, expected);
615}
616
617#[test]
618fn test_rotate_edge() {
619 let e = TreeEdge::new((1, 2).into(), EdgeDirection::Right);
620 let rotated = e.rotate_ccw90();
621
622 let expected = TreeEdge::new((-2, 1).into(), EdgeDirection::Up);
623 assert_eq!(rotated, expected);
624}
625
626#[test]
627fn test_rotate_edge_4_times() {
628 let e = TreeEdge::new((1, 2).into(), EdgeDirection::Right);
629 let rotated = e
630 .rotate_ccw90()
631 .rotate_ccw90()
632 .rotate_ccw90()
633 .rotate_ccw90();
634
635 assert_eq!(rotated, e);
636}
637
638#[test]
639fn test_add_edges() {
640 let mut tree = Tree::empty_non_canonical();
641
642 tree.add_edge(TreeEdge::new((0, 0).into(), EdgeDirection::Right))
643 .add_edge(TreeEdge::new((1, 0).into(), EdgeDirection::Right));
644}
645
646#[test]
647fn test_bounding_box() {
648 let mut tree = Tree::empty_non_canonical();
649
650 tree.add_edge(TreeEdge::new((0, 0).into(), EdgeDirection::Right))
651 .add_edge(TreeEdge::new((1, 0).into(), EdgeDirection::Up))
652 .add_edge(TreeEdge::new((1, 1).into(), EdgeDirection::Up))
653 .add_edge(TreeEdge::new((-1, 0).into(), EdgeDirection::Right));
654
655 assert_eq!(
656 tree.bounding_box(),
657 Some(Rect::new((-1, 0).into(), (1, 2).into()))
658 );
659}
660
661#[test]
662fn test_adjacent_edges() {
663 let mut tree = Tree::empty_non_canonical();
664
665 let a = TreeEdge::new((0, 0).into(), EdgeDirection::Right);
666 let b = TreeEdge::new((1, 0).into(), EdgeDirection::Right);
667
668 assert_eq!(tree.adjacent_edges(a.start()).count(), 0);
669 assert_eq!(tree.adjacent_edges(a.end()).count(), 0);
670
671 tree.add_edge(a);
672 tree.add_edge(b);
673
674 assert_eq!(tree.adjacent_edges(a.start()).next(), Some(a));
675 assert_eq!(tree.adjacent_edges(a.end()).count(), 2);
676 assert_eq!(tree.adjacent_edges(b.start()).count(), 2);
677 assert_eq!(tree.adjacent_edges(b.end()).next(), Some(b));
678}
679
680#[test]
681fn test_remove_edges() {
682 let mut tree = Tree::empty_non_canonical();
683 let a = TreeEdge::new((0, 0).into(), EdgeDirection::Right);
684 let b = TreeEdge::new((1, 0).into(), EdgeDirection::Right);
685 let c = TreeEdge::new((2, 0).into(), EdgeDirection::Right);
686
687 tree.add_edge(a)
688 .add_edge(b)
689 .add_edge(c)
690 .remove_edge(a)
691 .remove_edge(c)
692 .remove_edge(b);
693}
694
695#[test]
696#[should_panic]
697fn test_remove_disconnecting_edge() {
698 let mut tree = Tree::empty_non_canonical();
699
700 let a = TreeEdge::new((0, 0).into(), EdgeDirection::Right);
701 let b = TreeEdge::new((1, 0).into(), EdgeDirection::Right);
702 let c = TreeEdge::new((2, 0).into(), EdgeDirection::Right);
703
704 tree.add_edge(a)
705 .add_edge(b)
706 .add_edge(c)
707 .remove_edge(b);
709}
710
711#[test]
712fn test_canonical_tree_equivalence() {
713 let mut tree1 = Tree::empty_canonical();
714 let mut tree2 = Tree::empty_canonical();
715
716 assert_eq!(tree1, tree2);
717
718 tree1.add_edge(TreeEdge::new((0, 0).into(), EdgeDirection::Right));
719 tree1.add_edge(TreeEdge::new((1, 0).into(), EdgeDirection::Right));
720
721 tree2.add_edge(TreeEdge::new((1, 0).into(), EdgeDirection::Right));
723 tree2.add_edge(TreeEdge::new((0, 0).into(), EdgeDirection::Right));
724
725 assert_eq!(tree1, tree2);
726}
727
728#[test]
729#[should_panic]
730fn test_create_unconnected_tree() {
731 let mut tree = Tree::empty_non_canonical();
732 tree.add_edge(TreeEdge::new((0, 0).into(), EdgeDirection::Right));
733 tree.add_edge(TreeEdge::new((2, 0).into(), EdgeDirection::Right));
734}
735
736#[test]
737#[should_panic]
738fn test_create_tree_with_cycle() {
739 let mut tree = Tree::empty_non_canonical();
740 tree.add_edge(TreeEdge::new((0, 0).into(), EdgeDirection::Right));
741 tree.add_edge(TreeEdge::new((0, 0).into(), EdgeDirection::Up));
742 tree.add_edge(TreeEdge::new((1, 0).into(), EdgeDirection::Up));
743 tree.add_edge(TreeEdge::new((0, 1).into(), EdgeDirection::Right));
745}
746
747#[test]
748fn test_wirelength_vector() {
749 let mut tree = Tree::empty_non_canonical();
750
751 tree.add_edge(TreeEdge::new((0, 0).into(), EdgeDirection::Right))
752 .add_edge(TreeEdge::new((1, 0).into(), EdgeDirection::Up))
753 .add_edge(TreeEdge::new((1, 1).into(), EdgeDirection::Up))
754 .add_edge(TreeEdge::new((1, 2).into(), EdgeDirection::Up))
755 .add_edge(TreeEdge::new((0, 0).into(), EdgeDirection::Up));
756
757 let mut w = WirelenghtVector::zero(2, 3);
758
759 tree.compute_wirelength_vector(&mut w);
760
761 assert_eq!(w.hv_vectors().0, vec![1, 0]);
762 assert_eq!(w.hv_vectors().1, vec![2, 1, 1]);
763}