Skip to main content

sim_lib_discrete_algebra/
boolean.rs

1//! The boolean semiring `(OR, AND)`. Closure gives transitive reachability.
2
3use crate::semiring::Semiring;
4
5/// The two-element boolean semiring: `add` is OR, `mul` is AND.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct BoolRing(pub bool);
8
9impl Semiring for BoolRing {
10    fn zero() -> Self {
11        BoolRing(false)
12    }
13    fn one() -> Self {
14        BoolRing(true)
15    }
16    fn add(&self, other: &Self) -> Self {
17        BoolRing(self.0 || other.0)
18    }
19    fn mul(&self, other: &Self) -> Self {
20        BoolRing(self.0 && other.0)
21    }
22    fn is_zero(&self) -> bool {
23        !self.0
24    }
25    /// Reachability closure of a scalar is always reachable: `1 + a + ... = 1`.
26    fn star(&self) -> Option<Self> {
27        Some(BoolRing(true))
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34    use crate::semiring::laws::assert_semiring_laws;
35
36    #[test]
37    fn laws_hold() {
38        assert_semiring_laws(&[BoolRing(false), BoolRing(true)]);
39    }
40
41    #[test]
42    fn star_is_always_true() {
43        assert_eq!(BoolRing(false).star(), Some(BoolRing(true)));
44        assert_eq!(BoolRing(true).star(), Some(BoolRing(true)));
45    }
46}