better tree interfaces

This commit is contained in:
AF 2023-05-29 17:21:47 +00:00
parent f5791c930d
commit beefedaf2b
5 changed files with 74 additions and 27 deletions

View File

@ -25,13 +25,14 @@ pub trait BinaryTrees<'a>: 'a {
fn comparator(&self) -> &Self::Comparator;
fn split(&self, node: &Self::Node) -> Split<'a, Self>;
fn tree_of(&self, node: Self::Node) -> TreeRc<'a, Self>;
fn tree_of(&self, node: Self::Node) -> BTWrap<'a, Self, TreeRc<'a, Self>>;
fn resolve(&self, reference: &Self::Reference) -> BTWrap<'a, Self, NodeRc<'a, Self>>;
fn equal(&self, rhs: &Self::Reference, lhs: &Self::Reference) -> bool;
fn refer(&self, tree: &Self::Tree) -> Option<ReferenceRc<'a, Self>>;
}
pub trait BinaryTreesMutable<'a>: BinaryTrees<'a> {
fn empty(&self) -> Self::Tree;
fn join_key(
&self,
tl: Self::Tree,

View File

@ -10,6 +10,12 @@ pub struct Point<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
pub origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>,
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> PartialEq for Point<'a, Ctx, A> {
fn eq(&self, other: &Self) -> bool {
self.point == other.point
}
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for Point<'a, Ctx, A> {
fn clone(&self) -> Self {
Self {

View File

@ -1,5 +1,6 @@
pub mod binary;
pub mod bounds;
pub mod context;
use std::{error::Error, fmt::Display, rc::Rc};

View File

@ -7,6 +7,12 @@ pub struct AvlReference<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
parent_height: u64,
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> PartialEq for AvlReference<'a, Ctx, A> {
fn eq(&self, other: &Self) -> bool {
self.node == other.node && self.parent_height == other.parent_height
}
}
pub type AvlResult<'a, Ctx, A, T> = Result<T, AvlError<ParseError<'a, Ctx, Fctr<'a, Ctx, A>>>>;
pub type AvlNodeResult<'a, Ctx, A> = AvlResult<'a, Ctx, A, AvlNode<'a, Ctx, A>>;

View File

@ -51,7 +51,9 @@ pub struct BoundTree<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
}
pub struct BoundNode<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
node: AvlNode<'a, Ctx, A>,
l: BoundTree<'a, Ctx, A>,
r: BoundTree<'a, Ctx, A>,
key: Rc<A>,
bounds: Bounds<A>,
}
@ -116,13 +118,30 @@ impl<A> Bounds<A> {
}
Self::new(l.l, r.r, comparator)
}
pub fn equal_bound(
lhs: &Option<Rc<A>>,
rhs: &Option<Rc<A>>,
comparator: &impl Comparator<A>,
) -> bool {
match (lhs, rhs) {
(None, None) => true,
(Some(kl), Some(kr)) => matches!(comparator.pick_smaller(kl, kr), Comparison::E),
_ => false,
}
}
pub fn equal(lhs: &Self, rhs: &Self, comparator: &impl Comparator<A>) -> bool {
Self::equal_bound(&lhs.l, &rhs.l, comparator)
&& Self::equal_bound(&lhs.r, &rhs.r, comparator)
}
}
pub type BoundSplit<'a, Ctx, A> = (BoundTree<'a, Ctx, A>, BoundTree<'a, Ctx, A>, Rc<A>);
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundNode<'a, Ctx, A> {
pub fn into_tree(self) -> BoundTreeResult<'a, Ctx, A> {
let tree = self.node.into_tree()?;
let tree = AvlNode::new(self.l.tree, self.r.tree, self.key)?.into_tree()?;
let bounds = self.bounds;
Ok(BoundTree { tree, bounds })
}
@ -133,27 +152,12 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundNode<'a, Ctx, A> {
key: Rc<A>,
comparator: &impl Comparator<A>,
) -> BoundNodeResult<'a, Ctx, A> {
let bounds = Bounds::join(l.bounds, r.bounds, &key, comparator)?;
let node = AvlNode::new(l.tree, r.tree, key)?;
Ok(Self { node, bounds })
let bounds = Bounds::join(l.bounds.clone(), r.bounds.clone(), &key, comparator)?;
Ok(Self { l, r, key, bounds })
}
pub fn split(
&self,
comparator: &impl Comparator<A>,
) -> Result<BoundSplit<'a, Ctx, A>, BoundsError<A>> {
let (bl, br) = self.bounds.clone().split(&self.node.key, comparator)?;
Ok((
BoundTree {
tree: self.node.l.clone(),
bounds: bl,
},
BoundTree {
tree: self.node.r.clone(),
bounds: br,
},
self.node.key.clone(),
))
pub fn split(&self) -> BoundSplit<'a, Ctx, A> {
(self.l.clone(), self.r.clone(), self.key.clone())
}
}
@ -172,16 +176,25 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundTree<'a, Ctx, A> {
}
}
type BoundResolutionError<'a, Ctx, A> =
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for BoundTree<'a, Ctx, A> {
fn clone(&self) -> Self {
Self {
tree: self.tree.clone(),
bounds: self.bounds.clone(),
}
}
}
pub type BoundResolutionError<'a, Ctx, A> =
ResolutionError<<Ctx as Context<'a>>::LookupError, BoundErrorA<'a, Ctx, A>>;
type BoundResolutionResult<'a, Ctx, A> =
pub type BoundResolutionResult<'a, Ctx, A> =
Result<BoundNode<'a, Ctx, A>, BoundResolutionError<'a, Ctx, A>>;
type BoundResolution<'a, Ctx, A> = Wrapped<'a, Ctx, BoundResolutionResult<'a, Ctx, A>>;
pub type BoundResolution<'a, Ctx, A> = Wrapped<'a, Ctx, BoundResolutionResult<'a, Ctx, A>>;
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundReference<'a, Ctx, A> {
pub fn resolve(&self) -> BoundResolution<'a, Ctx, A> {
pub fn resolve(&self, comparator: Rc<impl 'a + Comparator<A>>) -> BoundResolution<'a, Ctx, A> {
let bounds = self.bounds.clone();
<Ctx::T as Functor>::fmap(
move |resolution| {
@ -192,9 +205,29 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundReference<'a, Ctx, A> {
})?
.as_ref()
.clone();
Ok(BoundNode { node, bounds })
let (bl, br) = bounds
.clone()
.split(&node.key, comparator.as_ref())
.map_err(BoundError::Bounds)
.map_err(ResolutionError::Parse)?;
Ok(BoundNode {
l: BoundTree {
tree: node.l,
bounds: bl,
},
r: BoundTree {
tree: node.r,
bounds: br,
},
key: node.key,
bounds,
})
},
self.reference.resolve(),
)
}
pub fn equal(lhs: &Self, rhs: &Self, comparator: &impl Comparator<A>) -> bool {
lhs.reference == rhs.reference && Bounds::equal(&lhs.bounds, &rhs.bounds, comparator)
}
}