1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use super::error::BinaryError;
use crate::{Formula, Metric};
pub struct Implies<A, C> {
antecedent: A,
consequent: C,
}
impl<A, C> Implies<A, C> {
pub fn new(antecedent: A, consequent: C) -> Implies<A, C> {
Implies { antecedent, consequent }
}
}
impl<T, A, C> Formula<T> for Implies<A, C>
where
A: Formula<T>,
C: Formula<T>,
{
type Error = BinaryError<A::Error, C::Error>;
fn satisfied_by(&self, value: &T) -> Result<bool, Self::Error> {
let antecedent = self.antecedent.satisfied_by(value).map_err(BinaryError::Left)?;
if !antecedent {
return Ok(true);
}
self.consequent.satisfied_by(value).map_err(BinaryError::Right)
}
}
impl<T, A, C> Metric<T> for Implies<A, C>
where
A: Metric<T>,
C: Metric<T>,
{
type Error = BinaryError<A::Error, C::Error>;
fn distance(&self, value: &T) -> Result<f64, Self::Error> {
let ante_dist = self.antecedent.distance(value).map_err(BinaryError::Left)?;
let cons_dist = self.consequent.distance(value).map_err(BinaryError::Right)?;
Ok(f64::max(-ante_dist, cons_dist))
}
}