better tree interfaces
This commit is contained in:
parent
f5791c930d
commit
beefedaf2b
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -1,5 +1,6 @@
|
||||
pub mod binary;
|
||||
pub mod bounds;
|
||||
pub mod context;
|
||||
|
||||
use std::{error::Error, fmt::Display, rc::Rc};
|
||||
|
||||
|
@ -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>>;
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user