use crate::proof::algebra::checker::{verify_laws, VerificationLevel};
use crate::proof::algebra::inference::{infer_binary_laws, InferenceReport};
use crate::spec::law::{canonical_law_id, AlgebraicLaw};
use super::{LawAuditReport, same_law, PROBE_VALUES, check_and_record};
#[must_use]
#[inline]
pub fn audit_binary(
op_id: &str,
cpu_fn: fn(&[u8]) -> Vec<u8>,
declared: &[AlgebraicLaw],
) -> LawAuditReport {
let mut report = LawAuditReport {
op_id: op_id.to_string(),
laws: Vec::new(),
};
for law in declared {
let results = verify_laws(op_id, cpu_fn, &[law.clone()], true);
let any_violation = results.iter().find_map(|r| r.violation.clone());
let verdict = if any_violation.is_some() {
AuditVerdict::OverClaimed {
witness: format!("{:?}", any_violation),
}
} else {
AuditVerdict::Confirmed
};
report.laws.push(AuditedLaw {
law: law.clone(),
verdict,
});
}
let inferred: InferenceReport = infer_binary_laws(op_id, cpu_fn);
for inferred_law in &inferred.proven {
if declared.iter().any(|d| same_law(d, &inferred_law.law)) {
continue;
}
report.laws.push(AuditedLaw {
law: inferred_law.law.clone(),
verdict: AuditVerdict::UnderClaimed {
suggestion: inferred_law.recommendation.clone(),
},
});
}
for element in PROBE_VALUES {
check_and_record(
op_id,
cpu_fn,
AlgebraicLaw::Identity { element: *element },
declared,
&mut report,
);
check_and_record(
op_id,
cpu_fn,
AlgebraicLaw::Absorbing { element: *element },
declared,
&mut report,
);
}
report
}