use super::{SplitMix64, ZIG_F, ZIG_K, ZIG_N, ZIG_W, fast_candidate, unpack, ziggurat_fixup};
const TWO_POW_31: u32 = 0x8000_0000;
#[kani::proof]
fn ziggurat_unpack_indices_in_range() {
let word: u64 = kani::any();
let (sign, layer, j) = unpack(word);
assert!(layer < ZIG_N, "layer {layer} escaped [0, ZIG_N)");
assert!(j < TWO_POW_31, "magnitude j escaped the 31-bit range");
assert!(sign == 1.0 || sign == -1.0, "sign was neither +1 nor -1");
}
#[kani::proof]
fn ziggurat_table_indices_in_bounds() {
let word: u64 = kani::any();
let (_, layer, _) = unpack(word);
assert!(ZIG_K.get(layer).is_some(), "ZIG_K index out of bounds");
assert!(ZIG_W.get(layer).is_some(), "ZIG_W index out of bounds");
assert!(ZIG_F.get(layer).is_some(), "ZIG_F index out of bounds");
if layer > 0 {
assert!(
ZIG_F.get(layer - 1).is_some(),
"ZIG_F[layer-1] index out of bounds"
);
}
}
#[kani::proof]
fn ziggurat_fast_candidate_finite() {
let word: u64 = kani::any();
let (candidate, _accepted) = fast_candidate(word);
assert!(candidate.is_finite(), "fast-path candidate was non-finite");
}
#[kani::proof]
#[kani::unwind(2)]
fn ziggurat_wedge_fixup_no_panic() {
let state: u64 = kani::any();
let mut rng = SplitMix64::new(state);
let layer: usize = kani::any();
kani::assume(layer >= 1);
kani::assume(layer < ZIG_N);
let j: u32 = kani::any();
kani::assume(j < TWO_POW_31);
let sign: f64 = if kani::any() { 1.0 } else { -1.0 };
let _ = ziggurat_fixup(&mut rng, sign, layer, j);
}