use crate::error::{Result, VerificationError};
use crate::ProofEnvironment;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProofTier {
Reflex,
Standard { max_fuel: u32 },
Deep,
}
#[derive(Debug, Clone)]
pub struct TierDecision {
pub tier: ProofTier,
pub reason: &'static str,
pub estimated_steps: u32,
}
#[derive(Debug, Clone)]
pub enum ProofKind {
Reflexivity,
DimensionEquality { expected: u32, actual: u32 },
TypeApplication { depth: u32 },
PipelineComposition { stages: u32 },
Custom { estimated_complexity: u32 },
}
#[cfg(feature = "gated-proofs")]
pub fn route_proof(
proof_kind: ProofKind,
_env: &ProofEnvironment,
) -> TierDecision {
match proof_kind {
ProofKind::Reflexivity => TierDecision {
tier: ProofTier::Reflex,
reason: "reflexivity: direct comparison",
estimated_steps: 0,
},
ProofKind::DimensionEquality { .. } => TierDecision {
tier: ProofTier::Reflex,
reason: "dimension equality: literal comparison",
estimated_steps: 1,
},
ProofKind::TypeApplication { depth } if depth <= 2 => TierDecision {
tier: ProofTier::Standard { max_fuel: 100 },
reason: "shallow type application",
estimated_steps: depth * 10,
},
ProofKind::TypeApplication { depth } => TierDecision {
tier: ProofTier::Standard { max_fuel: depth * 100 },
reason: "deep type application",
estimated_steps: depth * 50,
},
ProofKind::PipelineComposition { stages } => {
if stages <= 3 {
TierDecision {
tier: ProofTier::Standard { max_fuel: stages * 200 },
reason: "short pipeline composition",
estimated_steps: stages * 100,
}
} else {
TierDecision {
tier: ProofTier::Deep,
reason: "long pipeline: full kernel needed",
estimated_steps: stages * 500,
}
}
}
ProofKind::Custom { estimated_complexity } => {
if estimated_complexity < 10 {
TierDecision {
tier: ProofTier::Standard { max_fuel: 100 },
reason: "low complexity custom proof",
estimated_steps: estimated_complexity * 10,
}
} else {
TierDecision {
tier: ProofTier::Deep,
reason: "high complexity custom proof",
estimated_steps: estimated_complexity * 100,
}
}
}
}
}
#[cfg(feature = "gated-proofs")]
pub fn verify_tiered(
env: &mut ProofEnvironment,
expected_id: u32,
actual_id: u32,
tier: ProofTier,
) -> Result<u32> {
match tier {
ProofTier::Reflex => {
if expected_id == actual_id {
env.stats.proofs_verified += 1;
return Ok(env.alloc_term());
}
verify_tiered(env, expected_id, actual_id,
ProofTier::Standard { max_fuel: 100 })
}
ProofTier::Standard { max_fuel } => {
if expected_id == actual_id {
env.stats.proofs_verified += 1;
env.stats.total_reductions += max_fuel as u64 / 10;
return Ok(env.alloc_term());
}
if max_fuel >= 10_000 {
return Err(VerificationError::ConversionTimeout {
max_reductions: max_fuel,
});
}
verify_tiered(env, expected_id, actual_id, ProofTier::Deep)
}
ProofTier::Deep => {
env.stats.total_reductions += 10_000;
if expected_id == actual_id {
env.stats.proofs_verified += 1;
Ok(env.alloc_term())
} else {
Err(VerificationError::TypeCheckFailed(format!(
"type mismatch after full verification: {} != {}",
expected_id, actual_id,
)))
}
}
}
}
#[cfg(test)]
#[cfg(feature = "gated-proofs")]
mod tests {
use super::*;
#[test]
fn test_route_reflexivity() {
let env = ProofEnvironment::new();
let decision = route_proof(ProofKind::Reflexivity, &env);
assert_eq!(decision.tier, ProofTier::Reflex);
assert_eq!(decision.estimated_steps, 0);
}
#[test]
fn test_route_dimension_equality() {
let env = ProofEnvironment::new();
let decision = route_proof(
ProofKind::DimensionEquality { expected: 128, actual: 128 },
&env,
);
assert_eq!(decision.tier, ProofTier::Reflex);
}
#[test]
fn test_route_shallow_application() {
let env = ProofEnvironment::new();
let decision = route_proof(
ProofKind::TypeApplication { depth: 1 },
&env,
);
assert!(matches!(decision.tier, ProofTier::Standard { .. }));
}
#[test]
fn test_route_long_pipeline() {
let env = ProofEnvironment::new();
let decision = route_proof(
ProofKind::PipelineComposition { stages: 10 },
&env,
);
assert_eq!(decision.tier, ProofTier::Deep);
}
#[test]
fn test_verify_tiered_reflex() {
let mut env = ProofEnvironment::new();
let result = verify_tiered(&mut env, 5, 5, ProofTier::Reflex);
assert!(result.is_ok());
}
#[test]
fn test_verify_tiered_escalation() {
let mut env = ProofEnvironment::new();
let result = verify_tiered(&mut env, 1, 2, ProofTier::Reflex);
assert!(result.is_err()); }
#[test]
fn test_verify_tiered_standard() {
let mut env = ProofEnvironment::new();
let result = verify_tiered(&mut env, 3, 3, ProofTier::Standard { max_fuel: 100 });
assert!(result.is_ok());
}
}