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
51
52
53
54
55
//! Examples of generic numeric components.

use crate::model::Component;
use crate::{component, ret};
use std::ops::{Add, Div, Mul, Sub};

/// A predefined component with three numeric variables a, b, and c that satisfy the constraint `a + b = c`.
pub fn sum<T>() -> Component<T>
where
    T: Add<Output = T> + Sub<Output = T> + Default + Copy,
{
    let v = T::default();
    component! {
        component Component {
            let a: T = v, b: T = v, c: T = v;
            constraint Sum {
                abc(a: &T, b: &T) -> [c] = ret![*a + *b];
                acb(a: &T, c: &T) -> [b] = ret![*c - *a];
                bca(b: &T, c: &T) -> [a] = ret![*c - *b];
            }
        }
    }
}

/// A predefined component with three numeric variables a, b, and c that satisfy the constraint `a * b = c`.
/// This one also requires that the default values are provided to avoid the `Default` restriction.
pub fn product_with_defaults<T>(a: T, b: T, c: T) -> Component<T>
where
    T: Mul<Output = T> + Div<Output = T> + Copy,
{
    component! {
        component comp {
            let a: T = a, b: T = b, c: T = c;
            constraint sum {
                abc(a: &T, b: &T) -> [c] = ret![*a * *b];
                acb(a: &T, c: &T) -> [b] = ret![*c / *a];
                bca(b: &T, c: &T) -> [a] = ret![*c / *b];
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{product_with_defaults, sum};

    #[test]
    #[ignore = "This test is just to make sure it compiles"]
    fn it_compiles() {
        let _ = sum::<i32>();
        let _ = sum::<f32>();
        let _ = product_with_defaults::<u32>(3, 4, 12);
        let _ = product_with_defaults::<f64>(3.0, 4.0, 12.0);
    }
}