vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
pub use super::super::{SAMPLE, apply_unary};
pub use check_monotone::check_monotone;
pub use fake_broken_monotone_inverts::fake_broken_monotone_inverts;

use crate::properties::tests::{pair, primitive, result_u32, unary};
use crate::spec::law::AlgebraicLaw;

#[inline]
pub fn check_monotone(id: &str, f: fn(&[u8]) -> Vec<u8>) {
    // a <= b implies f(a) <= f(b) for unary f.
    let mut sorted = SAMPLE;
    sorted.sort_unstable();
    for window in sorted.windows(2) {
        let a = window[0];
        let b = window[1];
        let fa = apply_unary(f, a);
        let fb = apply_unary(f, b);
        assert!(
            fa <= fb,
            "{id} violates Monotone at ({a:#010x} <= {b:#010x}): \
             f(a)={fa:#010x} > f(b)={fb:#010x}"
        );
    }
}


#[inline]
pub fn fake_broken_monotone_inverts(input: &[u8]) -> Vec<u8> {
    let a = u32::from_le_bytes([input[0], input[1], input[2], input[3]]);
    (u32::MAX - a).to_le_bytes().to_vec()
}

use crate::properties::tests::declared_laws::identity::fake_identity_unary;

#[test]
fn monotone_checker_accepts_identity() {
    check_monotone("fake.identity", fake_identity_unary);
}


#[test]
fn monotone_checker_catches_violation() {
    let result = std::panic::catch_unwind(|| {
        check_monotone("fake.broken_monotone", fake_broken_monotone_inverts);
    });
    assert!(
        result.is_err(),
        "Monotone checker failed to catch an order-inverting impl"
    );
}