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};
#[cfg(test)]
mod tests {
use super::*;
fn add_cpu(input: &[u8]) -> Vec<u8> {
let a = u32::from_le_bytes(input[..4].try_into().unwrap_or_default());
let b = u32::from_le_bytes(input[4..8].try_into().unwrap_or_default());
a.wrapping_add(b).to_le_bytes().to_vec()
}
fn sub_cpu(input: &[u8]) -> Vec<u8> {
let a = u32::from_le_bytes(input[..4].try_into().unwrap_or_default());
let b = u32::from_le_bytes(input[4..8].try_into().unwrap_or_default());
a.wrapping_sub(b).to_le_bytes().to_vec()
}
#[test]
fn audit_add_confirms_commutativity_and_identity_zero() {
let report = audit_binary(
"test.add",
add_cpu,
&[
AlgebraicLaw::Commutative,
AlgebraicLaw::Identity { element: 0 },
],
);
assert!(
report
.laws
.iter()
.any(|a| matches!(a.law, AlgebraicLaw::Commutative)
&& matches!(a.verdict, AuditVerdict::Confirmed)),
"commutativity must confirm on add: {report:?}"
);
assert!(
report
.laws
.iter()
.any(|a| matches!(a.law, AlgebraicLaw::Identity { element: 0 })
&& matches!(a.verdict, AuditVerdict::Confirmed)),
"identity 0 must confirm on add: {report:?}"
);
assert!(report.over_claimed().is_empty());
}
#[test]
fn audit_sub_rejects_falsely_claimed_commutativity() {
let report = audit_binary("test.sub", sub_cpu, &[AlgebraicLaw::Commutative]);
assert!(
report
.laws
.iter()
.any(|a| matches!(a.verdict, AuditVerdict::OverClaimed { .. })),
"subtraction is not commutative; the audit must reject the false claim: {report:?}"
);
assert!(!report.is_clean());
}
#[test]
fn identity_subsumes_left_identity() {
assert!(same_law(
&AlgebraicLaw::Identity { element: 5 },
&AlgebraicLaw::LeftIdentity { element: 5 }
));
}
#[test]
fn identity_subsumes_right_identity() {
assert!(same_law(
&AlgebraicLaw::Identity { element: 5 },
&AlgebraicLaw::RightIdentity { element: 5 }
));
}
#[test]
fn left_identity_subsumes_identity_symmetric() {
assert!(same_law(
&AlgebraicLaw::LeftIdentity { element: 7 },
&AlgebraicLaw::Identity { element: 7 }
));
}
#[test]
fn right_identity_subsumes_identity_symmetric() {
assert!(same_law(
&AlgebraicLaw::RightIdentity { element: 7 },
&AlgebraicLaw::Identity { element: 7 }
));
}
#[test]
fn identity_does_not_subsume_different_element() {
assert!(!same_law(
&AlgebraicLaw::Identity { element: 5 },
&AlgebraicLaw::LeftIdentity { element: 6 }
));
}
#[test]
fn absorbing_subsumes_left_absorbing() {
assert!(same_law(
&AlgebraicLaw::Absorbing { element: 3 },
&AlgebraicLaw::LeftAbsorbing { element: 3 }
));
}
#[test]
fn absorbing_subsumes_right_absorbing() {
assert!(same_law(
&AlgebraicLaw::Absorbing { element: 3 },
&AlgebraicLaw::RightAbsorbing { element: 3 }
));
}
#[test]
fn left_absorbing_subsumes_absorbing_symmetric() {
assert!(same_law(
&AlgebraicLaw::LeftAbsorbing { element: 7 },
&AlgebraicLaw::Absorbing { element: 7 }
));
}
#[test]
fn right_absorbing_subsumes_absorbing_symmetric() {
assert!(same_law(
&AlgebraicLaw::RightAbsorbing { element: 7 },
&AlgebraicLaw::Absorbing { element: 7 }
));
}
#[test]
fn absorbing_does_not_subsume_different_element() {
assert!(!same_law(
&AlgebraicLaw::Absorbing { element: 5 },
&AlgebraicLaw::LeftAbsorbing { element: 6 }
));
}
#[test]
fn distinct_laws_remain_distinct() {
assert!(!same_law(
&AlgebraicLaw::Commutative,
&AlgebraicLaw::Associative
));
}
}