Skip to main content

oxilean_kernel/proof_cert/
types.rs

1//! Types for the Proof Certificate System.
2//!
3//! A proof certificate is a compact, checkable record that a term has been verified.
4//! Certificates enable exporting/importing proofs without re-checking from scratch.
5
6use std::collections::HashMap;
7
8/// Unique identifier for a proof certificate.
9#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
10pub struct ProofCertId(pub u64);
11
12impl ProofCertId {
13    /// Create a new certificate ID from a raw value.
14    pub fn new(id: u64) -> Self {
15        ProofCertId(id)
16    }
17
18    /// Get the raw numeric value.
19    pub fn raw(self) -> u64 {
20        self.0
21    }
22}
23
24impl std::fmt::Display for ProofCertId {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        write!(f, "cert#{}", self.0)
27    }
28}
29
30/// A single step in a proof reduction sequence.
31///
32/// These steps record the high-level reduction moves taken during kernel
33/// type-checking, enabling efficient replay or auditing.
34#[derive(Clone, Debug, PartialEq, Eq)]
35pub enum ProofStep {
36    /// β-reduction: substitute the argument into the body.
37    ///
38    /// `redex_depth` records the nesting depth at which this reduction occurred.
39    Beta {
40        /// De Bruijn depth of the beta-redex site.
41        redex_depth: u32,
42    },
43    /// δ-reduction: unfold a named definition.
44    Delta {
45        /// Name of the definition that was unfolded.
46        name: String,
47    },
48    /// ζ-reduction: substitute a let-binding.
49    Zeta,
50    /// ι-reduction: reduce a recursor application to a branch.
51    Iota {
52        /// Name of the recursor that fired.
53        recursor: String,
54        /// Index of the constructor branch selected.
55        ctor_idx: u32,
56    },
57    /// η-reduction: contract `λ x, f x` to `f`.
58    Eta,
59    /// Universe-level substitution.
60    SubstLevel {
61        /// Parameter names substituted.
62        params: Vec<String>,
63    },
64    /// Appeal to a local assumption (hypothesis) in the context.
65    Assumption,
66}
67
68impl std::fmt::Display for ProofStep {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        match self {
71            ProofStep::Beta { redex_depth } => write!(f, "Beta(depth={})", redex_depth),
72            ProofStep::Delta { name } => write!(f, "Delta({})", name),
73            ProofStep::Zeta => write!(f, "Zeta"),
74            ProofStep::Iota { recursor, ctor_idx } => {
75                write!(f, "Iota({}, ctor={})", recursor, ctor_idx)
76            }
77            ProofStep::Eta => write!(f, "Eta"),
78            ProofStep::SubstLevel { params } => write!(f, "SubstLevel({:?})", params),
79            ProofStep::Assumption => write!(f, "Assumption"),
80        }
81    }
82}
83
84/// A compact verification record for a single declaration.
85///
86/// Certificates record the structural hashes of the type and proof term, together
87/// with the sequence of reduction steps performed during kernel type-checking.
88/// They can be stored externally and replayed cheaply via hash verification.
89#[derive(Clone, Debug, PartialEq, Eq)]
90pub struct ProofCertificate {
91    /// Unique certificate identifier (derived from content at creation time).
92    pub id: ProofCertId,
93    /// Name of the declaration this certificate vouches for.
94    pub decl_name: String,
95    /// FNV-1a structural hash of the declaration's type expression.
96    pub type_hash: u64,
97    /// FNV-1a structural hash of the proof term expression.
98    pub proof_hash: u64,
99    /// Ordered sequence of reduction steps taken during type-checking.
100    pub reduction_steps: Vec<ProofStep>,
101    /// Unix timestamp (seconds) at which the certificate was created.
102    pub verified_at: u64,
103}
104
105impl ProofCertificate {
106    /// Return the number of reduction steps recorded.
107    pub fn step_count(&self) -> usize {
108        self.reduction_steps.len()
109    }
110
111    /// Return true if this certificate records no reduction steps.
112    pub fn is_trivial(&self) -> bool {
113        self.reduction_steps.is_empty()
114    }
115}
116
117impl std::fmt::Display for ProofCertificate {
118    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119        write!(
120            f,
121            "ProofCert {{ id: {}, decl: {}, type_hash: {:016x}, proof_hash: {:016x}, steps: {} }}",
122            self.id,
123            self.decl_name,
124            self.type_hash,
125            self.proof_hash,
126            self.reduction_steps.len()
127        )
128    }
129}
130
131/// Persistent store of proof certificates, keyed by declaration name.
132#[derive(Clone, Debug, Default)]
133pub struct CertificateStore {
134    /// Map from declaration name to its certificate.
135    pub certs: HashMap<String, ProofCertificate>,
136}
137
138impl CertificateStore {
139    /// Create an empty certificate store.
140    pub fn new() -> Self {
141        CertificateStore {
142            certs: HashMap::new(),
143        }
144    }
145
146    /// Return the number of certificates in the store.
147    pub fn len(&self) -> usize {
148        self.certs.len()
149    }
150
151    /// Return true if the store is empty.
152    pub fn is_empty(&self) -> bool {
153        self.certs.is_empty()
154    }
155
156    /// Iterate over all (name, certificate) pairs.
157    pub fn iter(&self) -> impl Iterator<Item = (&String, &ProofCertificate)> {
158        self.certs.iter()
159    }
160}
161
162/// The result of checking a proof certificate against a live environment.
163#[derive(Clone, Debug, PartialEq, Eq)]
164pub enum CertCheckResult {
165    /// The certificate is consistent with the environment.
166    Valid,
167    /// The stored hash does not match the recomputed hash.
168    HashMismatch {
169        /// The hash stored in the certificate.
170        expected: u64,
171        /// The hash recomputed from the environment.
172        actual: u64,
173    },
174    /// The declaration named in the certificate is absent from the environment.
175    MissingDecl(String),
176    /// The reduction steps are internally inconsistent or ill-formed.
177    InvalidSteps,
178}
179
180impl std::fmt::Display for CertCheckResult {
181    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182        match self {
183            CertCheckResult::Valid => write!(f, "Valid"),
184            CertCheckResult::HashMismatch { expected, actual } => {
185                write!(
186                    f,
187                    "HashMismatch {{ expected: {:016x}, actual: {:016x} }}",
188                    expected, actual
189                )
190            }
191            CertCheckResult::MissingDecl(name) => write!(f, "MissingDecl({})", name),
192            CertCheckResult::InvalidSteps => write!(f, "InvalidSteps"),
193        }
194    }
195}