diff --git a/src/flow/binary/bounds.rs b/src/flow/binary/bounds.rs index 304f884..1f7917d 100644 --- a/src/flow/binary/bounds.rs +++ b/src/flow/binary/bounds.rs @@ -1,3 +1,5 @@ +pub mod bound; + use crate::flow::comparator::*; #[derive(Clone)] diff --git a/src/flow/binary/bounds/bound.rs b/src/flow/binary/bounds/bound.rs new file mode 100644 index 0000000..a3909ea --- /dev/null +++ b/src/flow/binary/bounds/bound.rs @@ -0,0 +1,99 @@ +use crate::{flow::binary::*, func::context::*}; + +use super::*; + +#[derive(Clone)] +pub struct Bound { + bound: T, + bounds: Bounds, +} + +pub struct BoundNode2 { + boundsl: Bounds, + boundsr: Bounds, + bounds: Bounds, + node: T, +} + +#[derive(Clone)] +pub struct BoundTrees(BT); + +impl<'a, BT: FunctorContext<'a>> FunctorContext<'a> for BoundTrees { + type T = BT::T; +} + +trait BinaryTreesBindable<'a>: BinaryTrees<'a> { + fn bounds_error(&self, error: BoundsError) -> BTWrap<'a, Self, T>; +} + +impl<'a, BT: BinaryTreesBindable<'a>> BinaryTrees<'a> for BoundTrees +where + BT::Tree: Clone, +{ + type Node = BoundNode2; + + type Reference = Bound; + + type Tree = Bound; + + type Key = BT::Key; + + type Comparator = BT::Comparator; + + type _Tm = Self::T; + + fn comparator(&self) -> &Self::Comparator { + self.0.comparator() + } + + fn split(&self, node: &Self::Node) -> Split<'a, Self> { + let (tl, tr, key) = self.0.split(&node.node); + ( + Bound { + bound: tl, + bounds: node.boundsl.clone(), + }, + Bound { + bound: tr, + bounds: node.boundsr.clone(), + }, + key, + ) + } + + fn tree_of(&self, node: Self::Node) -> BTWrap<'a, Self, Self::Tree> { + Self::fmap(self.0.tree_of(node.node), move |tree| Bound { + bound: tree, + bounds: node.bounds, + }) + } + + fn resolve(&self, reference: &Self::Reference) -> BTWrap<'a, Self, Self::Node> { + let ctx = self.clone(); + let bounds = reference.bounds.clone(); + Self::bind(self.0.resolve(&reference.bound), move |node| { + let (_, _, key) = ctx.0.split(&node); + match bounds.clone().split(&key, ctx.comparator()) { + Ok((boundsl, boundsr)) => Self::pure(BoundNode2 { + boundsl, + boundsr, + bounds, + node, + }), + Err(e) => ctx.0.bounds_error(e), + } + }) + } + + fn equal(&self, rl: &Self::Reference, rr: &Self::Reference) -> bool { + Bounds::equal(&rl.bounds, &rr.bounds, self.comparator()) + && self.0.equal(&rl.bound, &rr.bound) + } + + fn refer(&self, tree: &Self::Tree) -> Option { + Some(Bound { + bound: self.0.refer(&tree.bound)?, + bounds: tree.bounds.clone(), + }) + } +}