use crate::semiring::{IdempotentSemiring, Semiring};
use llattice::Lattice;
pub trait SemiringLattice: Semiring + IdempotentSemiring {}
impl<S> SemiringLattice for S where S: Semiring + IdempotentSemiring {}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(
feature = "lattice-persistent",
derive(serde::Serialize, serde::Deserialize)
)]
#[cfg_attr(feature = "lattice-persistent", serde(transparent))]
pub struct SemiringLatticeWrapper<S>(pub S);
impl<S: Semiring + IdempotentSemiring + Clone + Send + Sync> Lattice for SemiringLatticeWrapper<S> {
#[inline]
fn join(&self, other: &Self) -> Self {
SemiringLatticeWrapper(self.0.plus(&other.0))
}
#[inline]
fn meet(&self, other: &Self) -> Self {
SemiringLatticeWrapper(self.0.times(&other.0))
}
}
#[cfg(not(feature = "lattice-persistent"))]
impl<S: Clone + Default + Send + Sync + Unpin + 'static> libdictenstein::value::DictionaryValue
for SemiringLatticeWrapper<S>
{
}
#[cfg(feature = "lattice-persistent")]
impl<
S: Clone
+ Default
+ Send
+ Sync
+ Unpin
+ 'static
+ serde::Serialize
+ serde::de::DeserializeOwned,
> libdictenstein::value::DictionaryValue for SemiringLatticeWrapper<S>
{
}
#[cfg(test)]
mod tests {
use super::*;
use crate::semiring::{BoolWeight, TropicalWeight};
use ordered_float::OrderedFloat;
#[test]
fn tropical_join_is_plus_meet_is_times() {
let a = SemiringLatticeWrapper(TropicalWeight(OrderedFloat(10.0)));
let b = SemiringLatticeWrapper(TropicalWeight(OrderedFloat(5.0)));
assert_eq!(a.join(&b).0 .0 .0, 5.0);
assert_eq!(a.meet(&b).0 .0 .0, 15.0);
}
#[test]
fn bool_join_is_or() {
let t = SemiringLatticeWrapper(BoolWeight(true));
let f = SemiringLatticeWrapper(BoolWeight(false));
assert!(t.join(&f).0 .0); assert!(!f.join(&f).0 .0); }
}