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