222 lines
6.2 KiB
Rust
222 lines
6.2 KiB
Rust
use crate::flow::comparator::*;
|
|
use crate::flow::traversible::*;
|
|
use crate::func::fail::*;
|
|
|
|
fn and(_l: (), _r: ()) {}
|
|
|
|
struct SubsetContext<'a, T: MonadFail<'a, ()>, A: 'a, D: 'a + PartialEq> {
|
|
comparator: &'a dyn Comparator<A>,
|
|
n_subset: Arc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
|
n_superset: Arc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
|
k_l: Option<A>,
|
|
k_r: Option<A>,
|
|
t_superl: Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
|
t_superr: Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
|
k_super: A,
|
|
}
|
|
|
|
impl<'a, T: 'a + MonadFail<'a, ()>, A: 'a + Send + Clone, 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<()> {
|
|
T::la2(
|
|
algorithms::contains::t_contains(self.comparator, self.t_superl.clone(), k_sub.clone()),
|
|
T::la2(
|
|
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),
|
|
self.k_r,
|
|
),
|
|
and,
|
|
),
|
|
and,
|
|
)
|
|
}
|
|
|
|
fn on_e(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<()> {
|
|
T::la2(
|
|
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),
|
|
self.k_r,
|
|
),
|
|
and,
|
|
)
|
|
}
|
|
|
|
fn on_r(self, (t_subl, t_subr, k_sub): Split<'a, T, A, D>) -> T::F<()> {
|
|
T::la2(
|
|
algorithms::contains::t_contains(self.comparator, self.t_superr.clone(), k_sub.clone()),
|
|
T::la2(
|
|
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),
|
|
self.k_r,
|
|
),
|
|
and,
|
|
),
|
|
and,
|
|
)
|
|
}
|
|
|
|
fn test_unoptimised(self) -> T::F<()> {
|
|
let split = self.n_subset.split();
|
|
match self.comparator.compare(&split.2, &self.k_super) {
|
|
Comparison::L => self.on_l(split),
|
|
Comparison::E => self.on_e(split),
|
|
Comparison::R => self.on_r(split),
|
|
}
|
|
}
|
|
|
|
fn outside_l(&self) -> bool {
|
|
outside_l(self.comparator, &self.k_l, &self.k_super)
|
|
}
|
|
|
|
fn outside_r(&self) -> bool {
|
|
outside_r(self.comparator, &self.k_r, &self.k_super)
|
|
}
|
|
|
|
fn test_r_only(self) -> T::F<()> {
|
|
t_subset_of_t(
|
|
self.comparator,
|
|
self.n_subset.to_tree(),
|
|
self.t_superr,
|
|
self.k_l,
|
|
self.k_r,
|
|
)
|
|
}
|
|
|
|
fn test_l_only(self) -> T::F<()> {
|
|
t_subset_of_t(
|
|
self.comparator,
|
|
self.n_subset.to_tree(),
|
|
self.t_superl,
|
|
self.k_l,
|
|
self.k_r,
|
|
)
|
|
}
|
|
|
|
fn test_optimised(self) -> T::F<()> {
|
|
if self.outside_l() {
|
|
self.test_r_only()
|
|
} else if self.outside_r() {
|
|
self.test_l_only()
|
|
} else {
|
|
self.test_unoptimised()
|
|
}
|
|
}
|
|
}
|
|
|
|
fn outside_l<A>(comparator: &dyn Comparator<A>, k_l: &Option<A>, k_super: &A) -> bool {
|
|
if let Some(a_l) = k_l {
|
|
comparator.compare(a_l, k_super) == Comparison::R
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
fn outside_r<A>(comparator: &dyn Comparator<A>, k_r: &Option<A>, k_super: &A) -> bool {
|
|
if let Some(a_r) = k_r {
|
|
comparator.compare(a_r, k_super) == Comparison::L
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
pub fn n_subset_of_n<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>(
|
|
comparator: &'a dyn Comparator<A>,
|
|
n_subset: Arc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
|
n_superset: Arc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
|
k_l: Option<A>,
|
|
k_r: Option<A>,
|
|
) -> T::F<()> {
|
|
let (t_superl, t_superr, k_super) = n_superset.split();
|
|
SubsetContext {
|
|
comparator,
|
|
n_subset,
|
|
n_superset,
|
|
k_l,
|
|
k_r,
|
|
t_superl,
|
|
t_superr,
|
|
k_super,
|
|
}
|
|
.test_optimised()
|
|
}
|
|
|
|
pub fn r_subset_of_r_unoptimised<
|
|
'a,
|
|
T: MonadFail<'a, ()>,
|
|
A: 'a + Send + Clone,
|
|
D: 'a + PartialEq,
|
|
>(
|
|
comparator: &'a dyn Comparator<A>,
|
|
r_subset: Arc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
|
r_superset: Arc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
|
k_l: Option<A>,
|
|
k_r: Option<A>,
|
|
) -> T::F<()> {
|
|
T::bind2(
|
|
r_subset.resolve(),
|
|
r_superset.resolve(),
|
|
move |n_subset, n_superset| n_subset_of_n(comparator, n_subset, n_superset, k_l, k_r),
|
|
)
|
|
}
|
|
|
|
fn r_subset_of_r_optimised<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>(
|
|
r_subset: Arc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
|
r_superset: Arc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
|
comparator: &'a dyn Comparator<A>,
|
|
k_l: Option<A>,
|
|
k_r: Option<A>,
|
|
) -> <T as WeakFunctor<'a>>::F<()> {
|
|
if r_subset.data() == r_superset.data() {
|
|
T::pure(())
|
|
} else {
|
|
r_subset_of_r_unoptimised(comparator, r_subset, r_superset, k_l, k_r)
|
|
}
|
|
}
|
|
|
|
pub fn t_subset_of_t<'a, T: MonadFail<'a, ()>, A: 'a + Send + Clone, D: 'a + PartialEq>(
|
|
comparator: &'a dyn Comparator<A>,
|
|
t_subset: Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
|
t_superset: Arc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
|
k_l: Option<A>,
|
|
k_r: Option<A>,
|
|
) -> T::F<()> {
|
|
match (t_subset.refer(), t_superset.refer()) {
|
|
(None, _) => T::pure(()),
|
|
(Some(_), None) => T::fail(()),
|
|
(Some(r_subset), Some(r_superset)) => {
|
|
r_subset_of_r_optimised(r_subset, r_superset, comparator, k_l, k_r)
|
|
}
|
|
}
|
|
}
|