result-based subset check
This commit is contained in:
parent
4809d08082
commit
0abdfe9751
@ -15,9 +15,7 @@ pub enum Comparison {
|
|||||||
R,
|
R,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn and(left: bool, right: bool) -> bool {
|
fn and(_l: (), _r: ()) -> () {}
|
||||||
left && right
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns [`Comparison`] saying which value is smaller.
|
/// Returns [`Comparison`] saying which value is smaller.
|
||||||
///
|
///
|
||||||
@ -69,45 +67,45 @@ 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 + Monad, A: 'a, D: 'a + PartialEq>(
|
pub fn n_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
comparator: &'a dyn Comparator<A>,
|
comparator: &'a dyn Comparator<A>,
|
||||||
n_set: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
n_set: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
||||||
key: Rc<A>,
|
key: Rc<A>,
|
||||||
) -> T::F<'a, bool> {
|
) -> T::F<'a, ()> {
|
||||||
let (t_setl, t_setr, k_set) = n_set.split();
|
let (t_setl, t_setr, k_set) = n_set.split();
|
||||||
match comparator.pick_smaller(key.as_ref(), k_set.as_ref()) {
|
match comparator.pick_smaller(key.as_ref(), k_set.as_ref()) {
|
||||||
Comparison::L => t_contains(comparator, t_setl, key),
|
Comparison::L => t_contains(comparator, t_setl, key),
|
||||||
Comparison::E => T::pure(true),
|
Comparison::E => T::pure(()),
|
||||||
Comparison::R => t_contains(comparator, t_setr, key),
|
Comparison::R => t_contains(comparator, t_setr, key),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn r_contains<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
pub fn r_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
comparator: &'a dyn Comparator<A>,
|
comparator: &'a dyn Comparator<A>,
|
||||||
r_set: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
r_set: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
||||||
key: Rc<A>,
|
key: Rc<A>,
|
||||||
) -> T::F<'a, bool> {
|
) -> T::F<'a, ()> {
|
||||||
T::bind(r_set.resolve(), |n_set| n_contains(comparator, n_set, key))
|
T::bind(r_set.resolve(), |n_set| n_contains(comparator, n_set, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn t_contains<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
pub fn t_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
comparator: &'a dyn Comparator<A>,
|
comparator: &'a dyn Comparator<A>,
|
||||||
t_set: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
t_set: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
key: Rc<A>,
|
key: Rc<A>,
|
||||||
) -> T::F<'a, bool> {
|
) -> T::F<'a, ()> {
|
||||||
match t_set.refer() {
|
match t_set.refer() {
|
||||||
Some(r_set) => r_contains(comparator, r_set, key),
|
Some(r_set) => r_contains(comparator, r_set, key),
|
||||||
None => T::pure(false),
|
None => T::fail(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn n_subset_of_n<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
pub fn n_subset_of_n<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
comparator: &'a dyn Comparator<A>,
|
comparator: &'a dyn Comparator<A>,
|
||||||
n_subset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
n_subset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
||||||
n_superset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
n_superset: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
||||||
k_l: Option<Rc<A>>,
|
k_l: Option<Rc<A>>,
|
||||||
k_r: Option<Rc<A>>,
|
k_r: Option<Rc<A>>,
|
||||||
) -> T::F<'a, bool> {
|
) -> T::F<'a, ()> {
|
||||||
let (t_superl, t_superr, k_super) = n_superset.split();
|
let (t_superl, t_superr, k_super) = n_superset.split();
|
||||||
if let Some(ref a_l) = k_l {
|
if let Some(ref a_l) = k_l {
|
||||||
if let Comparison::R = comparator.pick_smaller(a_l.as_ref(), k_super.as_ref()) {
|
if let Comparison::R = comparator.pick_smaller(a_l.as_ref(), k_super.as_ref()) {
|
||||||
@ -159,13 +157,13 @@ pub fn n_subset_of_n<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn r_subset_of_r<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
pub fn r_subset_of_r<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>(
|
||||||
comparator: &'a dyn Comparator<A>,
|
comparator: &'a dyn Comparator<A>,
|
||||||
r_subset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
r_subset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
||||||
r_superset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
r_superset: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
||||||
k_l: Option<Rc<A>>,
|
k_l: Option<Rc<A>>,
|
||||||
k_r: Option<Rc<A>>,
|
k_r: Option<Rc<A>>,
|
||||||
) -> T::F<'a, bool> {
|
) -> T::F<'a, ()> {
|
||||||
T::join(T::la2(
|
T::join(T::la2(
|
||||||
move |n_subset, n_superset| n_subset_of_n(comparator, n_subset, n_superset, k_l, k_r),
|
move |n_subset, n_superset| n_subset_of_n(comparator, n_subset, n_superset, k_l, k_r),
|
||||||
r_subset.resolve(),
|
r_subset.resolve(),
|
||||||
@ -173,19 +171,19 @@ pub fn r_subset_of_r<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn t_subset_of_t<'a, T: Monad, A, D: 'a + PartialEq>(
|
pub fn t_subset_of_t<'a, T: MonadFail<()>, A, D: 'a + PartialEq>(
|
||||||
comparator: &'a dyn Comparator<A>,
|
comparator: &'a dyn Comparator<A>,
|
||||||
t_subset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
t_subset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
t_superset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
t_superset: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
k_l: Option<Rc<A>>,
|
k_l: Option<Rc<A>>,
|
||||||
k_r: Option<Rc<A>>,
|
k_r: Option<Rc<A>>,
|
||||||
) -> T::F<'a, bool> {
|
) -> T::F<'a, ()> {
|
||||||
match (t_subset.refer(), t_superset.refer()) {
|
match (t_subset.refer(), t_superset.refer()) {
|
||||||
(None, _) => T::pure(true),
|
(None, _) => T::pure(()),
|
||||||
(Some(_), None) => T::pure(false),
|
(Some(_), None) => T::fail(()),
|
||||||
(Some(r_subset), Some(r_superset)) => {
|
(Some(r_subset), Some(r_superset)) => {
|
||||||
if r_subset.data() == r_superset.data() {
|
if r_subset.data() == r_superset.data() {
|
||||||
T::pure(true)
|
T::pure(())
|
||||||
} else {
|
} else {
|
||||||
r_subset_of_r(comparator, r_subset, r_superset, k_l, k_r)
|
r_subset_of_r(comparator, r_subset, r_superset, k_l, k_r)
|
||||||
}
|
}
|
||||||
|
@ -34,23 +34,38 @@ pub enum UnbalancedTree<'a, T: 'a + Monad, A: 'a> {
|
|||||||
Node(Rc<UnbalancedReference<'a, T, A>>),
|
Node(Rc<UnbalancedReference<'a, T, A>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, A: 'a + Display> Display for UnbalancedNode<'a, classes::solo::SoloClass, A> {
|
impl<'a, T: 'a + Monad, A: 'a + Display> Display for UnbalancedNode<'a, T, A>
|
||||||
|
where
|
||||||
|
UnbalancedReference<'a, T, A>: std::fmt::Display,
|
||||||
|
{
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_fmt(format_args!("({} {} {})", self.cl, self.key, self.cr))
|
f.write_fmt(format_args!("({} {} {})", self.cl, self.key, self.cr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: 'a + Monad, A: 'a + Display> Display for UnbalancedTree<'a, T, A>
|
||||||
|
where
|
||||||
|
UnbalancedReference<'a, T, A>: std::fmt::Display,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
UnbalancedTree::Leaf => f.write_fmt(format_args!(".")),
|
||||||
|
UnbalancedTree::Node(reference) => f.write_fmt(format_args!("{}", reference)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, A: 'a + Display> Display for UnbalancedReference<'a, classes::solo::SoloClass, A> {
|
impl<'a, A: 'a + Display> Display for UnbalancedReference<'a, classes::solo::SoloClass, A> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_fmt(format_args!("{}", self.0()))
|
f.write_fmt(format_args!("{}", self.0()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, A: 'a + Display> Display for UnbalancedTree<'a, classes::solo::SoloClass, A> {
|
impl<'a, A: 'a + Display> Display for UnbalancedReference<'a, classes::result::ResultClass<()>, A> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self.0() {
|
||||||
UnbalancedTree::Leaf => f.write_fmt(format_args!(".")),
|
Ok(node) => f.write_fmt(format_args!("{}", node)),
|
||||||
UnbalancedTree::Node(reference) => f.write_fmt(format_args!("{}", reference)),
|
Err(()) => f.write_fmt(format_args!("~")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,60 +181,41 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple_slices() {
|
fn test_simple_slices() {
|
||||||
let ctr: Rc<UnbalancedConstructor<classes::solo::SoloClass, _>> =
|
let ctr: Rc<UnbalancedConstructor<classes::result::ResultClass<()>, _>> =
|
||||||
UnbalancedConstructor::rc(Box::new(|node| node));
|
UnbalancedConstructor::rc(Box::new(|node| Ok(node)));
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let t_set = ctr.from_slice(&mut rng, &[0]);
|
let t_set = ctr.from_slice(&mut rng, &[0]);
|
||||||
assert!(t_contains(&DefaultComparator, t_set.clone(), 0.into()));
|
assert!(t_contains(&DefaultComparator, t_set.clone(), 0.into()).is_ok());
|
||||||
assert!(!t_contains(&DefaultComparator, t_set.clone(), 1.into()));
|
assert!(t_contains(&DefaultComparator, t_set.clone(), 1.into()).is_err());
|
||||||
assert!(t_subset_of_t(
|
assert!(
|
||||||
&DefaultComparator,
|
t_subset_of_t(&DefaultComparator, t_set.clone(), t_set.clone(), None, None).is_ok()
|
||||||
t_set.clone(),
|
);
|
||||||
t_set.clone(),
|
assert!(t_subset_of_t(&DefaultComparator, t_set.clone(), ctr.leaf(), None, None).is_err());
|
||||||
None,
|
assert!(t_subset_of_t(&DefaultComparator, ctr.leaf(), t_set.clone(), None, None).is_ok());
|
||||||
None
|
assert!(t_subset_of_t(&DefaultComparator, ctr.leaf(), ctr.leaf(), None, None).is_ok());
|
||||||
));
|
|
||||||
assert!(!t_subset_of_t(
|
|
||||||
&DefaultComparator,
|
|
||||||
t_set.clone(),
|
|
||||||
ctr.leaf(),
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
));
|
|
||||||
assert!(t_subset_of_t(
|
|
||||||
&DefaultComparator,
|
|
||||||
ctr.leaf(),
|
|
||||||
t_set.clone(),
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
));
|
|
||||||
assert!(t_subset_of_t(
|
|
||||||
&DefaultComparator,
|
|
||||||
ctr.leaf(),
|
|
||||||
ctr.leaf(),
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
));
|
|
||||||
assert!(t_subset_of_t(
|
assert!(t_subset_of_t(
|
||||||
&DefaultComparator,
|
&DefaultComparator,
|
||||||
ctr.from_slice(&mut rng, &[0, 1, 2, 4, 5, 6, 7]),
|
ctr.from_slice(&mut rng, &[0, 1, 2, 4, 5, 6, 7]),
|
||||||
ctr.from_slice(&mut rng, &[0, 1, 2, 3, 4, 5, 6, 7]),
|
ctr.from_slice(&mut rng, &[0, 1, 2, 3, 4, 5, 6, 7]),
|
||||||
None,
|
None,
|
||||||
None
|
None
|
||||||
));
|
)
|
||||||
assert!(!t_subset_of_t(
|
.is_ok());
|
||||||
|
assert!(t_subset_of_t(
|
||||||
&DefaultComparator,
|
&DefaultComparator,
|
||||||
ctr.from_slice(&mut rng, &[0, 1, 2, 3, 4, 5, 6, 7]),
|
ctr.from_slice(&mut rng, &[0, 1, 2, 3, 4, 5, 6, 7]),
|
||||||
ctr.from_slice(&mut rng, &[0, 1, 2, 4, 5, 6, 7]),
|
ctr.from_slice(&mut rng, &[0, 1, 2, 4, 5, 6, 7]),
|
||||||
None,
|
None,
|
||||||
None
|
None
|
||||||
));
|
)
|
||||||
|
.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_random_slices() {
|
fn test_random_slices() {
|
||||||
let ctr: Rc<UnbalancedConstructor<classes::solo::SoloClass, _>> =
|
let ctr: Rc<UnbalancedConstructor<classes::result::ResultClass<()>, _>> =
|
||||||
UnbalancedConstructor::rc(Box::new(|node| node));
|
UnbalancedConstructor::rc(Box::new(|node| Ok(node)));
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let big: Vec<i32> = (0..(rng.gen_range(2..10))).collect();
|
let big: Vec<i32> = (0..(rng.gen_range(2..10))).collect();
|
||||||
@ -238,19 +234,21 @@ mod tests {
|
|||||||
t_big.clone(),
|
t_big.clone(),
|
||||||
None,
|
None,
|
||||||
None
|
None
|
||||||
),
|
)
|
||||||
|
.is_ok(),
|
||||||
"{} should be a subset of {}",
|
"{} should be a subset of {}",
|
||||||
t_small,
|
t_small,
|
||||||
t_big,
|
t_big,
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!t_subset_of_t(
|
t_subset_of_t(
|
||||||
&DefaultComparator,
|
&DefaultComparator,
|
||||||
t_big.clone(),
|
t_big.clone(),
|
||||||
t_small.clone(),
|
t_small.clone(),
|
||||||
None,
|
None,
|
||||||
None
|
None
|
||||||
),
|
)
|
||||||
|
.is_err(),
|
||||||
"{} should not be a subset of {}",
|
"{} should not be a subset of {}",
|
||||||
t_big,
|
t_big,
|
||||||
t_small,
|
t_small,
|
||||||
@ -258,10 +256,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TracedMonad =
|
||||||
|
classes::composition::CompositionClass<TracedClass, classes::result::ResultClass<()>>;
|
||||||
|
|
||||||
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
fn trace_one_slice() {
|
fn trace_one_slice() {
|
||||||
let ctr: Rc<UnbalancedConstructor<TracedClass, _>> =
|
let ctr: Rc<UnbalancedConstructor<TracedMonad, _>> =
|
||||||
UnbalancedConstructor::rc(Box::new(|node| TracedClass::pure(node).after_resolution()));
|
UnbalancedConstructor::rc(Box::new(|node| TracedMonad::pure(node).after_resolution()));
|
||||||
// let mut rng = rand::thread_rng();
|
// let mut rng = rand::thread_rng();
|
||||||
let mut rng = rand::rngs::StdRng::seed_from_u64(426);
|
let mut rng = rand::rngs::StdRng::seed_from_u64(426);
|
||||||
let big: Vec<i32> = (0..(rng.gen_range(1000..2000))).collect();
|
let big: Vec<i32> = (0..(rng.gen_range(1000..2000))).collect();
|
||||||
@ -280,7 +282,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
assert!(traced.a);
|
assert!(traced.a.is_ok());
|
||||||
// panic!("{:?}", traced.render().to_vec());
|
// panic!("{:?}", traced.render().to_vec());D
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user