use crate::interval::Interval;
use core::cmp::Ordering;
pub fn new_orientation<A: Copy + PartialOrd>(x: A, y: A) -> bool {
let i = Interval::new(x, y);
matches!(
(x.partial_cmp(&y), i),
(
Some(Ordering::Less | Ordering::Equal),
Interval::Closed { .. }
) | (Some(Ordering::Greater) | None, Interval::Empty)
)
}
pub fn singleton_contains_self<A: Clone + PartialOrd>(a: A) -> bool {
Interval::singleton(a.clone()).contains(&a)
}
pub fn empty_contains_nothing<A: PartialOrd>(p: &A) -> bool {
!Interval::<A>::Empty.contains(p)
}
pub fn imap_identity_preserves<A: Copy + PartialOrd>(x: A, y: A) -> bool {
let i = Interval::new(x, y);
i.imap(|a| a) == i
}
pub fn imap_saturating_add_preserves(i: Interval<i64>, k: i64) -> bool {
let f = |a: i64| a.saturating_add(k);
let expected = match i {
Interval::Empty => Interval::Empty,
Interval::Closed { lo, hi } => Interval::new(f(lo), f(hi)),
};
i.imap(f) == expected
}
pub fn containment_preorder_reflex<A: PartialOrd>(i: &Interval<A>) -> bool {
matches!(i.partial_cmp(i), Some(Ordering::Equal))
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
fn arb_interval_i32() -> impl Strategy<Value = Interval<i32>> {
prop_oneof![
1 => Just(Interval::Empty),
9 => (any::<i32>(), any::<i32>()).prop_map(|(a, b)| {
let (lo, hi) = if a <= b { (a, b) } else { (b, a) };
Interval::Closed { lo, hi }
}),
]
}
fn arb_interval_i64() -> impl Strategy<Value = Interval<i64>> {
prop_oneof![
1 => Just(Interval::Empty),
9 => (any::<i64>(), any::<i64>()).prop_map(|(a, b)| {
let (lo, hi) = if a <= b { (a, b) } else { (b, a) };
Interval::Closed { lo, hi }
}),
]
}
proptest! {
#[test]
fn prop_new_orientation(x: i32, y: i32) {
prop_assert!(new_orientation(x, y));
}
#[test]
fn prop_singleton_contains_self(a: i32) {
prop_assert!(singleton_contains_self(a));
}
#[test]
fn prop_empty_contains_nothing(p: i32) {
prop_assert!(empty_contains_nothing(&p));
}
#[test]
fn prop_imap_identity_preserves(x: i32, y: i32) {
prop_assert!(imap_identity_preserves(x, y));
}
#[test]
fn prop_imap_saturating_add_preserves(i in arb_interval_i64(), k: i64) {
prop_assert!(imap_saturating_add_preserves(i, k));
}
#[test]
fn prop_containment_preorder_reflex(i in arb_interval_i32()) {
prop_assert!(containment_preorder_reflex(&i));
}
}
}