1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
#![warn(missing_docs)]
#![doc = include_str!("../README.md")]
use std::cmp::Ordering::{self, *};
pub use cc_traits;
use sealed::sealed;
pub mod collections;
mod conflict;
mod dom_pair;
pub mod map_union;
mod ord;
mod pair;
mod point;
mod seq;
pub mod set_union;
pub mod test;
mod unit;
mod with_bot;
mod with_top;
pub use conflict::Conflict;
pub use dom_pair::DomPair;
pub use ord::{Max, Min};
pub use pair::Pair;
pub use point::Point;
pub use seq::Seq;
pub use with_bot::WithBot;
pub use with_top::WithTop;
/// Trait for lattice merge (AKA "join" or "least upper bound").
pub trait Merge<Other> {
/// Merge `other` into the `self` lattice.
///
/// This operation must be associative, commutative, and idempotent.
///
/// Returns `true` if `self` changed, `false` otherwise.
/// Returning `true` implies that the new value for `self` is later in the lattice order than
/// the old value. Returning `false` means that `self` was unchanged and therefore `other` came
/// before `self` (or the two are equal) in the lattice order.
fn merge(&mut self, other: Other) -> bool;
/// Merge `this` and `delta` together, returning the new value.
fn merge_owned(mut this: Self, delta: Other) -> Self
where
Self: Sized,
{
Self::merge(&mut this, delta);
this
}
}
/// Trait for lattice partial order comparison
/// PartialOrd is implemented for many things, this trait can be used to require the type be a lattice.
pub trait LatticeOrd<Rhs = Self>: PartialOrd<Rhs> {}
/// Naive lattice compare, based on the [`Merge::merge`] function.
#[sealed]
pub trait NaiveLatticeOrd<Rhs = Self>
where
Self: Clone + Merge<Rhs> + Sized,
Rhs: Clone + Merge<Self>,
{
/// Naive compare based on the [`Merge::merge`] method. This method can be very inefficient;
/// use [`PartialOrd::partial_cmp`] instead.
///
/// This method should not be overridden.
fn naive_cmp(&self, other: &Rhs) -> Option<Ordering> {
let mut self_a = self.clone();
let other_a = other.clone();
let self_b = self.clone();
let mut other_b = other.clone();
match (self_a.merge(other_a), other_b.merge(self_b)) {
(true, true) => None,
(true, false) => Some(Less),
(false, true) => Some(Greater),
(false, false) => Some(Equal),
}
}
}
#[sealed]
impl<This, Other> NaiveLatticeOrd<Other> for This
where
Self: Clone + Merge<Other>,
Other: Clone + Merge<Self>,
{
}
/// Same as `From` but for lattices.
///
/// This should only be implemented between different representations of the same lattice type.
/// This should recursively convert nested lattice types, but not non-lattice ("scalar") types.
pub trait LatticeFrom<Other> {
/// Convert from the `Other` lattice into `Self`.
fn lattice_from(other: Other) -> Self;
}
/// Trait to check if a lattice instance is bottom (⊥).
pub trait IsBot {
/// Returns if `self` is lattice bottom (⊥).
fn is_bot(&self) -> bool;
}
/// Trait to check if a lattice instance is top (⊤) and therefore cannot change any futher.
pub trait IsTop {
/// Returns if `self` is lattice top (⊤).
fn is_top(&self) -> bool;
}