flow::traversible
This commit is contained in:
parent
3cc868d8d3
commit
911e536c67
1
src/flow.rs
Normal file
1
src/flow.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod traversible;
|
164
src/flow/traversible.rs
Normal file
164
src/flow/traversible.rs
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::func::*;
|
||||||
|
|
||||||
|
pub enum Comparison {
|
||||||
|
L,
|
||||||
|
E,
|
||||||
|
R,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn and(left: bool, right: bool) -> bool {
|
||||||
|
left && right
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Comparator<A> {
|
||||||
|
fn pick_smaller(&self, kl: &A, kr: &A) -> Comparison;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Split<'a, T, A, D> = (
|
||||||
|
Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
|
Rc<dyn TraversibleBinaryTree<'a, T, A, D>>,
|
||||||
|
Rc<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: 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: Monad, A, D: 'a + PartialEq>: 'a {
|
||||||
|
fn refer(&self) -> Option<Rc<dyn TraversibleBinaryReference<'a, T, A, D>>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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>,
|
||||||
|
) -> T::F<'a, bool> {
|
||||||
|
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(true),
|
||||||
|
Comparison::R => t_contains(comparator, t_setr, key),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>,
|
||||||
|
) -> T::F<'a, bool> {
|
||||||
|
T::bind(r_set.resolve(), |n_set| n_contains(comparator, n_set, key))
|
||||||
|
}
|
||||||
|
|
||||||
|
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>,
|
||||||
|
) -> T::F<'a, bool> {
|
||||||
|
match t_set.refer() {
|
||||||
|
Some(r_set) => r_contains(comparator, r_set, key),
|
||||||
|
None => T::pure(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>>,
|
||||||
|
k_l: Option<Rc<A>>,
|
||||||
|
k_r: Option<Rc<A>>,
|
||||||
|
) -> T::F<'a, bool> {
|
||||||
|
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_subset.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_subset.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: 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>>,
|
||||||
|
k_l: Option<Rc<A>>,
|
||||||
|
k_r: Option<Rc<A>>,
|
||||||
|
) -> T::F<'a, bool> {
|
||||||
|
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: Monad, 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, bool> {
|
||||||
|
match (t_subset.refer(), t_superset.refer()) {
|
||||||
|
(None, _) => T::pure(true),
|
||||||
|
(Some(_), None) => T::pure(false),
|
||||||
|
(Some(r_subset), Some(r_superset)) => {
|
||||||
|
if r_subset.data() == r_superset.data() {
|
||||||
|
T::pure(true)
|
||||||
|
} else {
|
||||||
|
r_subset_of_r(comparator, r_subset, r_superset, k_l, k_r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
pub mod core;
|
pub mod core;
|
||||||
|
pub mod flow;
|
||||||
pub mod func;
|
pub mod func;
|
||||||
pub mod std;
|
pub mod std;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -19,7 +19,7 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
|
|||||||
Self::from_fields(point, Rc::new(origin))
|
Self::from_fields(point, Rc::new(origin))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_mentionable(mentionable: A) -> Self {
|
fn from_mentionable(mentionable: Rc<A>) -> Self {
|
||||||
Self::from_values(
|
Self::from_values(
|
||||||
Ctx::hash(&Self::prepare_bytes_for_hashing(&mentionable)),
|
Ctx::hash(&Self::prepare_bytes_for_hashing(&mentionable)),
|
||||||
LocalOrigin::from(mentionable),
|
LocalOrigin::from(mentionable),
|
||||||
@ -41,14 +41,20 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A> From<A> for LocalOrigin<A> {
|
impl<A> From<Rc<A>> for LocalOrigin<A> {
|
||||||
fn from(value: A) -> Self {
|
fn from(value: Rc<A>) -> Self {
|
||||||
LocalOrigin(value.into())
|
LocalOrigin(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From<Rc<A>> for Point<'a, Ctx, A> {
|
||||||
|
fn from(value: Rc<A>) -> Self {
|
||||||
|
Self::from_mentionable(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From<A> for Point<'a, Ctx, A> {
|
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From<A> for Point<'a, Ctx, A> {
|
||||||
fn from(value: A) -> Self {
|
fn from(value: A) -> Self {
|
||||||
Self::from_mentionable(value)
|
Self::from_mentionable(value.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,15 +78,21 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Nullable<'a, Ctx, Nullable<
|
|||||||
/// Reduce [Nullable] nesting.
|
/// Reduce [Nullable] nesting.
|
||||||
pub fn join(&self) -> Resolution<'a, Ctx, Nullable<'a, Ctx, A>> {
|
pub fn join(&self) -> Resolution<'a, Ctx, Nullable<'a, Ctx, A>> {
|
||||||
match self {
|
match self {
|
||||||
Nullable::Null(nullable_factory) => {
|
Self::Null(nullable_factory) => {
|
||||||
let NullableFactory { factory } = nullable_factory;
|
let NullableFactory { factory } = nullable_factory;
|
||||||
Ctx::T::pure(Ok(Rc::new(Nullable::Null(factory.clone()))))
|
Ctx::T::pure(Ok(Rc::new(Nullable::Null(factory.clone()))))
|
||||||
}
|
}
|
||||||
Nullable::NotNull(point) => point.resolve(),
|
Self::NotNull(point) => point.resolve(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Nullable<'a, Ctx, A> {
|
||||||
|
fn from_mentionable(mentionable: Rc<A>) -> Self {
|
||||||
|
Self::NotNull(mentionable.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<F> NullableFactory<F> {
|
impl<F> NullableFactory<F> {
|
||||||
pub fn new(factory: F) -> Self {
|
pub fn new(factory: F) -> Self {
|
||||||
Self { factory }
|
Self { factory }
|
||||||
@ -105,3 +111,15 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Clone for Nullable<'a, Ctx,
|
|||||||
impl<F> AlwaysConstSize for NullableFactory<F> {
|
impl<F> AlwaysConstSize for NullableFactory<F> {
|
||||||
const _SIZE: usize = HASH_SIZE;
|
const _SIZE: usize = HASH_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From<Rc<A>> for Nullable<'a, Ctx, A> {
|
||||||
|
fn from(value: Rc<A>) -> Self {
|
||||||
|
Self::from_mentionable(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From<A> for Nullable<'a, Ctx, A> {
|
||||||
|
fn from(value: A) -> Self {
|
||||||
|
Self::from_mentionable(value.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user