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 comparator(&self) -> &Self::Comparator;
|
||||||
fn split(&self, node: &Self::Node) -> Split<'a, Self>;
|
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 resolve(&self, reference: &Self::Reference) -> BTWrap<'a, Self, NodeRc<'a, Self>>;
|
||||||
fn equal(&self, rhs: &Self::Reference, lhs: &Self::Reference) -> bool;
|
fn equal(&self, rhs: &Self::Reference, lhs: &Self::Reference) -> bool;
|
||||||
fn refer(&self, tree: &Self::Tree) -> Option<ReferenceRc<'a, Self>>;
|
fn refer(&self, tree: &Self::Tree) -> Option<ReferenceRc<'a, Self>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BinaryTreesMutable<'a>: BinaryTrees<'a> {
|
pub trait BinaryTreesMutable<'a>: BinaryTrees<'a> {
|
||||||
|
fn empty(&self) -> Self::Tree;
|
||||||
fn join_key(
|
fn join_key(
|
||||||
&self,
|
&self,
|
||||||
tl: Self::Tree,
|
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>>,
|
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> {
|
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for Point<'a, Ctx, A> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
pub mod binary;
|
pub mod binary;
|
||||||
pub mod bounds;
|
pub mod bounds;
|
||||||
|
pub mod context;
|
||||||
|
|
||||||
use std::{error::Error, fmt::Display, rc::Rc};
|
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,
|
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 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>>;
|
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>> {
|
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>,
|
bounds: Bounds<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,13 +118,30 @@ impl<A> Bounds<A> {
|
|||||||
}
|
}
|
||||||
Self::new(l.l, r.r, comparator)
|
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>);
|
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> {
|
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundNode<'a, Ctx, A> {
|
||||||
pub fn into_tree(self) -> BoundTreeResult<'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;
|
let bounds = self.bounds;
|
||||||
Ok(BoundTree { tree, 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>,
|
key: Rc<A>,
|
||||||
comparator: &impl Comparator<A>,
|
comparator: &impl Comparator<A>,
|
||||||
) -> BoundNodeResult<'a, Ctx, A> {
|
) -> BoundNodeResult<'a, Ctx, A> {
|
||||||
let bounds = Bounds::join(l.bounds, r.bounds, &key, comparator)?;
|
let bounds = Bounds::join(l.bounds.clone(), r.bounds.clone(), &key, comparator)?;
|
||||||
let node = AvlNode::new(l.tree, r.tree, key)?;
|
Ok(Self { l, r, key, bounds })
|
||||||
Ok(Self { node, bounds })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split(
|
pub fn split(&self) -> BoundSplit<'a, Ctx, A> {
|
||||||
&self,
|
(self.l.clone(), self.r.clone(), self.key.clone())
|
||||||
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(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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>>;
|
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>>;
|
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> {
|
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();
|
let bounds = self.bounds.clone();
|
||||||
<Ctx::T as Functor>::fmap(
|
<Ctx::T as Functor>::fmap(
|
||||||
move |resolution| {
|
move |resolution| {
|
||||||
@ -192,9 +205,29 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundReference<'a, Ctx, A> {
|
|||||||
})?
|
})?
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.clone();
|
.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(),
|
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