Compare commits
No commits in common. "3f6d290f5c61e60139b62befdf933e2785e8d6a0" and "5d604d283475c7a7fc4c093f13d9d6c0d9390cb9" have entirely different histories.
3f6d290f5c
...
5d604d2834
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -1,3 +1 @@
|
||||
{
|
||||
"rust-analyzer.showUnlinkedFileNotification": false
|
||||
}
|
||||
{}
|
@ -18,4 +18,3 @@ radn-derive = { path = "radn-derive" }
|
||||
|
||||
[dev-dependencies]
|
||||
sha2 = "0.10.6"
|
||||
rand = "0.8.5"
|
||||
|
@ -1,7 +1,5 @@
|
||||
//! Traversible binary trees.
|
||||
|
||||
pub mod unbalanced;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::func::*;
|
||||
@ -52,24 +50,24 @@ pub type Split<'a, T, A, D> = (
|
||||
Rc<A>,
|
||||
);
|
||||
|
||||
pub trait TraversibleBinaryNode<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>: 'a {
|
||||
pub trait TraversibleBinaryNode<'a, T: Monad, A, D: 'a + PartialEq>: 'a {
|
||||
fn split(&self) -> Split<'a, T, A, D>;
|
||||
|
||||
fn to_tree(self: Rc<Self>) -> Rc<dyn TraversibleBinaryTree<'a, T, A, D>>;
|
||||
}
|
||||
|
||||
pub trait TraversibleBinaryReference<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>: 'a {
|
||||
pub trait TraversibleBinaryReference<'a, T: Monad, A, D: 'a + PartialEq>: 'a {
|
||||
fn resolve(&self) -> <T as WeakFunctor>::F<'a, Rc<dyn TraversibleBinaryNode<'a, T, A, D>>>;
|
||||
|
||||
/// This should be enough to compare reference for equality.
|
||||
fn data(&self) -> D;
|
||||
}
|
||||
|
||||
pub trait TraversibleBinaryTree<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>: 'a {
|
||||
pub trait TraversibleBinaryTree<'a, T: Monad, A, D: 'a + PartialEq>: 'a {
|
||||
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: Monad, A, D: 'a + PartialEq>(
|
||||
comparator: &'a dyn Comparator<A>,
|
||||
n_set: Rc<dyn TraversibleBinaryNode<'a, T, A, D>>,
|
||||
key: Rc<A>,
|
||||
@ -82,7 +80,7 @@ pub fn n_contains<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn r_contains<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
||||
pub fn r_contains<'a, T: Monad, A, D: 'a + PartialEq>(
|
||||
comparator: &'a dyn Comparator<A>,
|
||||
r_set: Rc<dyn TraversibleBinaryReference<'a, T, A, D>>,
|
||||
key: Rc<A>,
|
||||
@ -90,7 +88,7 @@ pub fn r_contains<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
||||
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: Monad, A, D: 'a + PartialEq>(
|
||||
comparator: &'a dyn Comparator<A>,
|
||||
t_set: Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||
key: Rc<A>,
|
||||
@ -101,7 +99,7 @@ pub fn t_contains<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn n_subset_of_n<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
||||
pub fn n_subset_of_n<'a, T: Monad, 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>>,
|
||||
@ -130,7 +128,7 @@ pub fn n_subset_of_n<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
||||
t_subset_of_t(
|
||||
comparator,
|
||||
t_subr,
|
||||
n_superset.to_tree(),
|
||||
n_subset.to_tree(),
|
||||
Some(k_sub.clone()),
|
||||
k_r,
|
||||
),
|
||||
@ -149,7 +147,7 @@ pub fn n_subset_of_n<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>(
|
||||
t_subset_of_t(
|
||||
comparator,
|
||||
t_subl,
|
||||
n_superset.to_tree(),
|
||||
n_subset.to_tree(),
|
||||
k_l,
|
||||
Some(k_sub.clone()),
|
||||
),
|
||||
@ -159,7 +157,7 @@ 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: Monad, 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>>,
|
||||
|
@ -1,258 +0,0 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::func::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub struct UnbalancedData;
|
||||
|
||||
impl PartialEq for UnbalancedData {
|
||||
fn eq(&self, _other: &Self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[allow(clippy::partialeq_ne_impl)]
|
||||
fn ne(&self, _other: &Self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UnbalancedNode<'a, T: 'a + Monad, A: 'a> {
|
||||
cl: Rc<UnbalancedTree<'a, T, A>>,
|
||||
cr: Rc<UnbalancedTree<'a, T, A>>,
|
||||
key: Rc<A>,
|
||||
}
|
||||
|
||||
pub type UnbalancedResolution<'a, T, A> = <T as WeakFunctor>::F<'a, Rc<UnbalancedNode<'a, T, A>>>;
|
||||
|
||||
pub struct UnbalancedReference<'a, T: 'a + Monad, A: 'a>(
|
||||
Box<dyn 'a + Fn() -> UnbalancedResolution<'a, T, A>>,
|
||||
);
|
||||
|
||||
pub enum UnbalancedTree<'a, T: 'a + Monad, A: 'a> {
|
||||
Leaf,
|
||||
Node(Rc<UnbalancedReference<'a, T, A>>),
|
||||
}
|
||||
|
||||
impl<'a, A: 'a + Display> Display for UnbalancedNode<'a, classes::solo::SoloClass, A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!("({} {} {})", self.cl, self.key, self.cr))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, A: 'a + Display> Display for UnbalancedReference<'a, classes::solo::SoloClass, A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!("{}", self.0()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, A: 'a + Display> Display for UnbalancedTree<'a, classes::solo::SoloClass, A> {
|
||||
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, T: 'a + Monad, A: 'a> TraversibleBinaryNode<'a, T, A, UnbalancedData>
|
||||
for UnbalancedNode<'a, T, A>
|
||||
{
|
||||
fn split(&self) -> Split<'a, T, A, UnbalancedData> {
|
||||
(self.cl.clone(), self.cr.clone(), self.key.clone())
|
||||
}
|
||||
|
||||
fn to_tree(self: Rc<Self>) -> Rc<dyn TraversibleBinaryTree<'a, T, A, UnbalancedData>> {
|
||||
Rc::new(UnbalancedTree::Node(Rc::new(UnbalancedReference(
|
||||
Box::new(move || T::pure(self.clone())),
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: 'a + Monad, A: 'a> TraversibleBinaryReference<'a, T, A, UnbalancedData>
|
||||
for UnbalancedReference<'a, T, A>
|
||||
{
|
||||
fn resolve(
|
||||
&self,
|
||||
) -> <T as WeakFunctor>::F<'a, Rc<dyn TraversibleBinaryNode<'a, T, A, UnbalancedData>>> {
|
||||
<T as Functor>::fmap(
|
||||
|rc| rc as Rc<dyn TraversibleBinaryNode<'a, T, A, UnbalancedData>>,
|
||||
self.0(),
|
||||
)
|
||||
}
|
||||
|
||||
fn data(&self) -> UnbalancedData {
|
||||
UnbalancedData
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: 'a + Monad, A: 'a> TraversibleBinaryTree<'a, T, A, UnbalancedData>
|
||||
for UnbalancedTree<'a, T, A>
|
||||
{
|
||||
fn refer(&self) -> Option<Rc<dyn TraversibleBinaryReference<'a, T, A, UnbalancedData>>> {
|
||||
match self {
|
||||
UnbalancedTree::Leaf => None,
|
||||
UnbalancedTree::Node(reference) => Some(reference.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type WrapType<'a, T, A> =
|
||||
Box<dyn 'a + Fn(Rc<UnbalancedNode<'a, T, A>>) -> UnbalancedResolution<'a, T, A>>;
|
||||
|
||||
pub struct UnbalancedConstructor<'a, T: 'a + Monad, A: 'a> {
|
||||
wrap: WrapType<'a, T, A>,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a + Monad, A: 'a> UnbalancedConstructor<'a, T, A> {
|
||||
pub fn rc(wrap: WrapType<'a, T, A>) -> Rc<Self> {
|
||||
Self { wrap }.into()
|
||||
}
|
||||
|
||||
pub fn leaf(&self) -> Rc<UnbalancedTree<'a, T, A>> {
|
||||
UnbalancedTree::Leaf.into()
|
||||
}
|
||||
|
||||
pub fn node(
|
||||
self: &Rc<Self>,
|
||||
cl: Rc<UnbalancedTree<'a, T, A>>,
|
||||
key: A,
|
||||
cr: Rc<UnbalancedTree<'a, T, A>>,
|
||||
) -> Rc<UnbalancedTree<'a, T, A>> {
|
||||
let node = Rc::new(UnbalancedNode {
|
||||
cl,
|
||||
cr,
|
||||
key: key.into(),
|
||||
});
|
||||
let ctr = self.clone();
|
||||
UnbalancedTree::Node(Rc::new(UnbalancedReference(Box::new(move || {
|
||||
(ctr.wrap)(node.clone())
|
||||
}))))
|
||||
.into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn from_slice<R: 'a + rand::Rng>(
|
||||
self: &Rc<Self>,
|
||||
rng: &mut R,
|
||||
slice: &[A],
|
||||
) -> Rc<UnbalancedTree<'a, T, A>>
|
||||
where
|
||||
A: 'a + Clone,
|
||||
{
|
||||
if slice.is_empty() {
|
||||
self.leaf()
|
||||
} else {
|
||||
let key_at = rng.gen_range(0..slice.len());
|
||||
let key = slice[key_at].clone();
|
||||
let lslice = &slice[..key_at];
|
||||
let rslice = &slice[key_at + 1..];
|
||||
self.clone().node(
|
||||
self.clone().from_slice(rng, lslice),
|
||||
key,
|
||||
self.clone().from_slice(rng, rslice),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rand::Rng;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_simple_slices() {
|
||||
let ctr: Rc<UnbalancedConstructor<classes::solo::SoloClass, _>> =
|
||||
UnbalancedConstructor::rc(Box::new(|node| node));
|
||||
let mut rng = rand::thread_rng();
|
||||
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(), 1.into()));
|
||||
assert!(t_subset_of_t(
|
||||
&DefaultComparator,
|
||||
t_set.clone(),
|
||||
t_set.clone(),
|
||||
None,
|
||||
None
|
||||
));
|
||||
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(
|
||||
&DefaultComparator,
|
||||
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]),
|
||||
None,
|
||||
None
|
||||
));
|
||||
assert!(!t_subset_of_t(
|
||||
&DefaultComparator,
|
||||
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]),
|
||||
None,
|
||||
None
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_slices() {
|
||||
let ctr: Rc<UnbalancedConstructor<classes::solo::SoloClass, _>> =
|
||||
UnbalancedConstructor::rc(Box::new(|node| node));
|
||||
let mut rng = rand::thread_rng();
|
||||
for _ in 0..1000 {
|
||||
let big: Vec<i32> = (0..(rng.gen_range(2..10))).collect();
|
||||
let key = big[rng.gen_range(0..big.len())];
|
||||
let small: Vec<i32> = big
|
||||
.iter()
|
||||
.filter(|x| **x != key && rng.gen_ratio(4, 5))
|
||||
.map(|x| *x)
|
||||
.collect();
|
||||
let t_small = ctr.from_slice(&mut rng, &small);
|
||||
let t_big = ctr.from_slice(&mut rng, &big);
|
||||
assert!(
|
||||
t_subset_of_t(
|
||||
&DefaultComparator,
|
||||
t_small.clone(),
|
||||
t_big.clone(),
|
||||
None,
|
||||
None
|
||||
),
|
||||
"{} should be a subset of {}",
|
||||
t_small,
|
||||
t_big,
|
||||
);
|
||||
assert!(
|
||||
!t_subset_of_t(
|
||||
&DefaultComparator,
|
||||
t_big.clone(),
|
||||
t_small.clone(),
|
||||
None,
|
||||
None
|
||||
),
|
||||
"{} should not be a subset of {}",
|
||||
t_big,
|
||||
t_small,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -306,13 +306,11 @@ mod stackless_test {
|
||||
}
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_factorial() {
|
||||
assert_eq!(factorial(10).evaluate(), 3628800);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_dumb() {
|
||||
let n = 1000;
|
||||
|
Loading…
Reference in New Issue
Block a user