traversible::algorithms
This commit is contained in:
parent
5863532338
commit
a90ea90529
@ -1,5 +1,6 @@
|
|||||||
//! Traversible binary trees.
|
//! Traversible binary trees.
|
||||||
|
|
||||||
|
pub mod algorithms;
|
||||||
pub mod unbalanced;
|
pub mod unbalanced;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -66,127 +67,3 @@ pub trait TraversibleBinaryReference<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq
|
|||||||
pub trait TraversibleBinaryTree<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>: 'a {
|
pub trait TraversibleBinaryTree<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>: 'a {
|
||||||
fn refer(&self) -> Option<Rc<dyn TraversibleBinaryReference<'a, T, A, D>>>;
|
fn refer(&self) -> Option<Rc<dyn TraversibleBinaryReference<'a, T, A, D>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn n_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
|
||||||
comparator: &'a dyn Comparator<A>,
|
|
||||||
n_set: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
|
||||||
key: Rc<A>,
|
|
||||||
) -> T::F<'a, ()> {
|
|
||||||
let (t_setl, t_setr, k_set) = n_set.split();
|
|
||||||
match comparator.pick_smaller(key.as_ref(), k_set.as_ref()) {
|
|
||||||
Comparison::L => t_contains(comparator, t_setl, key),
|
|
||||||
Comparison::E => T::pure(()),
|
|
||||||
Comparison::R => t_contains(comparator, t_setr, key),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn r_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
|
||||||
comparator: &'a dyn Comparator<A>,
|
|
||||||
r_set: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
|
||||||
key: Rc<A>,
|
|
||||||
) -> T::F<'a, ()> {
|
|
||||||
T::bind(r_set.resolve(), |n_set| n_contains(comparator, n_set, key))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn t_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
|
||||||
comparator: &'a dyn Comparator<A>,
|
|
||||||
t_set: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
|
||||||
key: Rc<A>,
|
|
||||||
) -> T::F<'a, ()> {
|
|
||||||
match t_set.refer() {
|
|
||||||
Some(r_set) => r_contains(comparator, r_set, key),
|
|
||||||
None => T::fail(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn n_subset_of_n<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
|
||||||
comparator: &'a dyn Comparator<A>,
|
|
||||||
n_subset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
|
||||||
n_superset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
|
||||||
k_l: Option<Rc<A>>,
|
|
||||||
k_r: Option<Rc<A>>,
|
|
||||||
) -> T::F<'a, ()> {
|
|
||||||
let (t_superl, t_superr, k_super) = n_superset.split();
|
|
||||||
if let Some(ref a_l) = k_l {
|
|
||||||
if let Comparison::R = comparator.pick_smaller(a_l.as_ref(), k_super.as_ref()) {
|
|
||||||
return t_subset_of_t(comparator, n_subset.to_tree(), t_superr, k_l, k_r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(ref a_r) = k_r {
|
|
||||||
if let Comparison::L = comparator.pick_smaller(a_r.as_ref(), k_super.as_ref()) {
|
|
||||||
return t_subset_of_t(comparator, n_subset.to_tree(), t_superl, k_l, k_r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let (t_subl, t_subr, k_sub) = n_subset.split();
|
|
||||||
match comparator.pick_smaller(k_sub.as_ref(), k_super.as_ref()) {
|
|
||||||
Comparison::L => T::la2(
|
|
||||||
and,
|
|
||||||
t_contains(comparator, t_superl.clone(), k_sub.clone()),
|
|
||||||
T::la2(
|
|
||||||
and,
|
|
||||||
t_subset_of_t(comparator, t_subl, t_superl, k_l, Some(k_sub.clone())),
|
|
||||||
t_subset_of_t(
|
|
||||||
comparator,
|
|
||||||
t_subr,
|
|
||||||
n_superset.to_tree(),
|
|
||||||
Some(k_sub.clone()),
|
|
||||||
k_r,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Comparison::E => T::la2(
|
|
||||||
and,
|
|
||||||
t_subset_of_t(comparator, t_subl, t_superl, k_l, Some(k_sub.clone())),
|
|
||||||
t_subset_of_t(comparator, t_subr, t_superr, Some(k_sub.clone()), k_r),
|
|
||||||
),
|
|
||||||
Comparison::R => T::la2(
|
|
||||||
and,
|
|
||||||
t_contains(comparator, t_superr.clone(), k_sub.clone()),
|
|
||||||
T::la2(
|
|
||||||
and,
|
|
||||||
t_subset_of_t(
|
|
||||||
comparator,
|
|
||||||
t_subl,
|
|
||||||
n_superset.to_tree(),
|
|
||||||
k_l,
|
|
||||||
Some(k_sub.clone()),
|
|
||||||
),
|
|
||||||
t_subset_of_t(comparator, t_subr, t_superr, Some(k_sub.clone()), k_r),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn r_subset_of_r<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
|
||||||
comparator: &'a dyn Comparator<A>,
|
|
||||||
r_subset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
|
||||||
r_superset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
|
||||||
k_l: Option<Rc<A>>,
|
|
||||||
k_r: Option<Rc<A>>,
|
|
||||||
) -> T::F<'a, ()> {
|
|
||||||
T::join(T::la2(
|
|
||||||
move |n_subset, n_superset| n_subset_of_n(comparator, n_subset, n_superset, k_l, k_r),
|
|
||||||
r_subset.resolve(),
|
|
||||||
r_superset.resolve(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn t_subset_of_t<'a, T: MonadFail<()>, A, D: 'a + PartialEq>(
|
|
||||||
comparator: &'a dyn Comparator<A>,
|
|
||||||
t_subset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
|
||||||
t_superset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
|
||||||
k_l: Option<Rc<A>>,
|
|
||||||
k_r: Option<Rc<A>>,
|
|
||||||
) -> T::F<'a, ()> {
|
|
||||||
match (t_subset.refer(), t_superset.refer()) {
|
|
||||||
(None, _) => T::pure(()),
|
|
||||||
(Some(_), None) => T::fail(()),
|
|
||||||
(Some(r_subset), Some(r_superset)) => {
|
|
||||||
if r_subset.data() == r_superset.data() {
|
|
||||||
T::pure(())
|
|
||||||
} else {
|
|
||||||
r_subset_of_r(comparator, r_subset, r_superset, k_l, k_r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
2
src/flow/traversible/algorithms.rs
Normal file
2
src/flow/traversible/algorithms.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod contains;
|
||||||
|
pub mod subset;
|
33
src/flow/traversible/algorithms/contains.rs
Normal file
33
src/flow/traversible/algorithms/contains.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use crate::flow::traversible::*;
|
||||||
|
|
||||||
|
pub fn n_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
|
comparator: &'a dyn Comparator<A>,
|
||||||
|
n_set: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
||||||
|
key: Rc<A>,
|
||||||
|
) -> T::F<'a, ()> {
|
||||||
|
let (t_setl, t_setr, k_set) = n_set.split();
|
||||||
|
match comparator.pick_smaller(key.as_ref(), k_set.as_ref()) {
|
||||||
|
Comparison::L => t_contains(comparator, t_setl, key),
|
||||||
|
Comparison::E => T::pure(()),
|
||||||
|
Comparison::R => t_contains(comparator, t_setr, key),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn r_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
|
comparator: &'a dyn Comparator<A>,
|
||||||
|
r_set: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
||||||
|
key: Rc<A>,
|
||||||
|
) -> T::F<'a, ()> {
|
||||||
|
T::bind(r_set.resolve(), |n_set| n_contains(comparator, n_set, key))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn t_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
|
comparator: &'a dyn Comparator<A>,
|
||||||
|
t_set: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
|
key: Rc<A>,
|
||||||
|
) -> T::F<'a, ()> {
|
||||||
|
match t_set.refer() {
|
||||||
|
Some(r_set) => r_contains(comparator, r_set, key),
|
||||||
|
None => T::fail(()),
|
||||||
|
}
|
||||||
|
}
|
159
src/flow/traversible/algorithms/subset.rs
Normal file
159
src/flow/traversible/algorithms/subset.rs
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
use crate::flow::traversible::*;
|
||||||
|
|
||||||
|
struct SubsetContext<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq> {
|
||||||
|
comparator: &'a dyn Comparator<A>,
|
||||||
|
n_subset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
||||||
|
n_superset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
||||||
|
k_l: Option<Rc<A>>,
|
||||||
|
k_r: Option<Rc<A>>,
|
||||||
|
t_superl: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
|
t_superr: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
|
k_super: Rc<A>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq> SubsetContext<'a, T, A, D> {
|
||||||
|
fn on_l(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<'a, ()> {
|
||||||
|
T::la2(
|
||||||
|
and,
|
||||||
|
algorithms::contains::t_contains(self.comparator, self.t_superl.clone(), k_sub.clone()),
|
||||||
|
T::la2(
|
||||||
|
and,
|
||||||
|
t_subset_of_t(
|
||||||
|
self.comparator,
|
||||||
|
t_subl,
|
||||||
|
self.t_superl,
|
||||||
|
self.k_l,
|
||||||
|
Some(k_sub.clone()),
|
||||||
|
),
|
||||||
|
t_subset_of_t(
|
||||||
|
self.comparator,
|
||||||
|
t_subr,
|
||||||
|
self.n_superset.to_tree(),
|
||||||
|
Some(k_sub.clone()),
|
||||||
|
self.k_r,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_e(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<'a, ()> {
|
||||||
|
T::la2(
|
||||||
|
and,
|
||||||
|
t_subset_of_t(
|
||||||
|
self.comparator,
|
||||||
|
t_subl,
|
||||||
|
self.t_superl,
|
||||||
|
self.k_l,
|
||||||
|
Some(k_sub.clone()),
|
||||||
|
),
|
||||||
|
t_subset_of_t(
|
||||||
|
self.comparator,
|
||||||
|
t_subr,
|
||||||
|
self.t_superr,
|
||||||
|
Some(k_sub.clone()),
|
||||||
|
self.k_r,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_r(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<'a, ()> {
|
||||||
|
T::la2(
|
||||||
|
and,
|
||||||
|
algorithms::contains::t_contains(self.comparator, self.t_superr.clone(), k_sub.clone()),
|
||||||
|
T::la2(
|
||||||
|
and,
|
||||||
|
t_subset_of_t(
|
||||||
|
self.comparator,
|
||||||
|
t_subl,
|
||||||
|
self.n_superset.to_tree(),
|
||||||
|
self.k_l,
|
||||||
|
Some(k_sub.clone()),
|
||||||
|
),
|
||||||
|
t_subset_of_t(
|
||||||
|
self.comparator,
|
||||||
|
t_subr,
|
||||||
|
self.t_superr,
|
||||||
|
Some(k_sub.clone()),
|
||||||
|
self.k_r,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test(self) -> T::F<'a, ()> {
|
||||||
|
let split = self.n_subset.split();
|
||||||
|
match self
|
||||||
|
.comparator
|
||||||
|
.pick_smaller(split.2.as_ref(), self.k_super.as_ref())
|
||||||
|
{
|
||||||
|
Comparison::L => self.on_l(split),
|
||||||
|
Comparison::E => self.on_e(split),
|
||||||
|
Comparison::R => self.on_r(split),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn n_subset_of_n<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
|
comparator: &'a dyn Comparator<A>,
|
||||||
|
n_subset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
||||||
|
n_superset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
||||||
|
k_l: Option<Rc<A>>,
|
||||||
|
k_r: Option<Rc<A>>,
|
||||||
|
) -> T::F<'a, ()> {
|
||||||
|
let (t_superl, t_superr, k_super) = n_superset.split();
|
||||||
|
if let Some(ref a_l) = k_l {
|
||||||
|
if let Comparison::R = comparator.pick_smaller(a_l.as_ref(), k_super.as_ref()) {
|
||||||
|
return t_subset_of_t(comparator, n_subset.to_tree(), t_superr, k_l, k_r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(ref a_r) = k_r {
|
||||||
|
if let Comparison::L = comparator.pick_smaller(a_r.as_ref(), k_super.as_ref()) {
|
||||||
|
return t_subset_of_t(comparator, n_subset.to_tree(), t_superl, k_l, k_r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SubsetContext {
|
||||||
|
comparator,
|
||||||
|
n_subset,
|
||||||
|
n_superset,
|
||||||
|
k_l,
|
||||||
|
k_r,
|
||||||
|
t_superl,
|
||||||
|
t_superr,
|
||||||
|
k_super,
|
||||||
|
}
|
||||||
|
.test()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn r_subset_of_r<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
|
comparator: &'a dyn Comparator<A>,
|
||||||
|
r_subset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
||||||
|
r_superset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
||||||
|
k_l: Option<Rc<A>>,
|
||||||
|
k_r: Option<Rc<A>>,
|
||||||
|
) -> T::F<'a, ()> {
|
||||||
|
T::join(T::la2(
|
||||||
|
move |n_subset, n_superset| n_subset_of_n(comparator, n_subset, n_superset, k_l, k_r),
|
||||||
|
r_subset.resolve(),
|
||||||
|
r_superset.resolve(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn t_subset_of_t<'a, T: MonadFail<()>, A, D: 'a + PartialEq>(
|
||||||
|
comparator: &'a dyn Comparator<A>,
|
||||||
|
t_subset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
|
t_superset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
|
k_l: Option<Rc<A>>,
|
||||||
|
k_r: Option<Rc<A>>,
|
||||||
|
) -> T::F<'a, ()> {
|
||||||
|
match (t_subset.refer(), t_superset.refer()) {
|
||||||
|
(None, _) => T::pure(()),
|
||||||
|
(Some(_), None) => T::fail(()),
|
||||||
|
(Some(r_subset), Some(r_superset)) => {
|
||||||
|
if r_subset.data() == r_superset.data() {
|
||||||
|
T::pure(())
|
||||||
|
} else {
|
||||||
|
r_subset_of_r(comparator, r_subset, r_superset, k_l, k_r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -175,7 +175,7 @@ mod tests {
|
|||||||
|
|
||||||
use crate::std::tracing::*;
|
use crate::std::tracing::*;
|
||||||
|
|
||||||
use super::*;
|
use super::{algorithms::contains::*, algorithms::subset::*, *};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple_slices() {
|
fn test_simple_slices() {
|
||||||
|
Loading…
Reference in New Issue
Block a user