holos_tda/relative_interface/
verify.rs1use std::collections::BTreeSet;
2
3use crate::Diagram;
4use crate::certificate::{CertificateError, CertificateLimits};
5
6use super::cancellation::replay_cancellations;
7use super::chain::check_chain_complex;
8use super::digest::{certificate_digest, diagrams_equal};
9use super::model::RelativeInterfaceCertificate;
10use super::reduction::check_reduction;
11use super::validation::{check_interface_parameters, check_protected_cells, enforce_cell_limits};
12
13impl RelativeInterfaceCertificate {
14 pub fn verify(&self, limits: CertificateLimits) -> Result<Diagram, CertificateError> {
16 check_interface_parameters(self.max_dim, self.modulus, limits)?;
17 enforce_cell_limits(&self.input_cells, limits)?;
18 enforce_cell_limits(&self.core_cells, limits)?;
19 check_chain_complex(&self.input_cells, self.max_dim, self.modulus, limits)?;
20 let protected: BTreeSet<_> = self.protected_vertices.iter().copied().collect();
21 check_cancellation_replay(self, &protected)?;
22 check_protected_cells(&self.input_cells, &self.core_cells, &protected)?;
23 let (diagram, _) = check_reduction(&self.core_cells, self.modulus, &self.columns, limits)?;
24 check_interface_result(self, &diagram)?;
25 Ok(diagram)
26 }
27}
28
29fn check_cancellation_replay(
30 certificate: &RelativeInterfaceCertificate,
31 protected: &BTreeSet<usize>,
32) -> Result<(), CertificateError> {
33 let replayed = replay_cancellations(
34 certificate.input_cells.clone(),
35 &certificate.cancellations,
36 protected,
37 certificate.modulus,
38 )?;
39 if replayed != certificate.core_cells {
40 return Err(CertificateError::new(
41 "relative cancellation trace does not produce the declared core",
42 ));
43 }
44 Ok(())
45}
46
47fn check_interface_result(
48 certificate: &RelativeInterfaceCertificate,
49 diagram: &Diagram,
50) -> Result<(), CertificateError> {
51 if !diagrams_equal(diagram, &certificate.diagram) {
52 return Err(CertificateError::new(
53 "relative interface diagram differs from its checked reduction",
54 ));
55 }
56 let digest = certificate_digest(
57 certificate.max_dim,
58 certificate.modulus,
59 &certificate.protected_vertices,
60 &certificate.core_cells,
61 &certificate.columns,
62 &certificate.diagram,
63 );
64 if digest != certificate.digest {
65 return Err(CertificateError::new(
66 "relative interface digest differs from its checked content",
67 ));
68 }
69 Ok(())
70}