1use std::{cmp::Ordering, collections::VecDeque};
2
3use bitvec::vec::BitVec;
4use itertools::Itertools;
5
6use crate::tree::{
7 parent_pointer::ParentPointerStore, Forest, ForestNodeStore, ForestNodeStoreBfs,
8 ForestNodeStoreDown, ForestNodeStorePreorder, RootId,
9};
10
11use super::{
12 involution::{Hedge, Involution},
13 subgraph::{Cycle, Inclusion, InternalSubGraph, ModifySubgraph, SubGraph, SubGraphOps},
14 HedgeGraph, HedgeGraphError, NodeIndex, NodeStorageOps,
15};
16
17#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
43#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
44#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
45pub enum TTRoot {
52 Child(usize),
55 Root,
57 None,
59}
60
61impl TTRoot {
62 pub fn includes(&self) -> bool {
63 match self {
64 TTRoot::Child(_) => true,
65 TTRoot::Root => true,
66 TTRoot::None => false,
67 }
68 }
69
70 pub fn is_root(&self) -> bool {
71 match self {
72 TTRoot::Child(_) => false,
73 TTRoot::Root => true,
74 TTRoot::None => false,
75 }
76 }
77
78 pub fn is_child(&self) -> bool {
79 match self {
80 TTRoot::Child(_) => true,
81 TTRoot::Root => false,
82 TTRoot::None => false,
83 }
84 }
85}
86
87#[derive(Debug, Clone)]
88#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
89pub struct SimpleTraversalTree<P: ForestNodeStore<NodeData = ()> = ParentPointerStore<()>> {
105 forest: Forest<TTRoot, P>,
109 pub tree_subgraph: BitVec,
113}
114#[cfg(feature = "bincode")]
115impl<P: ForestNodeStore<NodeData = ()>> ::bincode::Encode for SimpleTraversalTree<P>
116where
117 P: ::bincode::Encode,
118{
119 fn encode<__E: ::bincode::enc::Encoder>(
120 &self,
121 encoder: &mut __E,
122 ) -> core::result::Result<(), ::bincode::error::EncodeError> {
123 ::bincode::Encode::encode(&self.forest, encoder)?;
124 ::bincode::Encode::encode(&::bincode::serde::Compat(&self.tree_subgraph), encoder)?;
125 core::result::Result::Ok(())
126 }
127}
128
129#[cfg(feature = "bincode")]
130impl<P: ForestNodeStore<NodeData = ()>, __Context> ::bincode::Decode<__Context>
131 for SimpleTraversalTree<P>
132where
133 P: ::bincode::Decode<__Context>,
134{
135 fn decode<__D: ::bincode::de::Decoder<Context = __Context>>(
136 decoder: &mut __D,
137 ) -> core::result::Result<Self, ::bincode::error::DecodeError> {
138 core::result::Result::Ok(Self {
139 forest: ::bincode::Decode::decode(decoder)?,
140 tree_subgraph: (<::bincode::serde::Compat<_> as ::bincode::Decode<__Context>>::decode(
141 decoder,
142 )?)
143 .0,
144 })
145 }
146}
147
148#[cfg(feature = "bincode")]
149impl<'__de, P: ForestNodeStore<NodeData = ()>, __Context> ::bincode::BorrowDecode<'__de, __Context>
150 for SimpleTraversalTree<P>
151where
152 P: ::bincode::de::BorrowDecode<'__de, __Context>,
153{
154 fn borrow_decode<__D: ::bincode::de::BorrowDecoder<'__de, Context = __Context>>(
155 decoder: &mut __D,
156 ) -> core::result::Result<Self, ::bincode::error::DecodeError> {
157 core::result::Result::Ok(Self {
158 forest: ::bincode::BorrowDecode::<'_, __Context>::borrow_decode(decoder)?,
159 tree_subgraph: (<::bincode::serde::BorrowCompat<_> as ::bincode::BorrowDecode<
160 '_,
161 __Context,
162 >>::borrow_decode(decoder)?)
163 .0,
164 })
165 }
166}
167impl<P: ForestNodeStore<NodeData = ()>> SimpleTraversalTree<P> {
168 pub fn cast<P2: ForestNodeStore<NodeData = ()>>(self) -> SimpleTraversalTree<P2>
169 where
170 Forest<TTRoot, P2>: From<Forest<TTRoot, P>>,
171 {
172 SimpleTraversalTree {
173 forest: self.forest.into(),
174 tree_subgraph: self.tree_subgraph,
175 }
176 }
177}
178
179impl<P: ForestNodeStore<NodeData = ()>> SimpleTraversalTree<P> {
180 pub fn node_order(&self) -> Vec<NodeIndex> {
181 self.forest
182 .iter_roots()
183 .enumerate()
184 .filter_map(|(i, (a, _))| match a {
185 TTRoot::Root => Some((0, i)),
186 TTRoot::Child(a) => Some((*a, i)),
187 _ => None,
188 })
189 .sorted_by(|a, b| a.0.cmp(&b.0))
190 .map(|a| NodeIndex(a.1))
191 .collect()
192 }
193 pub fn covers<S: SubGraph>(&self, subgraph: &S) -> BitVec {
194 let mut covers = BitVec::empty(self.tree_subgraph.len());
196
197 for i in 0..self.tree_subgraph.len() {
200 if self.node_data(self.node_id(Hedge(i))).includes() && subgraph.includes(&Hedge(i)) {
201 covers.set(i, true);
202 }
203 }
204
205 covers
206 }
207
208 pub fn node_data(&self, node: NodeIndex) -> &TTRoot {
213 &self.forest[RootId(node.0)]
214 }
215
216 pub fn internal<I: AsRef<Involution>>(&self, hedge: Hedge, _inv: I) -> bool {
217 self.tree_subgraph.includes(&hedge)
218 }
219
220 pub fn tree_subgraph<I: AsRef<Involution>>(&self, inv: I) -> InternalSubGraph {
221 let mut tree = BitVec::empty(self.tree_subgraph.len());
222 let inv = inv.as_ref();
223
224 for (r, h) in self.forest.iter_roots() {
225 let h: Hedge = (*h).into();
226 if r.is_child() {
227 tree.add(h);
228 tree.add(inv.inv(h))
229 }
230 }
231
232 unsafe { InternalSubGraph::new_unchecked(tree) }
233 }
234
235 pub fn get_cycle<I: AsRef<Involution>>(&self, cut: Hedge, inv: &I) -> Option<Cycle> {
236 if self.internal(cut, inv) {
237 return None;
238 }
239 let mut cycle = self.path_to_root(cut, inv);
240 cycle.sym_diff_with(&self.path_to_root(inv.as_ref().inv(cut), inv));
241 let mut cycle = Cycle::new_unchecked(cycle);
242 cycle.loop_count = Some(1);
243
244 Some(cycle)
245 }
246
247 pub fn node_id(&self, hedge: Hedge) -> NodeIndex {
248 NodeIndex::from(self.forest.root(hedge.into()))
249 }
250
251 pub fn node_parent<I: AsRef<Involution>>(&self, from: NodeIndex, inv: I) -> Option<NodeIndex> {
253 let root = RootId::from(from);
254
255 if self.forest[root].is_child() {
256 let involved = inv.as_ref().inv(self.forest[&root].into());
259 Some(self.node_id(involved))
260 } else {
261 None
262 }
263 }
264
265 fn path_to_root<I: AsRef<Involution>>(&self, start: Hedge, inv: I) -> BitVec {
266 let mut path = BitVec::empty(self.tree_subgraph.len());
267
268 self.ancestor_iter_hedge(start, inv.as_ref())
269 .for_each(|a| path.set(a.0, true));
270 path
271 }
272
273 pub fn hedge_parent<I: AsRef<Involution>>(&self, from: Hedge, inv: I) -> Option<Hedge> {
276 let root = self.forest.root(from.into()); match self.forest[root] {
279 TTRoot::Child(_) => {
280 let roothedge = self.forest[&root].into(); if from == roothedge {
283 Some(inv.as_ref().inv(from))
285 } else {
286 Some(roothedge)
288 }
289 }
290 TTRoot::None => {
291 None
293 }
294 TTRoot::Root => {
295 None
297 } }
299 }
300}
301
302pub struct TraversalTreeAncestorHedgeIterator<'a, P: ForestNodeStore<NodeData = ()>> {
310 tt: &'a SimpleTraversalTree<P>,
312 inv: &'a Involution,
314 current: Option<Hedge>,
316}
317
318impl<P: ForestNodeStore<NodeData = ()>> Iterator for TraversalTreeAncestorHedgeIterator<'_, P> {
319 type Item = Hedge;
320
321 fn next(&mut self) -> Option<Self::Item> {
322 if let Some(c) = self.current {
323 self.current = self.tt.hedge_parent(c, self.inv);
324 Some(c)
325 } else {
326 None
327 }
328 }
329}
330
331#[derive(Clone)]
332pub struct PreorderTraversalIter<'a, S: ForestNodeStore<NodeData = ()>>
343where
344 S: ForestNodeStoreBfs,
345{
346 store: &'a SimpleTraversalTree<S>,
348 inv: &'a Involution,
350 stack: Vec<NodeIndex>,
352}
353
354impl<'a, S: ForestNodeStoreBfs + ForestNodeStore<NodeData = ()>> PreorderTraversalIter<'a, S> {
355 pub fn new(
357 store: &'a SimpleTraversalTree<S>,
358 inv: &'a impl AsRef<Involution>,
359 start: NodeIndex,
360 ) -> Self {
361 PreorderTraversalIter {
362 inv: inv.as_ref(),
363 store,
364 stack: vec![start],
365 }
366 }
367}
368
369impl<S: ForestNodeStoreBfs + ForestNodeStore<NodeData = ()>> Iterator
370 for PreorderTraversalIter<'_, S>
371{
372 type Item = NodeIndex;
373 fn next(&mut self) -> Option<Self::Item> {
374 let node = self.stack.pop()?;
376
377 for child in self
380 .store
381 .iter_children(node, &self.inv)
382 .collect::<Vec<_>>()
383 .into_iter()
384 .rev()
385 {
386 self.stack.push(child);
387 }
388
389 Some(node)
390 }
391}
392
393impl<P: ForestNodeStore<NodeData = ()>> SimpleTraversalTree<P> {
394 pub fn debug_draw<FR>(
395 &self,
396 format_root: FR, ) -> String
398 where
399 FR: FnMut(&TTRoot) -> String,
400
401 P: ForestNodeStoreDown,
402 {
403 self.forest.debug_draw(format_root, |_| "".into())
404 }
405 pub fn iter_children<'a, I: AsRef<Involution>>(
406 &'a self,
407 node_id: NodeIndex,
408 inv: &'a I,
409 ) -> impl Iterator<Item = NodeIndex> + 'a
410 where
411 P: ForestNodeStoreBfs,
412 {
413 let root_node = self.forest[&RootId::from(node_id)];
414
415 let root_node_data = self.forest[RootId::from(node_id)];
416
417 self.forest.iter_bfs(root_node).filter_map(move |a| {
419 if root_node == a && !root_node_data.is_root() {
420 return None;
421 }
422 let h = Hedge::from(a);
423 if self.tree_subgraph.includes(&h) {
425 let invh = inv.as_ref().inv(a.into());
426 if invh != h {
428 if self.tree_subgraph.includes(&invh) {
430 let child = self.node_id(invh);
431 let root = RootId::from(child);
434
435 if self.forest[root].is_child() {
436 Some(child)
437 } else {
438 None
439 }
440 } else {
441 None
442 }
443 } else {
444 None
445 }
446 } else {
447 None
448 }
449 })
450 }
451
452 pub fn iter_preorder_tree_nodes<'a>(
467 &'a self,
468 inv: &'a impl AsRef<Involution>,
469 start: NodeIndex,
470 ) -> PreorderTraversalIter<'a, P>
471 where
472 P: ForestNodeStorePreorder<NodeData = ()> + ForestNodeStoreBfs,
473 {
474 PreorderTraversalIter::new(self, inv, start)
475 }
476
477 pub fn ancestor_iter_hedge<'a>(
478 &'a self,
479 start: Hedge,
480 inv: &'a Involution,
481 ) -> impl Iterator<Item = Hedge> + 'a {
482 TraversalTreeAncestorHedgeIterator {
483 tt: self,
484 inv,
485 current: Some(start),
486 }
487 }
488
489 pub fn dot<E, V, H, N: NodeStorageOps<NodeData = V>>(
490 &self,
491 graph: &HedgeGraph<E, V, H, N>,
492 ) -> String {
493 let mut structure = graph.just_structure();
494 structure.align_superficial_to_tree(self);
495
496 structure.base_dot()
497 }
498
499 pub fn tree_order<I: AsRef<Involution>>(
500 &self,
501 left: NodeIndex,
502 right: NodeIndex,
503 inv: I,
504 ) -> Option<Ordering> {
505 if left == right {
506 return Some(Ordering::Equal);
507 }
508
509 let left_to_root_passes_through_right = self
510 .ancestor_iter_node(left, inv.as_ref())
511 .any(|a| a == right);
512 if left_to_root_passes_through_right {
513 return Some(Ordering::Less);
514 }
515
516 let right_to_root_passes_through_left = self
517 .ancestor_iter_node(right, inv.as_ref())
518 .any(|a| a == left);
519 if right_to_root_passes_through_left {
520 return Some(Ordering::Greater);
521 }
522
523 None
524 }
525
526 pub fn iter_hedges(&self) -> impl Iterator<Item = (Hedge, TTRoot, Option<Hedge>)> + '_ {
535 self.forest.iter_node_ids().map(|a| {
536 let root = self.forest.root(a); let hedge: Hedge = a.into();
538 let ttype = self.forest[root];
539 let root_among_hedges = if self.tree_subgraph.includes(&hedge) {
540 Some(self.forest[&root].into())
541 } else {
542 None
543 };
544
545 (hedge, ttype, root_among_hedges)
546 })
547 }
548}
549
550pub struct TraversalTreeAncestorNodeIterator<'a, P: ForestNodeStore<NodeData = ()>> {
551 tt: &'a SimpleTraversalTree<P>,
552 inv: &'a Involution,
553 current: Option<NodeIndex>,
554}
555
556impl<P: ForestNodeStore<NodeData = ()>> Iterator for TraversalTreeAncestorNodeIterator<'_, P> {
557 type Item = NodeIndex;
558
559 fn next(&mut self) -> Option<Self::Item> {
560 if let Some(c) = self.current {
561 self.current = self.tt.node_parent(c, self.inv);
562 Some(c)
563 } else {
564 None
565 }
566 }
567}
568
569impl<P: ForestNodeStore<NodeData = ()>> SimpleTraversalTree<P> {
570 pub fn ancestor_iter_node<'a>(
571 &'a self,
572 from: NodeIndex,
573 inv: &'a Involution,
574 ) -> impl Iterator<Item = NodeIndex> + 'a {
575 TraversalTreeAncestorNodeIterator {
576 tt: self,
577 inv,
578 current: Some(from),
579 }
580 }
581}
582
583impl SimpleTraversalTree {
584 pub fn empty<E, V, H, N: NodeStorageOps<NodeData = V>>(graph: &HedgeGraph<E, V, H, N>) -> Self {
585 let forest = graph.node_store.to_forest(|_| TTRoot::None);
586 SimpleTraversalTree {
587 forest,
588 tree_subgraph: graph.empty_subgraph(),
589 }
590 }
591
592 pub fn depth_first_traverse<S: SubGraph, E, V, H, N: NodeStorageOps<NodeData = V>>(
597 graph: &HedgeGraph<E, V, H, N>,
598 subgraph: &S,
599 root_node: &NodeIndex,
600 include_hedge: Option<Hedge>,
601 ) -> Result<Self, HedgeGraphError> {
602 let mut seen = subgraph.hairs(graph.iter_crown(*root_node));
603
604 if seen.count_ones() == 0 {
605 return Err(HedgeGraphError::RootNodeNotInSubgraph(*root_node));
607 }
608
609 let mut stack = seen.included_iter().collect::<Vec<_>>();
610 if let Some(r) = include_hedge {
611 if graph.inv(r) == r {
612 return Err(HedgeGraphError::ExternalHedgeIncluded(r)); }
614
615 let pos = stack.iter().find_position(|a| **a == r).map(|a| a.0);
616
617 let last = stack.len() - 1;
618 if let Some(pos) = pos {
619 stack.swap(pos, last);
620 } else {
621 return Err(HedgeGraphError::NotInNode(r, *root_node));
622 }
623 }
624
625 let mut init = Self::empty(graph);
626 init.forest[RootId(root_node.0)] = TTRoot::Root;
627
628 let mut iter_order = 0;
629
630 while let Some(hedge) = stack.pop() {
631 if let Some(cn) = graph.involved_node_crown(hedge) {
633 let connected = graph.inv(hedge);
634
635 if !seen.includes(&connected) && subgraph.includes(&connected) {
636 init.tree_subgraph.set(connected.0, true);
639 init.tree_subgraph.set(hedge.0, true);
640 let node_id = init.forest.change_to_root(connected.into());
641 iter_order += 1;
642 init.forest[node_id] = TTRoot::Child(iter_order);
643 } else {
644 continue;
645 }
646
647 for i in cn {
651 if subgraph.includes(&i) {
652 seen.set(i.0, true);
653 if !seen.includes(&graph.inv(i)) {
654 stack.push(i);
655 }
656 }
657 }
658 }
659 }
660
661 Ok(init)
663 }
664
665 pub fn breadth_first_traverse<S: SubGraph, E, V, H, N: NodeStorageOps<NodeData = V>>(
666 graph: &HedgeGraph<E, V, H, N>,
667 subgraph: &S,
668 root_node: &NodeIndex,
669 include_hedge: Option<Hedge>,
670 ) -> Result<Self, HedgeGraphError> {
671 let mut seen = subgraph.hairs(graph.iter_crown(*root_node));
672
673 if seen.count_ones() == 0 {
674 return Err(HedgeGraphError::InvalidNode(*root_node));
676 }
677
678 let mut queue = seen.included_iter().collect::<VecDeque<_>>();
679 if let Some(r) = include_hedge {
680 if graph.inv(r) == r {
681 return Err(HedgeGraphError::InvalidHedge(r)); }
683 let pos = queue.iter().find_position(|a| **a == r).map(|a| a.0);
684 if let Some(pos) = pos {
685 queue.swap(pos, 0);
686 } else {
687 return Err(HedgeGraphError::InvalidHedge(r));
688 }
689 }
690
691 let mut init = Self::empty(graph);
692
693 let mut iter_order = 0;
694 init.forest[RootId(root_node.0)] = TTRoot::Root;
695 while let Some(hedge) = queue.pop_front() {
696 if let Some(cn) = graph.connected_neighbors(subgraph, hedge) {
698 let connected = graph.inv(hedge);
699
700 if !seen.includes(&connected) && subgraph.includes(&connected) {
701 init.tree_subgraph.set(connected.0, true);
705 init.tree_subgraph.set(hedge.0, true);
706 let node_id = init.forest.change_to_root(connected.into());
707 iter_order += 1;
708 init.forest[node_id] = TTRoot::Child(iter_order);
709 } else {
710 continue;
711 }
712 seen.union_with(&cn);
714
715 for i in cn.included_iter() {
717 if !seen.includes(&graph.inv(i)) && subgraph.includes(&i) {
719 queue.push_back(i);
720 }
721 }
722 }
723 }
724 Ok(init)
725 }
726}
727
728#[derive(Debug, Clone)]
729#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
730pub struct OwnedTraversalTree<P: ForestNodeStore<NodeData = ()> + Clone + ForestNodeStorePreorder> {
743 pub graph: HedgeGraph<(), bool, (), Forest<bool, P>>,
747 pub tree_subgraph: InternalSubGraph,
750 pub covers: BitVec,
754}
755
756#[cfg(test)]
837pub mod tests {
838 use crate::{dot, half_edge::involution::Orientation, parser::DotGraph};
839
840 use super::*;
841
842 #[test]
843 fn double_pentagon_tree() {
844 let mut graph: DotGraph = dot!(
845 digraph {
846 node [shape=circle,height=0.1,label=""]; overlap="scale"; layout="neato";
847 00 -> 07[ dir=none,label="a"];
848 00 -> 12[ dir=forward,label="d"];
849 01 -> 00[ dir=forward,label="d"];
850 05 -> 02[ dir=forward,label="d"];
851 02 -> 01[ dir=forward,label="d"];
852 09 -> 04[ dir=forward,label="d"];
853 02 -> 06[ dir=none,label="a"];
854 01 -> 03[ dir=none,label="a"];
855 03 -> 13[ dir=forward,label="d"];
856 04 -> 03[ dir=forward,label="d"];
857 04 -> 05[ dir=none,label="g"];
858 06 -> 07[ dir=forward,label="e-"];
859 07 -> 11[ dir=forward,label="e-"];
860 08 -> 06[ dir=forward,label="e-"];
861 10 -> 05[ dir=forward,label="d"];
862 }
863 )
864 .unwrap();
865
866 let tree = SimpleTraversalTree::depth_first_traverse(
869 &graph,
870 &graph.full_filter(),
871 &NodeIndex(0),
872 None,
873 )
874 .unwrap();
875 graph.align_underlying_to_tree(&tree);
878 graph.align_superficial_to_tree(&tree);
879 assert!(graph
880 .iter_edges()
881 .all(|(_, _, d)| !matches!(d.orientation, Orientation::Reversed)));
882 }
885}