pq_tree/
tree.rs

1use std::collections::VecDeque;
2use std::fmt::{Debug, Display, Formatter};
3use std::hash::Hash;
4
5use bimap::BiMap;
6use enum_map::Enum;
7
8use crate::errors::*;
9use crate::node::*;
10use crate::rel::*;
11
12#[derive(Debug, Clone)]
13pub struct PQTree<T>
14where
15    T: Clone + Eq + Hash,
16{
17    empty: bool,
18    pub(crate) nodes: Vec<TreeNode>,
19    freelist: VecDeque<usize>,
20    pub(crate) leaves: BiMap<T, usize>,
21    pub(crate) pertinent_root: Option<usize>,
22}
23
24pub(crate) const PSEUDONODE: usize = 0;
25pub(crate) const ROOT: usize = 1;
26pub(crate) const ABSENT: usize = usize::MAX;
27
28#[derive(Debug, Clone)]
29pub(crate) struct TreeNode {
30    pub(crate) rel: Rel,
31    pub(crate) node: Node,
32    pub(crate) red: ReductionInfo,
33}
34
35#[derive(Debug, Clone)]
36pub(crate) struct ReductionInfo {
37    pub(crate) mark: NodeMark,
38    pub(crate) label: NodeLabel,
39    pub(crate) pertinent_child_count: usize,
40    pub(crate) pertinent_leaf_count: usize,
41}
42
43impl Default for ReductionInfo {
44    fn default() -> Self {
45        ReductionInfo {
46            mark: NodeMark::Unmarked,
47            label: NodeLabel::Empty,
48            pertinent_child_count: 0,
49            pertinent_leaf_count: 0,
50        }
51    }
52}
53
54#[derive(Debug, Eq, PartialEq, Copy, Clone)]
55pub(crate) enum NodeMark {
56    Unmarked,
57    Blocked,
58    Unblocked,
59    Queued,
60}
61
62#[derive(Debug, Enum, Eq, PartialEq, Copy, Clone)]
63pub(crate) enum NodeLabel {
64    Empty,
65    Full,
66    SinglyPartial,
67    DoublyPartial,
68}
69
70impl<T: Clone + Eq + Hash> PQTree<T> {
71    /// Creates an empty `PQTree`.
72    pub fn new() -> PQTree<T> {
73        let root = TreeNode { rel: Rel::Root(ABSENT.into()), node: Node::L, red: ReductionInfo::default() };
74        let pseudonode = TreeNode { rel: Rel::Root(ABSENT.into()), node: Node::L, red: ReductionInfo::default() };
75
76        PQTree {
77            empty: true,
78            nodes: vec![root, pseudonode],
79            freelist: Default::default(),
80            leaves: BiMap::new(),
81            pertinent_root: None,
82        }
83    }
84
85    /// Creates PQTree from list of leaves.
86    ///
87    /// First creates an empty tree, then replaces whole tree by new leaves:
88    ///
89    /// ```PQTree::new().replace_tree_by_new_leaves(initial)```
90    ///
91    /// # Errors
92    /// Returns `Err(ReplacementError::DuplicateLeaf(leaf))` if `leaf` presents in `initial` more than one time.
93    pub fn from_leaves(initial: &[T]) -> Result<Self, ReplacementError<T>> {
94        PQTree::new().replace_tree_by_new_leaves(initial)
95    }
96
97    /// Applies reduction to the tree enforcing leaves from `s` to be consequent
98    /// and marks pertinent subroot.
99    /// # Errors
100    /// Returns `Err(ReductionError::EmptyLeafSet)` if `s` is empty.
101    ///
102    /// Returns `Err(ReductionError::LeafNotFound(leaf))` if `leaf` from `s` not found in the tree.
103    ///
104    /// Returns `Err(ReductionError::IrreducibleTree)` if tree cannot be reduced over new constraint.
105    pub fn reduction(mut self, s: &[T]) -> Result<Self, ReductionError<T>> {
106        if s.is_empty() {
107            return Err(ReductionError::EmptyLeafSet);
108        }
109
110        let mut s_nodes = Vec::with_capacity(s.len());
111        for leaf in s {
112            match self.leaves.get_by_left(leaf) {
113                Some(&node) => s_nodes.push(node),
114                None => return Err(ReductionError::LeafNotFound(leaf.clone())),
115            };
116        }
117
118        self.bubble(&s_nodes)?;
119        self.reduce(&s_nodes)?;
120        Ok(self)
121    }
122
123    /// Replaces whole tree by new leaves.
124    ///
125    /// Same as [`PQTree::from_leaves`] but without reallocation.
126    /// # Errors
127    /// Returns `Err(ReplacementError::DuplicateLeaf(leaf))` if `leaf` presents in `leaves` more than one time.
128    pub fn replace_tree_by_new_leaves(mut self, leaves: &[T]) -> Result<Self, ReplacementError<T>> {
129        self.destroy_tree(false);
130        self.pertinent_root = None;
131
132        self.replace_by_new_leaves(ROOT, leaves)?;
133
134        Ok(self)
135    }
136
137    /// Replaces single `leaf` by new `leaves`.
138    /// Can be called with empty `leaves` to remove `leaf` from tree.
139    ///
140    /// First removes `leaf` from tree, then adds new leaves.
141    ///
142    /// Clears pertinent root mark if any.
143    ///
144    /// # Errors
145    /// Returns `Err(ReplacementError::LeafNotFound(leaf))` if `leaf` not found in the tree.
146    ///
147    /// Returns `Err(ReplacementError::DuplicateLeaf(leaf))` if `leaf` already exists in the tree or presents in `leaves` more than one time.
148
149    pub fn replace_leaf_by_new_leaves(mut self, leaf: &T, leaves: &[T]) -> Result<Self, ReplacementError<T>> {
150        match self.leaves.get_by_left(leaf) {
151            None => Err(ReplacementError::LeafNotFound(leaf.clone())),
152            Some(&node) => self.replace_by_new_leaves(node, leaves),
153        }?;
154        self.pertinent_root = None; // TODO: think about it
155        Ok(self)
156    }
157
158    /// Replaces full children of the pertinent root by new `leaves`.
159    /// Can be called with empty `leaves` to remove all full children from the tree.
160    ///
161    /// First removes all full nodes and leaves from the tree, then adds new leaves.
162    ///
163    /// Marks added subtree root as the pertinent root if `leaves` is not empty or clears the mark.
164    ///
165    /// # Errors
166    /// Returns `Err(ReplacementError::DuplicateLeaf(leaf))` if `leaf` already exists in the tree or presents in `leaves` more than one time.
167    ///
168    /// Returns `Err(ReplacementError::NoPertinentRoot))` if no pertinent root is marked in the tree.
169
170    pub fn replace_pertinent_by_new_leaves(mut self, leaves: &[T]) -> Result<Self, ReplacementError<T>> {
171        let pertinent_root = self.pertinent_root.ok_or(ReplacementError::NoPertinentRoot)?;
172        self.pertinent_root = match self.nodes[pertinent_root].node {
173            Node::P(_) | Node::L => self.replace_by_new_leaves(pertinent_root, leaves),
174            Node::Q(q) => {
175                if pertinent_root != PSEUDONODE && self.nodes[pertinent_root].red.label == NodeLabel::Full {
176                    // full non-pseudo Q-node
177                    self.replace_by_new_leaves(pertinent_root, leaves)
178                } else {
179                    // partial Q-node or pseudonode
180                    // TODO: optimize for SinglyPartial case
181                    let mut next = Some(q.left);
182                    let mut first = None;
183                    while let Some(current) = next {
184                        next = if current == q.right { None } else { Some(self.nodes[current].rel.right()) };
185
186                        if self.nodes[current].red.label == NodeLabel::Full {
187                            if let Some(first_unwrapped) = first {
188                                // remove_node can demote Q-node to P-node and even remove P and hoist sole child
189                                // but: Q node have at least three children and first is retained here
190                                //      and Q is partial (or pseudonode witch also part of partial Q node,
191                                //      so at least one empty child will remain and first cannot be moved inside tree
192                                self.remove_node(current);
193
194                                // still keep debug_assert! here
195                                debug_assert!(!&self.freelist.contains(&first_unwrapped));
196                            } else {
197                                first = Some(current);
198                            }
199                        }
200                    }
201
202                    self.replace_by_new_leaves(first.expect("full child not found in pertinent root"), leaves)
203                }
204            }
205        }?;
206        Ok(self)
207    }
208
209    /// Returns the tree frontier: a vector of leaves ordered in an allowed way for the tree.
210    pub fn frontier(&self) -> Vec<T> {
211        if self.empty {
212            return vec![];
213        }
214        self.collect_frontier(Vec::with_capacity(self.leaves.len()), ROOT)
215    }
216
217    pub(crate) fn recycle_node(&mut self, idx: usize) {
218        // TODO: remove last node and truncate freelist if possible?
219        debug_assert!(!self.freelist.contains(&idx));
220        self.nodes[idx].rel = Rel::Root(ABSENT.into());
221        self.freelist.push_back(idx);
222    }
223
224    pub(crate) fn add_node(&mut self, node: TreeNode) -> usize {
225        if let Some(free) = self.freelist.pop_front() {
226            self.nodes[free] = node;
227            free
228        } else {
229            self.nodes.push(node);
230            self.nodes.len() - 1
231        }
232    }
233
234    fn destroy_tree(&mut self, recycle: bool) {
235        if !self.empty {
236            self.nodes.truncate(2); // pseunonode and root must be kept
237            self.freelist.clear();
238            self.leaves.clear();
239        }
240        self.empty = recycle;
241        // self.pertinent_root must be set or unset by caller
242    }
243
244    fn destroy_node(&mut self, idx: usize, recycle: bool) {
245        if idx == ROOT {
246            self.destroy_tree(recycle);
247            return;
248        }
249        debug_assert_ne!(idx, PSEUDONODE);
250
251        match self.nodes[idx].node {
252            Node::P(p) => {
253                let mut next = Some(p.child);
254                while let Some(current) = next {
255                    next = {
256                        let next = self.nodes[current].rel.next();
257                        if next != p.child {
258                            Some(next)
259                        } else {
260                            None
261                        }
262                    };
263                    self.destroy_node(current, true);
264                }
265            }
266            Node::Q(q) => {
267                let mut next = Some(q.left);
268                while let Some(current) = next {
269                    next = if current != q.right { Some(self.nodes[current].rel.right()) } else { None };
270                    self.destroy_node(current, true);
271                }
272            }
273            Node::L => {
274                self.leaves.remove_by_right(&idx).expect("broken leaves map");
275            }
276        }
277
278        if recycle {
279            self.recycle_node(idx);
280        }
281    }
282
283    fn remove_node(&mut self, idx: usize) {
284        match self.nodes[idx].rel {
285            Rel::Root(_) => {
286                self.destroy_tree(true);
287                return;
288            }
289            Rel::P(p) => {
290                if self.nodes[p.next].rel.as_p().next == idx {
291                    // last child remains in parent, replace node by child
292                    self.replace_node(p.parent, p.next);
293                }
294            }
295            Rel::LQ(lq) => {
296                let right_right = self.nodes[lq.right].rel.right();
297
298                if let Rel::RQ(_) = self.nodes[right_right].rel {
299                    self.replace_with_pair_p(lq.parent, lq.right, right_right);
300                } else {
301                    self.nodes[lq.parent].node.as_mut_q().left = lq.right;
302                    self.nodes[lq.right].rel = Rel::LQ(LeftChildOfQ { parent: lq.parent, right: right_right });
303                }
304            }
305            Rel::RQ(rq) => {
306                let left_left = self.nodes[rq.left].rel.left();
307
308                if let Rel::LQ(_) = self.nodes[left_left].rel {
309                    self.replace_with_pair_p(rq.parent, rq.left, left_left);
310                } else {
311                    self.nodes[rq.parent].node.as_mut_q().right = rq.left;
312                    self.nodes[rq.left].rel = Rel::RQ(RightChildOfQ { parent: rq.parent, left: left_left });
313                }
314            }
315            Rel::IQ(iq) => {
316                if let (Rel::LQ(lq), Rel::RQ(_)) = (self.nodes[iq.left].rel, self.nodes[iq.right].rel) {
317                    self.replace_with_pair_p(lq.parent, iq.left, iq.right);
318                } else {
319                    *self.nodes[iq.left].rel.mut_right() = iq.right;
320                    *self.nodes[iq.right].rel.mut_left() = iq.left;
321                }
322            }
323        };
324
325        self.destroy_node(idx, true);
326    }
327
328    fn replace_with_pair_p(&mut self, idx: usize, left: usize, right: usize) {
329        self.nodes[idx].node = Node::P(PNode { child: left });
330        self.nodes[left].rel = Rel::P(ChildOfP { parent: idx, next: right });
331        self.nodes[right].rel = Rel::P(ChildOfP { parent: idx, next: left });
332    }
333
334    fn replace_by_new_leaves(&mut self, idx: usize, leaves: &[T]) -> Result<Option<usize>, ReplacementError<T>> {
335        debug_assert!(!self.freelist.contains(&idx));
336        if leaves.is_empty() {
337            self.remove_node(idx);
338            Ok(None)
339        } else if leaves.len() == 1 {
340            self.destroy_node(idx, false);
341            self.nodes[idx].node = Node::L;
342            self.leaves
343                .insert_no_overwrite(leaves[0].clone(), idx)
344                .map_err(|e| ReplacementError::DuplicateLeaf(e.0))?;
345            Ok(Some(idx))
346        } else {
347            self.destroy_node(idx, false);
348
349            self.leaves.reserve(leaves.len());
350            if self.freelist.len() < leaves.len() {
351                self.nodes.reserve(leaves.len() - self.freelist.len());
352            }
353
354            let first_last = leaves.iter().rev().try_fold((None, None), |first_last, leaf| {
355                let leaf_node = self.add_node(TreeNode {
356                    rel: Rel::P(ChildOfP { parent: idx, next: first_last.1.unwrap_or(0) }),
357                    node: Node::L,
358                    red: Default::default(),
359                });
360                // TODO: T: Debug
361                self.leaves
362                    .insert_no_overwrite(leaf.clone(), leaf_node)
363                    .map_err(|e| ReplacementError::DuplicateLeaf(e.0))?;
364
365                Ok((first_last.0.or(Some(leaf_node)), Some(leaf_node)))
366            })?;
367
368            let (first, last) = (
369                first_last.0.expect("impossible, no first inserted node"),
370                first_last.1.expect("impossible, no last inserted node"),
371            );
372            // wrap circular list
373            self.nodes[first].rel.as_mut_p().next = last;
374            self.nodes[idx].node = Node::P(PNode { child: last });
375            Ok(Some(idx))
376        }
377    }
378
379    fn replace_node(&mut self, target: usize, source: usize) {
380        self.nodes[target].node = self.nodes[source].node;
381        self.nodes[target].red = self.nodes[source].red.clone();
382
383        match self.nodes[target].node {
384            Node::P(p) => {
385                let mut next = Some(p.child);
386                while let Some(current) = next {
387                    let r = self.nodes[current].rel.as_mut_p();
388                    next = if r.next != p.child { Some(r.next) } else { None };
389                    r.parent = target;
390                }
391            }
392            Node::Q(q) => {
393                self.nodes[q.left].rel.as_mut_lq().parent = target;
394                self.nodes[q.right].rel.as_mut_rq().parent = target;
395            }
396            Node::L => {
397                let leaf = self.leaves.remove_by_right(&source).expect("broken leaves map").0;
398                self.leaves.insert_no_overwrite(leaf, target).ok().expect("broken leaves map");
399            }
400        }
401
402        self.recycle_node(source);
403    }
404
405    fn collect_frontier(&self, mut v: Vec<T>, root: usize) -> Vec<T> {
406        match self.nodes[root].node {
407            Node::P(p) => {
408                let mut c = p.child;
409                loop {
410                    v = self.collect_frontier(v, c);
411                    c = self.nodes[c].rel.as_p().next;
412                    if c == p.child {
413                        break;
414                    }
415                }
416            }
417            Node::Q(q) => {
418                let mut c = q.left;
419                loop {
420                    v = self.collect_frontier(v, c);
421                    // TODO: iterator for Q children?
422                    c = match self.nodes[c].rel {
423                        Rel::LQ(lq) => lq.right,
424                        Rel::IQ(iq) => iq.right,
425                        Rel::RQ(_) => break,
426                        other => panic!("Not a Q-child: {:?} !", other),
427                    };
428                }
429            }
430            Node::L => v.push(self.leaves.get_by_right(&root).expect("broken leaves map").clone()),
431        };
432        v
433    }
434}
435
436// TODO: optimize, reduce allocations, refs and so on
437#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
438struct SortPair<T: Ord + Clone>(T, usize);
439
440impl<T: Clone + Eq + Hash + Ord> PQTree<T> {
441    /// Sorts the tree by "minimal order"
442    pub fn sort_minimal(&mut self) {
443        if !self.empty {
444            self.sort(ROOT, false);
445        }
446    }
447
448    /// Sorts the tree "lexicographically"
449    pub fn sort_lexicographically(&mut self) {
450        if !self.empty {
451            self.sort(ROOT, true);
452        }
453    }
454
455    fn sort(&mut self, idx: usize, lexicographically: bool) -> T {
456        match self.nodes[idx].node {
457            Node::P(PNode { child }) => self.sort_p(idx, child, lexicographically),
458            Node::Q(QNode { left, right }) => self.sort_q(idx, left, right, lexicographically),
459            Node::L => self.leaves.get_by_right(&idx).unwrap().clone(),
460        }
461    }
462
463    fn sort_p(&mut self, idx: usize, first_child: usize, lexicographically: bool) -> T {
464        let mut scratch = vec![];
465
466        let mut next = Some(first_child);
467        while let Some(current) = next {
468            next = {
469                let next = self.nodes[current].rel.next();
470                if next != first_child {
471                    Some(next)
472                } else {
473                    None
474                }
475            };
476            scratch.push(SortPair(self.sort(current, lexicographically), current));
477        }
478
479        scratch.sort_unstable();
480        let first = scratch[0].clone();
481
482        let last = scratch
483            .into_iter()
484            .map(|p| p.1)
485            .reduce(|a, b| {
486                self.nodes[a].rel.as_mut_p().next = b;
487                b
488            })
489            .unwrap();
490
491        self.nodes[last].rel.as_mut_p().next = first.1;
492        self.nodes[idx].node.as_mut_p().child = first.1;
493
494        first.0
495    }
496
497    fn sort_q(&mut self, idx: usize, left_child: usize, right_child: usize, lexicographically: bool) -> T {
498        // for even number of children we have to deal with case with middle min
499
500        let mut left = left_child;
501        let mut right = right_child;
502        let left_min = self.sort(left, lexicographically);
503        let right_min = self.sort(right, lexicographically);
504        let (mut min, need_reverse) = if right_min.gt(&left_min) { (left_min, false) } else { (right_min, true) };
505
506        loop {
507            // left and right already processed
508            left = self.nodes[left].rel.right();
509            if left == right {
510                // even case
511                break;
512            }
513
514            right = self.nodes[right].rel.left();
515            if left == right {
516                // odd case
517                let middle_min = self.sort(left, lexicographically);
518                if !lexicographically {
519                    min = min.min(middle_min);
520                }
521                break;
522            }
523
524            let left_min = self.sort(left, lexicographically);
525            let right_min = self.sort(right, lexicographically);
526            if !lexicographically {
527                min = min.min(left_min).min(right_min);
528            }
529        }
530
531        if need_reverse {
532            self.reverse_q(idx);
533        }
534
535        min
536    }
537}
538
539impl<T: Clone + Eq + Hash + Display> Display for PQTree<T> {
540    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
541        fn node_fmt<T>(
542            tree: &PQTree<T>,
543            idx: usize,
544            f: &mut Formatter<'_>,
545            mut mark_full: bool,
546            non_first: bool,
547        ) -> std::fmt::Result
548        where
549            T: Clone + Eq + Hash + Display,
550        {
551            if non_first {
552                write!(f, " ")?;
553            }
554
555            let marked_full = if mark_full && tree.nodes[idx].red.label == NodeLabel::Full {
556                mark_full = false;
557                write!(f, "<")?;
558                true
559            } else {
560                false
561            };
562
563            let TreeNode { node, .. } = &tree.nodes[idx];
564            match node {
565                Node::P(p) => {
566                    write!(f, "(")?;
567
568                    let mut p_idx = p.child;
569                    let mut not_first = false;
570                    loop {
571                        node_fmt(tree, p_idx, f, mark_full, not_first)?;
572                        p_idx = tree.nodes[p_idx].rel.as_p().next;
573                        if p_idx == p.child {
574                            break;
575                        }
576                        // not_first = !marked;
577                        not_first = true;
578                    }
579
580                    write!(f, ")")?;
581                }
582                Node::Q(q) => {
583                    write!(f, "[")?;
584
585                    let mut q_idx = q.left;
586                    let mut not_first = false;
587
588                    loop {
589                        node_fmt(tree, q_idx, f, mark_full, not_first)?;
590                        let TreeNode { rel, .. } = &tree.nodes[q_idx];
591                        match rel {
592                            Rel::LQ(LeftChildOfQ { right, .. }) | Rel::IQ(InteriorChildOfQ { right, .. }) => {
593                                not_first = true;
594                                q_idx = *right
595                            }
596                            _ => break,
597                        }
598                    }
599
600                    write!(f, "]")?;
601                }
602                Node::L => {
603                    write!(f, "{}", tree.leaves.get_by_right(&idx).expect("broken leaves map"))?;
604                }
605            };
606
607            if marked_full {
608                write!(f, ">")?;
609            }
610
611            Ok(())
612        }
613
614        if self.empty {
615            write!(f, "()")
616        } else {
617            node_fmt(self, ROOT, f, self.pertinent_root.is_some(), false).map(|_| ())
618        }
619    }
620}