use vyre_primitives::types::{evaluate_shape, ShapeFormula};
#[must_use]
pub fn evaluate_shape_formula(formula: &ShapeFormula, count: u32) -> bool {
use crate::observability::{bump, dataflow_fixpoint_calls};
bump(&dataflow_fixpoint_calls);
evaluate_shape(formula, count)
}
#[must_use]
pub fn formula_proves_non_empty(formula: &ShapeFormula) -> bool {
use crate::observability::{bump, dataflow_fixpoint_calls};
bump(&dataflow_fixpoint_calls);
formula.proves_non_empty()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn at_least_evaluation() {
let f = ShapeFormula::AtLeast(8);
assert!(!evaluate_shape_formula(&f, 0));
assert!(evaluate_shape_formula(&f, 8));
}
#[test]
fn alignment_predicate() {
let f = ShapeFormula::MultipleOf(4);
assert!(evaluate_shape_formula(&f, 12));
assert!(!evaluate_shape_formula(&f, 11));
}
#[test]
fn conjunction_evaluation() {
let f = ShapeFormula::And(
Box::new(ShapeFormula::AtLeast(8)),
Box::new(ShapeFormula::AtMost(256)),
);
assert!(!evaluate_shape_formula(&f, 7));
assert!(evaluate_shape_formula(&f, 100));
assert!(!evaluate_shape_formula(&f, 257));
}
#[test]
fn matches_primitive_directly() {
let f = ShapeFormula::And(
Box::new(ShapeFormula::AtLeast(16)),
Box::new(ShapeFormula::MultipleOf(4)),
);
for c in [0u32, 8, 15, 16, 17, 20, 100] {
assert_eq!(
evaluate_shape_formula(&f, c),
evaluate_shape(&f, c),
"drift on c = {c}"
);
}
}
#[test]
fn multiple_of_zero_never_holds() {
let f = ShapeFormula::MultipleOf(0);
for c in [0u32, 1, 100, u32::MAX] {
assert!(
!evaluate_shape_formula(&f, c),
"MultipleOf(0) must never hold (c = {c})"
);
}
}
#[test]
fn proves_non_empty_at_least_one() {
assert!(formula_proves_non_empty(&ShapeFormula::AtLeast(1)));
assert!(formula_proves_non_empty(&ShapeFormula::Exactly(64)));
}
#[test]
fn proves_non_empty_no_lower_bound() {
assert!(!formula_proves_non_empty(&ShapeFormula::AtMost(256)));
assert!(!formula_proves_non_empty(&ShapeFormula::MultipleOf(4)));
}
#[test]
fn conjunction_inherits_non_empty_from_either_side() {
let left_proves = ShapeFormula::And(
Box::new(ShapeFormula::AtLeast(1)),
Box::new(ShapeFormula::AtMost(100)),
);
let right_proves = ShapeFormula::And(
Box::new(ShapeFormula::AtMost(100)),
Box::new(ShapeFormula::AtLeast(1)),
);
assert!(formula_proves_non_empty(&left_proves));
assert!(formula_proves_non_empty(&right_proves));
}
}