use crate::{Addition, Multiplication, One, Zero};
#[derive(PartialEq, Debug)]
pub struct BinaryTrust(bool);
impl BinaryTrust {
pub fn new() -> Self {
Self(true)
}
}
impl Default for BinaryTrust {
fn default() -> Self {
Self::new()
}
}
impl Addition<BinaryTrust> for BinaryTrust {
fn add(&mut self, other: BinaryTrust) {
self.0 = self.0 || other.0;
}
}
impl Multiplication<BinaryTrust> for BinaryTrust {
fn mul(&mut self, other: BinaryTrust) {
self.0 = self.0 && other.0;
}
}
impl Zero<bool> for BinaryTrust {
fn zero(&self) -> bool {
false
}
}
impl One<bool> for BinaryTrust {
fn one(&self) -> bool {
true
}
}
pub struct Multiplicity(u32);
impl Multiplicity {
pub fn new(value: u32) -> Self {
Multiplicity(value)
}
}
impl Addition<Multiplicity> for Multiplicity {
fn add(&mut self, other: Multiplicity) {
self.0 = self.0.checked_add(other.0).unwrap();
}
}
impl Multiplication<Multiplicity> for Multiplicity {
fn mul(&mut self, other: Multiplicity) {
self.0 = self.0.checked_mul(other.0).unwrap();
}
}
impl Zero<u32> for Multiplicity {
fn zero(&self) -> u32 {
0
}
}
impl One<u32> for Multiplicity {
fn one(&self) -> u32 {
1
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum U32WithInfinity {
Infinity,
Finite(u32),
}
pub struct Cost(U32WithInfinity);
impl Cost {
pub fn new(value: U32WithInfinity) -> Self {
Cost(value)
}
}
impl Addition<Cost> for Cost {
fn add(&mut self, other: Cost) {
self.0 = match (self.0, other.0) {
(U32WithInfinity::Infinity, x) | (x, U32WithInfinity::Infinity) => x,
(U32WithInfinity::Finite(a), U32WithInfinity::Finite(b)) => {
U32WithInfinity::Finite(a.min(b))
}
};
}
}
impl Multiplication<Cost> for Cost {
fn mul(&mut self, other: Cost) {
self.0 = match (self.0, other.0) {
(U32WithInfinity::Infinity, _) | (_, U32WithInfinity::Infinity) => {
U32WithInfinity::Infinity
}
(U32WithInfinity::Finite(a), U32WithInfinity::Finite(b)) => {
U32WithInfinity::Finite(a + b)
}
};
}
}
impl Zero<U32WithInfinity> for Cost {
fn zero(&self) -> U32WithInfinity {
U32WithInfinity::Infinity
}
}
impl One<U32WithInfinity> for Cost {
fn one(&self) -> U32WithInfinity {
U32WithInfinity::Finite(0)
}
}
pub struct ConfidenceScore(f64);
impl ConfidenceScore {
pub fn new(value: f64) -> Self {
assert!((0.0..=1.0).contains(&value));
ConfidenceScore(value)
}
}
impl Addition<ConfidenceScore> for ConfidenceScore {
fn add(&mut self, other: ConfidenceScore) {
self.0 = f64::max(self.0, other.0);
}
}
impl Multiplication<ConfidenceScore> for ConfidenceScore {
fn mul(&mut self, other: ConfidenceScore) {
self.0 *= other.0;
}
}
impl Zero<f64> for ConfidenceScore {
fn zero(&self) -> f64 {
0.0
}
}
impl One<f64> for ConfidenceScore {
fn one(&self) -> f64 {
1.0
}
}
pub struct FuzzyLogic(f64);
impl FuzzyLogic {
pub fn new(value: f64) -> Self {
assert!((0.0..=1.0).contains(&value));
FuzzyLogic(value)
}
}
impl Addition<FuzzyLogic> for FuzzyLogic {
fn add(&mut self, other: FuzzyLogic) {
self.0 = f64::max(self.0, other.0);
}
}
impl Multiplication<FuzzyLogic> for FuzzyLogic {
fn mul(&mut self, other: FuzzyLogic) {
self.0 = f64::min(self.0, other.0);
}
}
impl Zero<f64> for FuzzyLogic {
fn zero(&self) -> f64 {
0.0
}
}
impl One<f64> for FuzzyLogic {
fn one(&self) -> f64 {
1.0
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_binary_trust() {
let mut binary_trust = BinaryTrust::new();
binary_trust.add(BinaryTrust(true));
assert!(binary_trust.0);
binary_trust = BinaryTrust::new();
binary_trust.add(BinaryTrust(false));
assert!(binary_trust.0);
binary_trust = BinaryTrust::new();
binary_trust.mul(BinaryTrust(true));
assert!(binary_trust.0);
binary_trust = BinaryTrust::new();
binary_trust.mul(BinaryTrust(false));
assert!(!binary_trust.0);
assert!(!BinaryTrust(false).zero());
assert!(BinaryTrust(true).one());
}
#[test]
fn test_multiplicity() {
let mut multiplicity = Multiplicity::new(5);
multiplicity.add(Multiplicity(10));
assert_eq!(multiplicity.0, 15);
multiplicity = Multiplicity::new(5);
multiplicity.add(Multiplicity(0));
assert_eq!(multiplicity.0, 5);
multiplicity = Multiplicity::new(5);
multiplicity.mul(Multiplicity(10));
assert_eq!(multiplicity.0, 50);
multiplicity = Multiplicity::new(10);
multiplicity.mul(Multiplicity(5));
assert_eq!(multiplicity.0, 50);
multiplicity = Multiplicity::new(5);
multiplicity.mul(Multiplicity(0));
assert_eq!(multiplicity.0, 0);
assert_eq!(multiplicity.zero(), 0);
assert_eq!(multiplicity.one(), 1);
}
#[test]
fn test_cost() {
let mut cost = Cost::new(U32WithInfinity::Finite(5));
cost.add(Cost::new(U32WithInfinity::Finite(10)));
assert_eq!(cost.0, U32WithInfinity::Finite(5));
cost = Cost::new(U32WithInfinity::Finite(5));
cost.add(Cost::new(U32WithInfinity::Infinity));
assert_eq!(cost.0, U32WithInfinity::Finite(5));
cost = Cost::new(U32WithInfinity::Infinity);
cost.add(Cost::new(U32WithInfinity::Finite(5)));
assert_eq!(cost.0, U32WithInfinity::Finite(5));
cost = Cost::new(U32WithInfinity::Infinity);
cost.add(Cost::new(U32WithInfinity::Infinity));
assert_eq!(cost.0, U32WithInfinity::Infinity);
cost = Cost::new(U32WithInfinity::Finite(5));
cost.mul(Cost::new(U32WithInfinity::Finite(10)));
assert_eq!(cost.0, U32WithInfinity::Finite(15));
cost = Cost::new(U32WithInfinity::Finite(5));
cost.mul(Cost::new(U32WithInfinity::Infinity));
assert_eq!(cost.0, U32WithInfinity::Infinity);
cost = Cost::new(U32WithInfinity::Infinity);
cost.mul(Cost::new(U32WithInfinity::Finite(5)));
assert_eq!(cost.0, U32WithInfinity::Infinity);
assert_eq!(cost.zero(), U32WithInfinity::Infinity);
assert_eq!(cost.one(), U32WithInfinity::Finite(0));
}
#[test]
fn test_confidence_score() {
let mut confidence_score = ConfidenceScore::new(0.5);
confidence_score.add(ConfidenceScore::new(0.6));
assert_eq!(confidence_score.0, 0.6);
confidence_score = ConfidenceScore::new(0.5);
confidence_score.add(ConfidenceScore::new(0.4));
assert_eq!(confidence_score.0, 0.5);
confidence_score = ConfidenceScore::new(0.5);
confidence_score.mul(ConfidenceScore::new(0.6));
assert_eq!(confidence_score.0, 0.3);
confidence_score = ConfidenceScore::new(0.5);
confidence_score.mul(ConfidenceScore::new(0.4));
assert_eq!(confidence_score.0, 0.2);
assert_eq!(confidence_score.zero(), 0.0);
assert_eq!(confidence_score.one(), 1.0);
}
#[test]
fn test_fuzzy_logic() {
let mut fuzzy_logic = FuzzyLogic::new(0.5);
fuzzy_logic.add(FuzzyLogic::new(0.6));
assert_eq!(fuzzy_logic.0, 0.6);
fuzzy_logic = FuzzyLogic::new(0.5);
fuzzy_logic.add(FuzzyLogic::new(0.4));
assert_eq!(fuzzy_logic.0, 0.5);
fuzzy_logic = FuzzyLogic::new(0.5);
fuzzy_logic.mul(FuzzyLogic::new(0.6));
assert_eq!(fuzzy_logic.0, 0.5);
fuzzy_logic = FuzzyLogic::new(0.5);
fuzzy_logic.mul(FuzzyLogic::new(0.4));
assert_eq!(fuzzy_logic.0, 0.4);
assert_eq!(fuzzy_logic.zero(), 0.0);
assert_eq!(fuzzy_logic.one(), 1.0);
}
}