lattices/
semiring_application.rs

1//! Module containing the [`BinaryTrust`] applications.
2
3use crate::{Addition, Multiplication, One, Zero};
4#[derive(PartialEq, Debug)]
5// #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6
7/// Implementation of the Binary Trust semiring ({0,1}, OR, AND, False, True)
8pub struct BinaryTrust(bool);
9
10impl BinaryTrust {
11    /// Create a new 'Binary Trust' semiring instance.
12    pub fn new() -> Self {
13        Self(true)
14    }
15}
16
17impl Default for BinaryTrust {
18    fn default() -> Self {
19        Self::new()
20    }
21}
22
23/// Implementation of the addition trait for the Binary Trust semiring.
24impl Addition<BinaryTrust> for BinaryTrust {
25    /// OR operation
26    fn add(&mut self, other: BinaryTrust) {
27        self.0 = self.0 || other.0;
28    }
29}
30
31/// Implementation of the multiplication trait for the Binary Trust semiring.
32impl Multiplication<BinaryTrust> for BinaryTrust {
33    /// AND operation
34    fn mul(&mut self, other: BinaryTrust) {
35        self.0 = self.0 && other.0;
36    }
37}
38
39/// Implementation of Identity for addition.
40impl Zero<bool> for BinaryTrust {
41    /// False is the identity element for addition operation.
42    fn zero(&self) -> bool {
43        false
44    }
45}
46
47/// Implementation of Identity for multiplication.
48impl One<bool> for BinaryTrust {
49    /// True is the identity element for multiplication operation.
50    fn one(&self) -> bool {
51        true
52    }
53}
54
55/// Implementation of the Multiplicity semiring (N, +, *, 0, 1)
56pub struct Multiplicity(u32);
57
58impl Multiplicity {
59    /// Create a new instance of Multiplicity.
60    pub fn new(value: u32) -> Self {
61        Multiplicity(value)
62    }
63}
64
65/// Implementation of the addition trait for Multiplicity semiring.
66impl Addition<Multiplicity> for Multiplicity {
67    /// + operation
68    fn add(&mut self, other: Multiplicity) {
69        self.0 = self.0.checked_add(other.0).unwrap();
70    }
71}
72
73/// Implementation of the multiplication trait for Multiplicity semiring.
74impl Multiplication<Multiplicity> for Multiplicity {
75    /// * operation
76    fn mul(&mut self, other: Multiplicity) {
77        self.0 = self.0.checked_mul(other.0).unwrap();
78    }
79}
80
81/// Implementation of Identity for addition.
82impl Zero<u32> for Multiplicity {
83    /// 0 is the zero element of the semiring.  
84    fn zero(&self) -> u32 {
85        0
86    }
87}
88
89/// Implementation of Identity for multiplication.
90impl One<u32> for Multiplicity {
91    /// 1 is the one element of the semiring.
92    fn one(&self) -> u32 {
93        1
94    }
95}
96
97#[derive(Copy, Clone, Debug, PartialEq, Eq)]
98/// Implementation for N U Inf
99pub enum U32WithInfinity {
100    /// Infinity
101    Infinity,
102    /// Natural numbers
103    Finite(u32),
104}
105
106/// Implementation of the Cost/Tropical semiring (N U Inf, min, +, inf, 0)
107pub struct Cost(U32WithInfinity);
108
109impl Cost {
110    /// Create a new instance of Cost.
111    pub fn new(value: U32WithInfinity) -> Self {
112        Cost(value)
113    }
114}
115
116/// Implementation of the addition trait for Cost semiring.
117impl Addition<Cost> for Cost {
118    /// Min operation
119    fn add(&mut self, other: Cost) {
120        self.0 = match (self.0, other.0) {
121            (U32WithInfinity::Infinity, x) | (x, U32WithInfinity::Infinity) => x,
122            (U32WithInfinity::Finite(a), U32WithInfinity::Finite(b)) => {
123                U32WithInfinity::Finite(a.min(b))
124            }
125        };
126    }
127}
128
129/// Implementation of the multiplication trait for Cost semiring.
130impl Multiplication<Cost> for Cost {
131    /// + operation
132    fn mul(&mut self, other: Cost) {
133        self.0 = match (self.0, other.0) {
134            (U32WithInfinity::Infinity, _) | (_, U32WithInfinity::Infinity) => {
135                U32WithInfinity::Infinity
136            }
137            (U32WithInfinity::Finite(a), U32WithInfinity::Finite(b)) => {
138                U32WithInfinity::Finite(a + b)
139            }
140        };
141    }
142}
143
144/// Implementation of Identity for addition.
145impl Zero<U32WithInfinity> for Cost {
146    /// Infinity is the identity element for addition operation.
147    fn zero(&self) -> U32WithInfinity {
148        U32WithInfinity::Infinity
149    }
150}
151
152/// Implementation of Identity for multiplication.
153impl One<U32WithInfinity> for Cost {
154    /// 0 is the one element of the semiring.
155    fn one(&self) -> U32WithInfinity {
156        U32WithInfinity::Finite(0)
157    }
158}
159
160/// Implementation of the confidence Score semiring ([0, 1], max, *, 0, 1)
161pub struct ConfidenceScore(f64);
162
163impl ConfidenceScore {
164    /// Create a new instance of ConfidenceScore with the given value.
165    pub fn new(value: f64) -> Self {
166        // Ensure the value is within the range [0, 1]
167        assert!((0.0..=1.0).contains(&value));
168        ConfidenceScore(value)
169    }
170}
171
172/// Implementation of the addition trait for ConfidenceScore semiring.
173impl Addition<ConfidenceScore> for ConfidenceScore {
174    /// Maximum is the addition operation for ConfidenceScore semiring.
175    fn add(&mut self, other: ConfidenceScore) {
176        self.0 = f64::max(self.0, other.0);
177    }
178}
179
180/// Implementation of the multiplication trait for ConfidenceScore semiring.
181impl Multiplication<ConfidenceScore> for ConfidenceScore {
182    /// Multiplication is the multiplication operation for ConfidenceScore semiring.
183    fn mul(&mut self, other: ConfidenceScore) {
184        self.0 *= other.0;
185    }
186}
187
188/// Implementation of Identity for addition.
189impl Zero<f64> for ConfidenceScore {
190    /// 0 is the zero element of the semiring.
191    fn zero(&self) -> f64 {
192        0.0
193    }
194}
195
196/// Implementation of Identity for multiplication.
197impl One<f64> for ConfidenceScore {
198    /// 1 is the one element of the semiring.
199    fn one(&self) -> f64 {
200        1.0
201    }
202}
203
204/// Implementation of Fuzzy Logic semiring ([0, 1], max, min, 0, 1).
205pub struct FuzzyLogic(f64);
206
207impl FuzzyLogic {
208    /// Create a new instance of FuzzyLogic with the given value.
209    pub fn new(value: f64) -> Self {
210        // Ensure the value is within the range [0, 1]
211        assert!((0.0..=1.0).contains(&value));
212        FuzzyLogic(value)
213    }
214}
215
216/// Implementation of the addition trait for FuzzyLogic semiring.
217impl Addition<FuzzyLogic> for FuzzyLogic {
218    /// Maximum is the addition operation for FuzzyLogic semiring.
219    fn add(&mut self, other: FuzzyLogic) {
220        self.0 = f64::max(self.0, other.0);
221    }
222}
223
224/// Implementation of the multiplication trait for FuzzyLogic semiring.
225impl Multiplication<FuzzyLogic> for FuzzyLogic {
226    /// Minimum is the multiplication operation for FuzzyLogic semiring.
227    fn mul(&mut self, other: FuzzyLogic) {
228        self.0 = f64::min(self.0, other.0);
229    }
230}
231
232/// Implementation of Identity for addition.
233impl Zero<f64> for FuzzyLogic {
234    /// 0 is the zero element of the semiring.
235    fn zero(&self) -> f64 {
236        0.0
237    }
238}
239
240/// Implementation of Identity for multiplication.
241impl One<f64> for FuzzyLogic {
242    /// 1 is the one element of the semiring.
243    fn one(&self) -> f64 {
244        1.0
245    }
246}
247
248#[cfg(test)]
249mod test {
250
251    use super::*;
252
253    // Test for BinaryTrust ({0,1}, OR, AND, False, True)
254    #[test]
255    fn test_binary_trust() {
256        let mut binary_trust = BinaryTrust::new();
257
258        // Test addition (OR)
259        binary_trust.add(BinaryTrust(true));
260        assert!(binary_trust.0);
261        binary_trust = BinaryTrust::new();
262        binary_trust.add(BinaryTrust(false));
263        assert!(binary_trust.0);
264
265        // Test multiplication (AND)
266        binary_trust = BinaryTrust::new();
267        binary_trust.mul(BinaryTrust(true));
268        assert!(binary_trust.0);
269        binary_trust = BinaryTrust::new();
270        binary_trust.mul(BinaryTrust(false));
271        assert!(!binary_trust.0);
272
273        // Test identity element for addition (False)
274        assert!(!BinaryTrust(false).zero());
275
276        // Test identity element for multiplication (True)
277        assert!(BinaryTrust(true).one());
278    }
279
280    // Test for Multiplicity (N, +, *, 0, 1)
281    #[test]
282    fn test_multiplicity() {
283        let mut multiplicity = Multiplicity::new(5);
284
285        // Test addition (+)
286        multiplicity.add(Multiplicity(10));
287        assert_eq!(multiplicity.0, 15);
288        multiplicity = Multiplicity::new(5);
289        multiplicity.add(Multiplicity(0));
290        assert_eq!(multiplicity.0, 5);
291
292        // Test multiplication (*)
293        multiplicity = Multiplicity::new(5);
294        multiplicity.mul(Multiplicity(10));
295        assert_eq!(multiplicity.0, 50);
296        multiplicity = Multiplicity::new(10);
297        multiplicity.mul(Multiplicity(5));
298        assert_eq!(multiplicity.0, 50);
299        multiplicity = Multiplicity::new(5);
300        multiplicity.mul(Multiplicity(0));
301        assert_eq!(multiplicity.0, 0);
302
303        // Test identity element for addition (0)
304        assert_eq!(multiplicity.zero(), 0);
305
306        // Test identity element for multiplication (1)
307        assert_eq!(multiplicity.one(), 1);
308    }
309
310    // Test for Cost/Tropical semiring (N U Inf, min, +, inf, 0)
311    #[test]
312    fn test_cost() {
313        let mut cost = Cost::new(U32WithInfinity::Finite(5));
314
315        // Test addition (min)
316        cost.add(Cost::new(U32WithInfinity::Finite(10)));
317        assert_eq!(cost.0, U32WithInfinity::Finite(5));
318        cost = Cost::new(U32WithInfinity::Finite(5));
319        cost.add(Cost::new(U32WithInfinity::Infinity));
320        assert_eq!(cost.0, U32WithInfinity::Finite(5));
321        cost = Cost::new(U32WithInfinity::Infinity);
322        cost.add(Cost::new(U32WithInfinity::Finite(5)));
323        assert_eq!(cost.0, U32WithInfinity::Finite(5));
324        cost = Cost::new(U32WithInfinity::Infinity);
325        cost.add(Cost::new(U32WithInfinity::Infinity));
326        assert_eq!(cost.0, U32WithInfinity::Infinity);
327
328        // Test multiplication (+)
329        cost = Cost::new(U32WithInfinity::Finite(5));
330        cost.mul(Cost::new(U32WithInfinity::Finite(10)));
331        assert_eq!(cost.0, U32WithInfinity::Finite(15));
332        cost = Cost::new(U32WithInfinity::Finite(5));
333        cost.mul(Cost::new(U32WithInfinity::Infinity));
334        assert_eq!(cost.0, U32WithInfinity::Infinity);
335        cost = Cost::new(U32WithInfinity::Infinity);
336        cost.mul(Cost::new(U32WithInfinity::Finite(5)));
337        assert_eq!(cost.0, U32WithInfinity::Infinity);
338
339        // Test identity element for addition (Infinity)
340        assert_eq!(cost.zero(), U32WithInfinity::Infinity);
341
342        // Test identity element for multiplication (0)
343        assert_eq!(cost.one(), U32WithInfinity::Finite(0));
344    }
345
346    // Test for Confidence Score ([0, 1], max, *, 0, 1)
347    #[test]
348    fn test_confidence_score() {
349        let mut confidence_score = ConfidenceScore::new(0.5);
350
351        // Test addition (max)
352        confidence_score.add(ConfidenceScore::new(0.6));
353        assert_eq!(confidence_score.0, 0.6);
354        confidence_score = ConfidenceScore::new(0.5);
355        confidence_score.add(ConfidenceScore::new(0.4));
356        assert_eq!(confidence_score.0, 0.5);
357
358        // Test multiplication (*)
359        confidence_score = ConfidenceScore::new(0.5);
360        confidence_score.mul(ConfidenceScore::new(0.6));
361        assert_eq!(confidence_score.0, 0.3);
362        confidence_score = ConfidenceScore::new(0.5);
363        confidence_score.mul(ConfidenceScore::new(0.4));
364        assert_eq!(confidence_score.0, 0.2);
365
366        // Test identity element for addition (0)
367        assert_eq!(confidence_score.zero(), 0.0);
368
369        // Test identity element for multiplication (1)
370        assert_eq!(confidence_score.one(), 1.0);
371    }
372
373    // Test for Fuzzy Logic ([0, 1], max, min, 0, 1).
374    #[test]
375    fn test_fuzzy_logic() {
376        let mut fuzzy_logic = FuzzyLogic::new(0.5);
377
378        // Test addition (max)
379        fuzzy_logic.add(FuzzyLogic::new(0.6));
380        assert_eq!(fuzzy_logic.0, 0.6);
381        fuzzy_logic = FuzzyLogic::new(0.5);
382        fuzzy_logic.add(FuzzyLogic::new(0.4));
383        assert_eq!(fuzzy_logic.0, 0.5);
384
385        // Test multiplication (min)
386        fuzzy_logic = FuzzyLogic::new(0.5);
387        fuzzy_logic.mul(FuzzyLogic::new(0.6));
388        assert_eq!(fuzzy_logic.0, 0.5);
389        fuzzy_logic = FuzzyLogic::new(0.5);
390        fuzzy_logic.mul(FuzzyLogic::new(0.4));
391        assert_eq!(fuzzy_logic.0, 0.4);
392
393        // Test identity element for addition (0)
394        assert_eq!(fuzzy_logic.zero(), 0.0);
395
396        // Test identity element for multiplication (1)
397        assert_eq!(fuzzy_logic.one(), 1.0);
398    }
399}