use axiolid_guarantees::{Certified, Precision, Sign};
use crate::arith::Arith;
use crate::dyadic::Dyadic;
use crate::interval::Interval;
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExactError {
NonFinite,
DegenerateLine,
NegativeRadius,
DifferentLines,
Undefined,
TooDeep,
DegenerateConic,
}
pub fn require_finite(values: &[f64]) -> Result<(), ExactError> {
if values.iter().all(|value| value.is_finite()) {
Ok(())
} else {
Err(ExactError::NonFinite)
}
}
pub trait SignExpr {
fn sign_in<T: Arith>(&self) -> Option<Sign>;
}
pub fn filter<E: SignExpr>(expr: &E) -> Certified {
match expr.sign_in::<Interval>() {
Some(sign) => Certified::Certain {
sign,
precision: Precision::F64,
},
None => Certified::Uncertain {
attempted: Precision::F64,
},
}
}
pub fn certify<E: SignExpr>(expr: &E) -> Result<Sign, ExactError> {
if let Some(sign) = expr.sign_in::<Interval>() {
return Ok(sign);
}
expr.sign_in::<Dyadic>().ok_or(ExactError::Undefined)
}