#[cfg(kani)]
mod proofs {
use crate::envelope::AdmissibilityEnvelope;
use crate::grammar::{GrammarEvaluator, GrammarState};
use crate::platform::{PlatformContext, WaveformState};
use crate::sign::SignTuple;
use crate::engine::DecimationAccumulator;
use crate::fixedpoint::{quantize_q16_16, apply_periodic_resync, PeriodicResyncConfig};
#[kani::proof]
#[kani::unwind(8)]
fn proof_grammar_evaluator_no_panic() {
let norm: f32 = kani::any();
let drift: f32 = kani::any();
let slew: f32 = kani::any();
let rho: f32 = kani::any();
kani::assume(rho > 0.0);
let sign = SignTuple::new(norm, drift, slew);
let env = AdmissibilityEnvelope::new(rho);
let mut eval_op = GrammarEvaluator::<4>::new();
let _ = eval_op.evaluate(&sign, &env, WaveformState::Operational);
let mut eval_tr = GrammarEvaluator::<4>::new();
let _ = eval_tr.evaluate(&sign, &env, WaveformState::Transition);
let mut eval_long = GrammarEvaluator::<4>::new();
for _ in 0..5_usize {
let n2: f32 = kani::any();
kani::assume(n2 >= 0.0);
let sign2 = SignTuple::new(n2, 0.0, 0.0);
let _ = eval_long.evaluate(&sign2, &env, WaveformState::Operational);
}
}
#[kani::proof]
fn proof_grammar_state_severity_bounded() {
let norm: f32 = kani::any();
let drift: f32 = kani::any();
let slew: f32 = kani::any();
let rho: f32 = kani::any();
kani::assume(rho > 0.0);
kani::assume(norm.is_finite() && norm >= 0.0);
let sign = SignTuple::new(norm, drift, slew);
let env = AdmissibilityEnvelope::new(rho);
let mut eval = GrammarEvaluator::<4>::new();
let state = eval.evaluate(&sign, &env, WaveformState::Operational);
let sev = state.severity();
kani::assert(sev <= 2, "severity() exceeds maximum ordinal 2");
let trust = state.severity_trust();
kani::assert(trust >= 0.0, "severity_trust() is negative");
kani::assert(trust <= 1.0, "severity_trust() exceeds 1.0");
}
#[kani::proof]
fn proof_envelope_judgment_consistency() {
let norm: f32 = kani::any();
let rho: f32 = kani::any();
let mult: f32 = kani::any();
kani::assume(norm.is_finite() && norm >= 0.0);
kani::assume(rho > 0.0 && rho < 1.0e6);
kani::assume(mult >= 1.0);
let env = AdmissibilityEnvelope::new(rho);
let is_viol = env.is_violation(norm, mult);
let is_bound = env.is_boundary_approach(norm, mult);
if is_viol {
kani::assert(is_bound, "is_violation() without is_boundary_approach()");
}
}
#[kani::proof]
#[kani::unwind(16)]
fn proof_decimation_exact_epoch_count() {
const FACTOR: u32 = 4;
let mut acc = DecimationAccumulator::new(FACTOR);
let mut fires: u32 = 0;
for _ in 0..FACTOR {
let norm: f32 = kani::any();
kani::assume(norm.is_finite() && norm >= 0.0);
kani::assume(norm < 1.0e9_f32);
if let Some(rms) = acc.push(norm) {
fires += 1;
kani::assert(rms.is_finite(), "RMS is not finite");
kani::assert(rms >= 0.0, "RMS is negative");
}
}
kani::assert(fires == 1, "DecimationAccumulator did not fire exactly once");
}
#[kani::proof]
fn proof_fixedpoint_resync_drift_bounded() {
let accumulator: i32 = kani::any();
let reference_q: i32 = kani::any();
let max_drift_ulps: i32 = kani::any();
kani::assume(max_drift_ulps > 0 && max_drift_ulps < i32::MAX / 2);
kani::assume(accumulator > i32::MIN / 2 && accumulator < i32::MAX / 2);
kani::assume(reference_q > i32::MIN / 2 && reference_q < i32::MAX / 2);
let (new_acc, resynced) = apply_periodic_resync(
accumulator,
reference_q,
max_drift_ulps,
);
if resynced {
let drift = if new_acc >= reference_q {
new_acc - reference_q
} else {
reference_q - new_acc
};
kani::assert(
drift <= max_drift_ulps,
"post-resync drift exceeds max_drift_ulps",
);
}
}
#[kani::proof]
fn proof_quantize_q16_16_no_panic() {
let x: f32 = kani::any();
kani::assume(x.is_finite());
let _q = quantize_q16_16(x.into());
}
}