use super::Monoid;
pub trait MeetSemilattice: Monoid + PartialOrd {
fn meet(self, other: Self) -> Self;
}
pub trait JoinSemilattice: Monoid + PartialOrd {
fn join(self, other: Self) -> Self;
}
pub trait BoundedMeetSemilattice: MeetSemilattice {
fn top() -> Self;
}
pub trait BoundedJoinSemilattice: JoinSemilattice {
fn bottom() -> Self;
}
pub trait Lattice: MeetSemilattice + JoinSemilattice {}
impl<T: MeetSemilattice + JoinSemilattice> Lattice for T {}
#[cfg(test)]
mod tests {
use super::*;
use crate::algebra::Semigroup;
use std::collections::BTreeSet;
impl<T: Ord + Clone> MeetSemilattice for BTreeSet<T> {
fn meet(self, other: Self) -> Self {
self.intersection(&other).cloned().collect()
}
}
impl<T: Ord + Clone> JoinSemilattice for BTreeSet<T> {
fn join(self, other: Self) -> Self {
self.combine(other) }
}
#[test]
fn test_meet_commutativity() {
let a: BTreeSet<i32> = [1, 2, 3].iter().cloned().collect();
let b: BTreeSet<i32> = [2, 3, 4].iter().cloned().collect();
assert_eq!(a.clone().meet(b.clone()), b.meet(a));
}
#[test]
fn test_meet_associativity() {
let a: BTreeSet<i32> = [1, 2, 3].iter().cloned().collect();
let b: BTreeSet<i32> = [2, 3, 4].iter().cloned().collect();
let c: BTreeSet<i32> = [3, 4, 5].iter().cloned().collect();
let left = a.clone().meet(b.clone()).meet(c.clone());
let right = a.meet(b.meet(c));
assert_eq!(left, right);
}
#[test]
fn test_meet_idempotence() {
let a: BTreeSet<i32> = [1, 2, 3].iter().cloned().collect();
assert_eq!(a.clone().meet(a.clone()), a);
}
#[test]
fn test_join_commutativity() {
let a: BTreeSet<i32> = [1, 2].iter().cloned().collect();
let b: BTreeSet<i32> = [3, 4].iter().cloned().collect();
assert_eq!(a.clone().join(b.clone()), b.join(a));
}
#[test]
fn test_join_idempotence() {
let a: BTreeSet<i32> = [1, 2, 3].iter().cloned().collect();
assert_eq!(a.clone().join(a.clone()), a);
}
}