use std::collections::HashSet;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Rank {
Rank4,
Rank3,
Rank2,
Rank1,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ValidationStatus {
Valid { rank: Rank },
Invalid { reason: String },
}
impl ValidationStatus {
pub fn is_valid(&self) -> bool {
matches!(self, ValidationStatus::Valid { .. })
}
}
pub struct OracleValidator {
rank1_keywords: HashSet<&'static str>,
rank2_keywords: HashSet<&'static str>,
rank3_keywords: HashSet<&'static str>,
rank4_keywords: HashSet<&'static str>,
forbidden_keywords: HashSet<&'static str>,
}
impl OracleValidator {
pub fn new() -> Self {
let mut rank1_keywords = HashSet::new();
rank1_keywords.insert("bellman");
rank1_keywords.insert("equation");
rank1_keywords.insert("western");
rank1_keywords.insert("electric");
rank1_keywords.insert("theorem");
rank1_keywords.insert("proven");
rank1_keywords.insert("mathematical");
rank1_keywords.insert("property");
rank1_keywords.insert("convergence");
rank1_keywords.insert("bound");
let mut rank2_keywords = HashSet::new();
rank2_keywords.insert("contract");
rank2_keywords.insert("invariant");
rank2_keywords.insert("domain");
rank2_keywords.insert("rule");
rank2_keywords.insert("policy");
rank2_keywords.insert("always");
rank2_keywords.insert("never");
rank2_keywords.insert("must");
let mut rank3_keywords = HashSet::new();
rank3_keywords.insert("perturbation");
rank3_keywords.insert("metamorphic");
rank3_keywords.insert("relation");
rank3_keywords.insert("increase");
rank3_keywords.insert("decrease");
rank3_keywords.insert("proportional");
rank3_keywords.insert("inverse");
let mut rank4_keywords = HashSet::new();
rank4_keywords.insert("convergence");
rank4_keywords.insert("trend");
rank4_keywords.insert("trial");
rank4_keywords.insert("seed");
rank4_keywords.insert("confidence");
rank4_keywords.insert("mean");
rank4_keywords.insert("variance");
rank4_keywords.insert("statistical");
let mut forbidden_keywords = HashSet::new();
forbidden_keywords.insert("computed_same_formula");
forbidden_keywords.insert("impl_variable");
forbidden_keywords.insert("code_path");
forbidden_keywords.insert("state_machine");
forbidden_keywords.insert("test_derives");
OracleValidator {
rank1_keywords,
rank2_keywords,
rank3_keywords,
rank4_keywords,
forbidden_keywords,
}
}
pub fn validate(
&self,
oracle_type: Rank,
assertion: &str,
implementation_context: &str,
) -> ValidationStatus {
let assertion_lower = assertion.to_lowercase();
let context_lower = implementation_context.to_lowercase();
for forbidden in &self.forbidden_keywords {
if assertion_lower.contains(forbidden) {
return ValidationStatus::Invalid {
reason: format!(
"FM-5 violation: oracle uses forbidden keyword '{}'",
forbidden
),
};
}
}
if context_lower.contains("assert") && assertion_lower.contains(&context_lower) {
return ValidationStatus::Invalid {
reason: "Oracle couples to implementation context; must be independent".to_string(),
};
}
match oracle_type {
Rank::Rank1 => self.validate_rank1(&assertion_lower),
Rank::Rank2 => self.validate_rank2(&assertion_lower),
Rank::Rank3 => self.validate_rank3(&assertion_lower),
Rank::Rank4 => self.validate_rank4(&assertion_lower),
}
}
fn validate_rank1(&self, assertion: &str) -> ValidationStatus {
let has_theorem_marker = self.rank1_keywords.iter().any(|kw| assertion.contains(*kw));
if !has_theorem_marker {
return ValidationStatus::Invalid {
reason: "Rank-1 oracle must reference mathematical theorem (Bellman, Western Electric, etc.)".to_string(),
};
}
if assertion.contains("=")
&& !assertion.contains("<=")
&& !assertion.contains(">=")
&& !assertion.contains("!=")
{
return ValidationStatus::Invalid {
reason: "Rank-1 oracle must use comparison operators (<=, >=, !=), not assignment"
.to_string(),
};
}
ValidationStatus::Valid { rank: Rank::Rank1 }
}
fn validate_rank2(&self, assertion: &str) -> ValidationStatus {
let has_contract_marker = self.rank2_keywords.iter().any(|kw| assertion.contains(*kw));
if !has_contract_marker {
return ValidationStatus::Invalid {
reason: "Rank-2 oracle must state domain contract (invariant, rule, policy)"
.to_string(),
};
}
if assertion.contains("code says") || assertion.contains("implementation") {
return ValidationStatus::Invalid {
reason: "Rank-2 oracle must not depend on code behavior; state the contract independently".to_string(),
};
}
ValidationStatus::Valid { rank: Rank::Rank2 }
}
fn validate_rank3(&self, assertion: &str) -> ValidationStatus {
let has_relation_marker = self.rank3_keywords.iter().any(|kw| assertion.contains(*kw));
if !has_relation_marker {
return ValidationStatus::Invalid {
reason: "Rank-3 oracle must describe metamorphic relation (increase/decrease/proportional)".to_string(),
};
}
if !assertion.contains("if") && !assertion.contains("when") {
return ValidationStatus::Invalid {
reason: "Rank-3 oracle must specify input condition (if X then Y)".to_string(),
};
}
ValidationStatus::Valid { rank: Rank::Rank3 }
}
fn validate_rank4(&self, assertion: &str) -> ValidationStatus {
let has_stat_marker = self.rank4_keywords.iter().any(|kw| assertion.contains(*kw));
if !has_stat_marker {
return ValidationStatus::Invalid {
reason: "Rank-4 oracle must reference statistical properties (convergence, trend, confidence)".to_string(),
};
}
if !assertion.contains("trial") && !assertion.contains("seed") {
return ValidationStatus::Invalid {
reason: "Rank-4 oracle must specify number of trials and random seeds (min 5 seeds, 50+ cycles)".to_string(),
};
}
ValidationStatus::Valid { rank: Rank::Rank4 }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validates_rank1_bellman_oracle() {
let validator = OracleValidator::new();
let oracle = "Bellman equation: TD error converges to 0 as cycles increase";
let result = validator.validate(Rank::Rank1, oracle, "");
assert_eq!(result, ValidationStatus::Valid { rank: Rank::Rank1 });
}
#[test]
fn test_validates_rank1_western_electric_oracle() {
let validator = OracleValidator::new();
let oracle = "Western Electric Rule 1: P(|x - μ| > 3σ) ≈ 0.27% proves special cause";
let result = validator.validate(Rank::Rank1, oracle, "");
assert_eq!(result, ValidationStatus::Valid { rank: Rank::Rank1 });
}
#[test]
fn test_rejects_rank1_without_theorem() {
let validator = OracleValidator::new();
let oracle = "The algorithm works because the code says so";
let result = validator.validate(Rank::Rank1, oracle, "");
assert!(!result.is_valid());
}
#[test]
fn test_validates_rank2_domain_contract() {
let validator = OracleValidator::new();
let oracle = "Domain contract: health improvement always yields positive reward";
let result = validator.validate(Rank::Rank2, oracle, "");
assert_eq!(result, ValidationStatus::Valid { rank: Rank::Rank2 });
}
#[test]
fn test_rejects_rank2_code_dependent() {
let validator = OracleValidator::new();
let oracle = "The code says the system improves health correctly";
let result = validator.validate(Rank::Rank2, oracle, "");
assert!(!result.is_valid());
}
#[test]
fn test_validates_rank3_metamorphic() {
let validator = OracleValidator::new();
let oracle = "Metamorphic: If health degrades, reward decreases (inverse relation)";
let result = validator.validate(Rank::Rank3, oracle, "");
assert_eq!(result, ValidationStatus::Valid { rank: Rank::Rank3 });
}
#[test]
fn test_rejects_rank3_without_relation() {
let validator = OracleValidator::new();
let oracle = "The system works correctly";
let result = validator.validate(Rank::Rank3, oracle, "");
assert!(!result.is_valid());
}
#[test]
fn test_validates_rank4_statistical() {
let validator = OracleValidator::new();
let oracle = "After 50+ cycles with 5 independent seeds, convergence trend shows mean TD error decreasing";
let result = validator.validate(Rank::Rank4, oracle, "");
assert_eq!(result, ValidationStatus::Valid { rank: Rank::Rank4 });
}
#[test]
fn test_rejects_rank4_insufficient_rigor() {
let validator = OracleValidator::new();
let oracle = "Convergence happens over time";
let result = validator.validate(Rank::Rank4, oracle, "");
assert!(!result.is_valid());
}
#[test]
fn test_rejects_fm5_self_reference() {
let validator = OracleValidator::new();
let oracle = "computed_same_formula() returns correct result";
let result = validator.validate(Rank::Rank1, oracle, "");
assert!(!result.is_valid());
}
#[test]
fn test_oracle_hierarchy() {
assert!(Rank::Rank1 > Rank::Rank2);
assert!(Rank::Rank2 > Rank::Rank3);
assert!(Rank::Rank3 > Rank::Rank4);
}
}