vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
//! Arithmetic witness minimization.

/// Shrink a numeric witness while `is_failure` remains true.
///
/// The shrinker tries zero, one, signed boundaries, and repeated halving. It
/// never invents a passing case: the returned value is the smallest candidate
/// this deterministic pass can find that still reproduces the failure.
#[inline]
pub fn shrink_word(mut value: u32, is_failure: impl Fn(u32) -> bool) -> u32 {
    if !is_failure(value) {
        return value;
    }

    for candidate in [
        0,
        1,
        2,
        i32::MAX as u32,
        i32::MIN as u32,
        value.wrapping_sub(1),
    ] {
        if candidate != value && is_failure(candidate) {
            value = candidate;
        }
    }

    loop {
        let candidate = value / 2;
        if candidate == value || !is_failure(candidate) {
            break;
        }
        value = candidate;
    }
    value
}

/// Shrink each word in an arithmetic witness independently.
#[inline]
pub fn shrink_words(mut values: Vec<u32>, is_failure: impl Fn(&[u32]) -> bool) -> Vec<u32> {
    if !is_failure(&values) {
        return values;
    }

    for index in 0..values.len() {
        let original = values[index];
        values[index] = shrink_word(original, |candidate| {
            let mut trial = values.clone();
            trial[index] = candidate;
            is_failure(&trial)
        });
    }
    values
}