use serde::{Deserialize, Serialize};
use crate::prelude::StandardLibrary;
use crate::{infer_type, is_subtype, Context, KernelError, Term};
pub const PRELUDE_VERSION: &str = "logos-coc-1";
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Certificate {
pub proof_term: Term,
pub claimed_type: Term,
pub prelude_version: String,
}
impl Certificate {
pub fn new(proof_term: Term, claimed_type: Term) -> Self {
Self {
proof_term,
claimed_type,
prelude_version: PRELUDE_VERSION.to_string(),
}
}
}
pub fn recheck(cert: &Certificate) -> Result<(), KernelError> {
if cert.prelude_version != PRELUDE_VERSION {
return Err(KernelError::CertificationError(format!(
"certificate was minted against prelude '{}', but this checker is '{}'",
cert.prelude_version, PRELUDE_VERSION
)));
}
let mut ctx = Context::new();
StandardLibrary::register(&mut ctx);
let inferred = infer_type(&ctx, &cert.proof_term)?;
if is_subtype(&ctx, &inferred, &cert.claimed_type) {
Ok(())
} else {
Err(KernelError::CertificationError(format!(
"certificate term proves a different proposition: has type {:?}, claims {:?}",
inferred, cert.claimed_type
)))
}
}