flow::binary::bounds

This commit is contained in:
AF 2023-06-16 08:00:18 +00:00
parent e7dc834c8b
commit f0aa3878c4
3 changed files with 84 additions and 82 deletions

View File

@ -1,4 +1,5 @@
mod avl; mod avl;
pub mod bounds;
use crate::flow::comparator::*; use crate::flow::comparator::*;
use crate::func::{context::*, *}; use crate::func::{context::*, *};

82
src/flow/binary/bounds.rs Normal file
View File

@ -0,0 +1,82 @@
use crate::flow::comparator::*;
#[derive(Clone)]
pub struct Bounds<A> {
l: Option<A>,
r: Option<A>,
}
pub enum BoundsError<A> {
BoundsViolated { l: A, r: A },
CannotJoin(A),
}
impl<A: Clone> Bounds<A> {
pub fn unbound() -> Self {
Bounds { l: None, r: None }
}
fn ordered(l: &A, r: &A, comparator: &impl Comparator<A>) -> Result<(), BoundsError<A>> {
if let Comparison::R = comparator.pick_smaller(l, r) {
Err(BoundsError::BoundsViolated {
l: l.clone(),
r: r.clone(),
})
} else {
Ok(())
}
}
fn new(
l: Option<A>,
r: Option<A>,
comparator: &impl Comparator<A>,
) -> Result<Self, BoundsError<A>> {
if let (Some(kl), Some(kr)) = (&l, &r) {
Self::ordered(kl, kr, comparator)?
}
Ok(Bounds { l, r })
}
pub fn split(
self,
key: &A,
comparator: &impl Comparator<A>,
) -> Result<(Self, Self), BoundsError<A>> {
Ok((
Self::new(self.l, Some(key.clone()), comparator)?,
Self::new(Some(key.clone()), self.r, comparator)?,
))
}
pub fn join(
l: Self,
r: Self,
key: &A,
comparator: &impl Comparator<A>,
) -> Result<Self, BoundsError<A>> {
if let Some(lr) = &l.r {
Self::ordered(lr, key, comparator)?
} else {
Err(BoundsError::CannotJoin(key.clone()))?
}
if let Some(rl) = &r.l {
Self::ordered(key, rl, comparator)?
} else {
Err(BoundsError::CannotJoin(key.clone()))?
}
Self::new(l.l, r.r, comparator)
}
pub fn equal_bound(l: &Option<A>, r: &Option<A>, comparator: &impl Comparator<A>) -> bool {
match (l, r) {
(None, None) => true,
(Some(kl), Some(kr)) => matches!(comparator.pick_smaller(kl, kr), Comparison::E),
_ => false,
}
}
pub fn equal(bl: &Self, br: &Self, comparator: &impl Comparator<A>) -> bool {
Self::equal_bound(&bl.l, &br.l, comparator) && Self::equal_bound(&bl.r, &br.r, comparator)
}
}

View File

@ -1,19 +1,8 @@
use crate::flow::comparator::*; use crate::flow::{binary::bounds::*, comparator::*};
use crate::func::context::*; use crate::func::context::*;
use super::{binary::*, *}; use super::{binary::*, *};
#[derive(Clone)]
struct Bounds<A> {
l: Option<A>,
r: Option<A>,
}
pub enum BoundsError<A> {
BoundsViolated { l: A, r: A },
CannotJoin(A),
}
pub enum BoundError<A, E> { pub enum BoundError<A, E> {
Avl(AvlError<E>), Avl(AvlError<E>),
Bounds(BoundsError<A>), Bounds(BoundsError<A>),
@ -56,76 +45,6 @@ pub struct BoundReference<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
bounds: Bounds<A>, bounds: Bounds<A>,
} }
impl<A: Clone> Bounds<A> {
fn unbound() -> Self {
Bounds { l: None, r: None }
}
fn ordered(l: &A, r: &A, comparator: &impl Comparator<A>) -> Result<(), BoundsError<A>> {
if let Comparison::R = comparator.pick_smaller(l, r) {
Err(BoundsError::BoundsViolated {
l: l.clone(),
r: r.clone(),
})
} else {
Ok(())
}
}
fn new(
l: Option<A>,
r: Option<A>,
comparator: &impl Comparator<A>,
) -> Result<Self, BoundsError<A>> {
if let (Some(kl), Some(kr)) = (&l, &r) {
Self::ordered(kl, kr, comparator)?
}
Ok(Bounds { l, r })
}
fn split(
self,
key: &A,
comparator: &impl Comparator<A>,
) -> Result<(Self, Self), BoundsError<A>> {
Ok((
Self::new(self.l, Some(key.clone()), comparator)?,
Self::new(Some(key.clone()), self.r, comparator)?,
))
}
fn join(
l: Self,
r: Self,
key: &A,
comparator: &impl Comparator<A>,
) -> Result<Self, BoundsError<A>> {
if let Some(lr) = &l.r {
Self::ordered(lr, key, comparator)?
} else {
Err(BoundsError::CannotJoin(key.clone()))?
}
if let Some(rl) = &r.l {
Self::ordered(key, rl, comparator)?
} else {
Err(BoundsError::CannotJoin(key.clone()))?
}
Self::new(l.l, r.r, comparator)
}
pub fn equal_bound(l: &Option<A>, r: &Option<A>, comparator: &impl Comparator<A>) -> bool {
match (l, r) {
(None, None) => true,
(Some(kl), Some(kr)) => matches!(comparator.pick_smaller(kl, kr), Comparison::E),
_ => false,
}
}
pub fn equal(bl: &Self, br: &Self, comparator: &impl Comparator<A>) -> bool {
Self::equal_bound(&bl.l, &br.l, comparator) && Self::equal_bound(&bl.r, &br.r, comparator)
}
}
pub type BoundSplit<'a, Ctx, A> = (BoundTree<'a, Ctx, A>, BoundTree<'a, Ctx, A>, A); pub type BoundSplit<'a, Ctx, A> = (BoundTree<'a, Ctx, A>, BoundTree<'a, Ctx, A>, A);
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone> BoundNode<'a, Ctx, A> { impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone> BoundNode<'a, Ctx, A> {