pub const AC_HP2_MIN_TPS: f32 = 380.0;
pub const AC_HP3_MIN_TPS: f32 = 390.0;
pub const AC_DECODE_HP_MIN_PARITY: f32 = 1.25;
pub const AC_HP2_GOLDEN_PASS_NUM: u32 = 2;
pub const AC_HP2_GOLDEN_PASS_DEN: u32 = 2;
pub const AC_HP3_CACHE_PATHS: usize = 3;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DecodeHpVerdict {
Pass,
Fail,
}
#[must_use]
pub fn verdict_from_zero_eprintln(
realizr_198_matches: u32,
replay_pos_matches: u32,
par062_unconditional_eprintln: u32,
) -> DecodeHpVerdict {
if realizr_198_matches == 0
&& replay_pos_matches == 0
&& par062_unconditional_eprintln == 0
{
DecodeHpVerdict::Pass
} else {
DecodeHpVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_tps_parity(tps: f32, parity: f32, min_tps: f32) -> DecodeHpVerdict {
if !tps.is_finite() || !parity.is_finite() {
return DecodeHpVerdict::Fail;
}
if tps <= 0.0 || parity <= 0.0 {
return DecodeHpVerdict::Fail;
}
if tps >= min_tps && parity >= AC_DECODE_HP_MIN_PARITY {
DecodeHpVerdict::Pass
} else {
DecodeHpVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_golden_output(pass: u32, total: u32) -> DecodeHpVerdict {
if total != AC_HP2_GOLDEN_PASS_DEN {
return DecodeHpVerdict::Fail;
}
if pass == AC_HP2_GOLDEN_PASS_NUM {
DecodeHpVerdict::Pass
} else {
DecodeHpVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_pmat450_gating(
pmat450_sites_total: u32,
pmat450_sites_gated: u32,
) -> DecodeHpVerdict {
if pmat450_sites_total == 0 {
return DecodeHpVerdict::Fail;
}
if pmat450_sites_gated == pmat450_sites_total {
DecodeHpVerdict::Pass
} else {
DecodeHpVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_symmetric_gating(paths_with_gating: &[bool]) -> DecodeHpVerdict {
if paths_with_gating.len() < AC_HP3_CACHE_PATHS {
return DecodeHpVerdict::Fail;
}
if paths_with_gating.iter().all(|&b| b) {
DecodeHpVerdict::Pass
} else {
DecodeHpVerdict::Fail
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn provenance_hp2_min_tps_is_380() {
assert_eq!(AC_HP2_MIN_TPS, 380.0);
}
#[test]
fn provenance_hp3_min_tps_is_390() {
assert_eq!(AC_HP3_MIN_TPS, 390.0);
}
#[test]
fn provenance_min_parity_is_1_25() {
assert_eq!(AC_DECODE_HP_MIN_PARITY, 1.25);
}
#[test]
fn provenance_golden_2_of_2() {
assert_eq!(AC_HP2_GOLDEN_PASS_NUM, 2);
assert_eq!(AC_HP2_GOLDEN_PASS_DEN, 2);
}
#[test]
fn provenance_hp3_cache_paths_is_3() {
assert_eq!(AC_HP3_CACHE_PATHS, 3);
}
#[test]
fn fhp2_001_pass_clean_hot_path() {
let v = verdict_from_zero_eprintln(0, 0, 0);
assert_eq!(v, DecodeHpVerdict::Pass);
}
#[test]
fn fhp2_001_fail_realizr_198_present() {
let v = verdict_from_zero_eprintln(1, 0, 0);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp2_001_fail_replay_pos_present() {
let v = verdict_from_zero_eprintln(0, 1, 0);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp2_001_fail_par062_unconditional_eprintln() {
let v = verdict_from_zero_eprintln(0, 0, 1);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp2_001_fail_all_three_diagnostics_present() {
let v = verdict_from_zero_eprintln(5, 5, 5);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp2_002_pass_at_thresholds() {
let v = verdict_from_tps_parity(380.0, 1.25, AC_HP2_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Pass);
}
#[test]
fn fhp2_002_pass_well_above() {
let v = verdict_from_tps_parity(450.0, 1.45, AC_HP2_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Pass);
}
#[test]
fn fhp2_002_fail_low_tps() {
let v = verdict_from_tps_parity(379.9, 1.30, AC_HP2_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp2_002_fail_low_parity() {
let v = verdict_from_tps_parity(400.0, 1.20, AC_HP2_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp3_002_pass_at_threshold() {
let v = verdict_from_tps_parity(390.0, 1.25, AC_HP3_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Pass);
}
#[test]
fn fhp3_002_fail_below_390() {
let v = verdict_from_tps_parity(385.0, 1.30, AC_HP3_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp_002_fail_nan() {
let v = verdict_from_tps_parity(f32::NAN, 1.30, AC_HP2_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Fail);
let v = verdict_from_tps_parity(400.0, f32::NAN, AC_HP2_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp_002_fail_zero_or_negative() {
let v = verdict_from_tps_parity(0.0, 1.30, AC_HP2_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Fail);
let v = verdict_from_tps_parity(400.0, -1.0, AC_HP2_MIN_TPS);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp2_003_pass_2_of_2() {
let v = verdict_from_golden_output(2, 2);
assert_eq!(v, DecodeHpVerdict::Pass);
}
#[test]
fn fhp2_003_fail_1_of_2() {
let v = verdict_from_golden_output(1, 2);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp2_003_fail_0_of_2() {
let v = verdict_from_golden_output(0, 2);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp2_003_fail_total_not_2() {
let v = verdict_from_golden_output(3, 3);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp3_001_pass_all_3_gated() {
let v = verdict_from_pmat450_gating(3, 3);
assert_eq!(v, DecodeHpVerdict::Pass);
}
#[test]
fn fhp3_001_fail_one_ungated() {
let v = verdict_from_pmat450_gating(3, 2);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp3_001_fail_zero_total() {
let v = verdict_from_pmat450_gating(0, 0);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp3_001_fail_gated_exceeds_total() {
let v = verdict_from_pmat450_gating(2, 3);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp3_003_pass_all_three_paths_gated() {
let v = verdict_from_symmetric_gating(&[true, true, true]);
assert_eq!(v, DecodeHpVerdict::Pass);
}
#[test]
fn fhp3_003_fail_only_hit_gated() {
let v = verdict_from_symmetric_gating(&[true, false, false]);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp3_003_fail_too_few_paths() {
let v = verdict_from_symmetric_gating(&[true, true]);
assert_eq!(v, DecodeHpVerdict::Fail);
}
#[test]
fn fhp3_003_pass_more_than_three() {
let v = verdict_from_symmetric_gating(&[true; 5]);
assert_eq!(v, DecodeHpVerdict::Pass);
}
#[test]
fn mutation_survey_001_only_zero_zero_zero_passes() {
for r in 0_u32..3 {
for p in 0_u32..3 {
for e in 0_u32..3 {
let v = verdict_from_zero_eprintln(r, p, e);
let expected = if r == 0 && p == 0 && e == 0 {
DecodeHpVerdict::Pass
} else {
DecodeHpVerdict::Fail
};
assert_eq!(v, expected, "(r,p,e)=({r},{p},{e})");
}
}
}
}
#[test]
fn realistic_healthy_decode_hot_path_passes_all_6() {
let v1 = verdict_from_zero_eprintln(0, 0, 0);
let v2 = verdict_from_tps_parity(440.4, 1.434, AC_HP2_MIN_TPS);
let v3 = verdict_from_golden_output(2, 2);
let v4 = verdict_from_pmat450_gating(3, 3);
let v5 = verdict_from_tps_parity(391.8, 1.36, AC_HP3_MIN_TPS);
let v6 = verdict_from_symmetric_gating(&[true, true, true]);
assert_eq!(v1, DecodeHpVerdict::Pass);
assert_eq!(v2, DecodeHpVerdict::Pass);
assert_eq!(v3, DecodeHpVerdict::Pass);
assert_eq!(v4, DecodeHpVerdict::Pass);
assert_eq!(v5, DecodeHpVerdict::Pass);
assert_eq!(v6, DecodeHpVerdict::Pass);
}
#[test]
fn realistic_pre_fix_all_6_failures() {
let v1 = verdict_from_zero_eprintln(2, 2, 5);
let v2 = verdict_from_tps_parity(184.0, 0.6, AC_HP2_MIN_TPS);
let v3 = verdict_from_golden_output(0, 2);
let v4 = verdict_from_pmat450_gating(3, 0);
let v5 = verdict_from_tps_parity(184.0, 0.6, AC_HP3_MIN_TPS);
let v6 = verdict_from_symmetric_gating(&[true, false, false]);
assert_eq!(v1, DecodeHpVerdict::Fail);
assert_eq!(v2, DecodeHpVerdict::Fail);
assert_eq!(v3, DecodeHpVerdict::Fail);
assert_eq!(v4, DecodeHpVerdict::Fail);
assert_eq!(v5, DecodeHpVerdict::Fail);
assert_eq!(v6, DecodeHpVerdict::Fail);
}
}