Skip to main content

erdos_unit_distance/
error.rs

1use std::fmt;
2
3/// Errors that can occur during point set generation.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum GenerationError {
6    /// A field generator is unsupported or violates the squarefree generator contract.
7    InvalidGenerator {
8        generator: i64,
9        reason: &'static str,
10    },
11    /// The same generator was provided more than once.
12    DuplicateGenerator { generator: i64 },
13    /// The split prime is not an odd prime.
14    InvalidSplitPrime { split_prime: i64 },
15    /// The requested prime is not split completely in the configured field.
16    PrimeNotSplit { split_prime: i64, generator: i64 },
17    /// The coefficient vector length does not match the field degree.
18    InvalidFieldElementDimension { expected: usize, actual: usize },
19    /// A generation/search parameter is outside its supported range.
20    InvalidSearchParameter {
21        parameter: &'static str,
22        reason: &'static str,
23    },
24    /// No suitable prime element theta found for the given field and prime.
25    PrimeElementNotFound { prime: i64, max_exponent: usize },
26    /// The field has no imaginary generator (-1), but the construction requires one.
27    MissingImaginaryGenerator,
28    /// Could not generate enough points within the radius expansion budget.
29    InsufficientPoints { requested: usize, found: usize },
30}
31
32impl fmt::Display for GenerationError {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        match self {
35            GenerationError::InvalidGenerator { generator, reason } => {
36                write!(f, "invalid generator {generator}: {reason}")
37            }
38            GenerationError::DuplicateGenerator { generator } => {
39                write!(f, "duplicate generator {generator}")
40            }
41            GenerationError::InvalidSplitPrime { split_prime } => {
42                write!(f, "split prime {split_prime} is not an odd prime")
43            }
44            GenerationError::PrimeNotSplit {
45                split_prime,
46                generator,
47            } => write!(
48                f,
49                "prime {split_prime} is not split by generator {generator}"
50            ),
51            GenerationError::InvalidFieldElementDimension { expected, actual } => write!(
52                f,
53                "field element has {actual} coefficients, but field degree is {expected}"
54            ),
55            GenerationError::InvalidSearchParameter { parameter, reason } => {
56                write!(f, "invalid search parameter {parameter}: {reason}")
57            }
58            GenerationError::PrimeElementNotFound {
59                prime,
60                max_exponent,
61            } => write!(
62                f,
63                "could not find a suitable prime element theta for p = {prime} up to exponent {max_exponent}"
64            ),
65            GenerationError::MissingImaginaryGenerator => write!(
66                f,
67                "field is missing the imaginary generator -1 required by the construction"
68            ),
69            GenerationError::InsufficientPoints { requested, found } => write!(
70                f,
71                "could not generate enough points: requested {requested}, found {found}"
72            ),
73        }
74    }
75}
76
77impl std::error::Error for GenerationError {}
78
79/// Errors that can occur while verifying a construction certificate.
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub enum VerificationError {
82    /// The certificate stores a different number of points than the construction claims.
83    PointCountMismatch { expected: usize, actual: usize },
84    /// A claimed unit-distance edge refers to a point index outside the point set.
85    EdgeIndexOutOfBounds {
86        edge: (usize, usize),
87        point_count: usize,
88    },
89    /// A claimed unit-distance edge connects a point to itself.
90    SelfEdge { index: usize },
91    /// The claimed edge set does not match the independently recomputed edge set.
92    EdgeSetMismatch {
93        expected: Vec<(usize, usize)>,
94        actual: Vec<(usize, usize)>,
95    },
96    /// A stored point does not match the deterministic construction.
97    PointMismatch { index: usize },
98    /// A stored projection key does not match the point it claims to certify.
99    QuantizedProjectionMismatch {
100        index: usize,
101        expected: [i64; 2],
102        actual: [i64; 2],
103    },
104    /// An algebraic certificate key has the wrong field dimension.
105    AlgebraicKeyDimensionMismatch { expected: usize, actual: usize },
106    /// An algebraic certificate key has a non-positive denominator.
107    InvalidAlgebraicKeyDenominator { denominator: i64 },
108    /// A claimed norm-one translation does not verify in the supported native model.
109    TranslationNotNormOne { index: usize },
110    /// A certified candidate is outside the claimed polydisk window.
111    CandidateOutsideWindow {
112        index: usize,
113        radius: String,
114        max_embedding_norm: String,
115    },
116    /// A stored projection point does not match the certified algebraic candidate.
117    ProjectionMismatch { index: usize },
118    /// A certified candidate path does not replay to the stored algebraic key.
119    CandidatePathMismatch { index: usize },
120    /// A candidate path references a missing translation.
121    CandidatePathTranslationOutOfBounds {
122        candidate_index: usize,
123        translation_index: usize,
124        translation_count: usize,
125    },
126    /// A certified construction edge is not explained by a norm-one translation.
127    EdgeProvenanceMismatch { edge_index: usize },
128    /// The certificate contains invalid construction metadata.
129    InvalidConstruction { reason: String },
130    /// The serialized certificate does not match the supported schema.
131    CertificateSchemaMismatch { reason: String },
132}
133
134impl fmt::Display for VerificationError {
135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136        match self {
137            VerificationError::PointCountMismatch { expected, actual } => write!(
138                f,
139                "certificate has {actual} points, but expected {expected}"
140            ),
141            VerificationError::EdgeIndexOutOfBounds { edge, point_count } => write!(
142                f,
143                "certificate edge ({}, {}) is outside point count {point_count}",
144                edge.0, edge.1
145            ),
146            VerificationError::SelfEdge { index } => {
147                write!(f, "certificate contains self-edge at point {index}")
148            }
149            VerificationError::EdgeSetMismatch { expected, actual } => write!(
150                f,
151                "certificate edge set mismatch: expected {} edges, got {}",
152                expected.len(),
153                actual.len()
154            ),
155            VerificationError::PointMismatch { index } => {
156                write!(f, "certificate point {index} does not match construction")
157            }
158            VerificationError::QuantizedProjectionMismatch {
159                index,
160                expected,
161                actual,
162            } => write!(
163                f,
164                "projection key {index} mismatch: expected {:?}, got {:?}",
165                expected, actual
166            ),
167            VerificationError::AlgebraicKeyDimensionMismatch { expected, actual } => write!(
168                f,
169                "algebraic key has {actual} coefficients, but field degree is {expected}"
170            ),
171            VerificationError::InvalidAlgebraicKeyDenominator { denominator } => write!(
172                f,
173                "algebraic key denominator must be positive, got {denominator}"
174            ),
175            VerificationError::TranslationNotNormOne { index } => {
176                write!(f, "translation {index} is not certified as norm-one")
177            }
178            VerificationError::CandidateOutsideWindow {
179                index,
180                radius,
181                max_embedding_norm,
182            } => write!(
183                f,
184                "candidate {index} is outside polydisk radius {radius}; max embedding norm is {max_embedding_norm}"
185            ),
186            VerificationError::ProjectionMismatch { index } => {
187                write!(f, "projection {index} does not match algebraic candidate")
188            }
189            VerificationError::CandidatePathMismatch { index } => {
190                write!(f, "candidate path {index} does not replay to stored key")
191            }
192            VerificationError::CandidatePathTranslationOutOfBounds {
193                candidate_index,
194                translation_index,
195                translation_count,
196            } => write!(
197                f,
198                "candidate {candidate_index} path references translation {translation_index}, but only {translation_count} translations exist"
199            ),
200            VerificationError::EdgeProvenanceMismatch { edge_index } => {
201                write!(
202                    f,
203                    "construction edge {edge_index} is not explained by its translation provenance"
204                )
205            }
206            VerificationError::InvalidConstruction { reason } => {
207                write!(f, "invalid certificate construction: {reason}")
208            }
209            VerificationError::CertificateSchemaMismatch { reason } => {
210                write!(f, "certificate schema mismatch: {reason}")
211            }
212        }
213    }
214}
215
216impl std::error::Error for VerificationError {}