use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ProofCertificate {
pub theorem_id: u32,
pub proof_system_id: u32,
pub verified_at: u32,
pub assumption_count: u32,
}
impl ProofCertificate {
pub const fn new(
theorem_id: u32,
proof_system_id: u32,
verified_at: u32,
assumption_count: u32,
) -> Self {
Self {
theorem_id,
proof_system_id,
verified_at,
assumption_count,
}
}
pub fn proof_system_name(&self) -> &'static str {
match self.proof_system_id {
1 => "Coq 8.18",
2 => "TLAPS",
3 => "Ivy",
4 => "Alloy",
_ => "Unknown",
}
}
pub fn verification_year(&self) -> u32 {
self.verified_at / 10000
}
pub fn is_complete(&self) -> bool {
self.assumption_count == 0
}
}
impl fmt::Display for ProofCertificate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"ProofCertificate {{ theorem_id: {}, proof_system: {}, verified: {}, assumptions: {} }}",
self.theorem_id,
self.proof_system_name(),
self.verified_at,
self.assumption_count
)
}
}
pub trait Verified {
fn proof_certificate() -> ProofCertificate;
fn theorem_name() -> &'static str;
fn theorem_description() -> &'static str;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_proof_certificate_display() {
let cert = ProofCertificate::new(100, 1, 20_260_205, 1);
let display = format!("{cert}");
assert!(display.contains("theorem_id: 100"));
assert!(display.contains("Coq 8.18"));
assert!(display.contains("20260205"));
assert!(display.contains("assumptions: 1"));
}
#[test]
fn test_proof_system_name() {
let cert = ProofCertificate::new(100, 1, 20_260_205, 0);
assert_eq!(cert.proof_system_name(), "Coq 8.18");
}
#[test]
fn test_verification_year() {
let cert = ProofCertificate::new(100, 1, 20_260_205, 0);
assert_eq!(cert.verification_year(), 2026);
}
#[test]
fn test_is_complete() {
let complete = ProofCertificate::new(100, 1, 20_260_205, 0);
assert!(complete.is_complete());
let partial = ProofCertificate::new(100, 1, 20_260_205, 2);
assert!(!partial.is_complete());
}
}