Skip to main content

superinstance_ffi/
constraint.rs

1/// Count how many constraint bounds are violated.
2/// vals[i] must be <= bounds[i] for satisfaction.
3/// Returns count of violations.
4#[no_mangle]
5pub extern "C" fn si_constraint_check(vals: *const f64, bounds: *const f64, n: usize) -> u8 {
6    if vals.is_null() || bounds.is_null() || n == 0 {
7        return 0;
8    }
9    let sv = unsafe { std::slice::from_raw_parts(vals, n) };
10    let sb = unsafe { std::slice::from_raw_parts(bounds, n) };
11    sv.iter().zip(sb.iter()).filter(|(v, b)| v > b).count() as u8
12}
13
14#[cfg(test)]
15mod tests {
16    use super::*;
17
18    #[test]
19    fn test_constraint_all_satisfied() {
20        let vals = [1.0, 2.0, 3.0];
21        let bounds = [2.0, 3.0, 4.0];
22        assert_eq!(si_constraint_check(vals.as_ptr(), bounds.as_ptr(), 3), 0);
23    }
24
25    #[test]
26    fn test_constraint_all_violated() {
27        let vals = [3.0, 4.0, 5.0];
28        let bounds = [1.0, 2.0, 3.0];
29        assert_eq!(si_constraint_check(vals.as_ptr(), bounds.as_ptr(), 3), 3);
30    }
31
32    #[test]
33    fn test_constraint_mixed() {
34        let vals = [1.0, 5.0, 2.0];
35        let bounds = [2.0, 3.0, 2.0]; // 1<=2 ok, 5>3 fail, 2<=2 ok
36        assert_eq!(si_constraint_check(vals.as_ptr(), bounds.as_ptr(), 3), 1);
37    }
38
39    #[test]
40    fn test_constraint_null() {
41        assert_eq!(si_constraint_check(std::ptr::null(), std::ptr::null(), 0), 0);
42    }
43}