1use std::fmt;
4
5use crate::{Bar, CriticalPair, Diagram, Error};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct CertificateError {
10 message: String,
11}
12
13impl CertificateError {
14 pub(crate) fn new(message: impl Into<String>) -> Self {
15 Self {
16 message: message.into(),
17 }
18 }
19
20 pub fn message(&self) -> &str {
22 &self.message
23 }
24}
25
26impl fmt::Display for CertificateError {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 write!(f, "reduction certificate: {}", self.message)
29 }
30}
31
32impl std::error::Error for CertificateError {}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36#[non_exhaustive]
37pub struct CertificateLimits {
38 pub max_bytes: usize,
40 pub max_vertices: usize,
42 pub max_edges: usize,
44 pub max_triangles: usize,
46 pub max_higher_simplices: usize,
48 pub max_dimension: usize,
50 pub max_terms: usize,
52 pub max_bars: usize,
54}
55
56impl Default for CertificateLimits {
57 fn default() -> Self {
58 Self {
59 max_bytes: 1 << 30,
60 max_vertices: 1_000_000,
61 max_edges: 20_000_000,
62 max_triangles: 100_000_000,
63 max_higher_simplices: 100_000_000,
64 max_dimension: 8,
65 max_terms: 200_000_000,
66 max_bars: 100_000_000,
67 }
68 }
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
73pub struct CertificateTerm {
74 pub index: usize,
76 pub coefficient: u32,
78}
79
80#[derive(Debug, Clone, PartialEq, Eq)]
82pub struct ChangeColumn {
83 pub terms: Vec<CertificateTerm>,
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub enum ReductionRepairMode {
90 Reused,
92 SuffixRepaired,
94 Rebuilt,
96}
97
98#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
100pub struct ReductionRepairWork {
101 pub edge_columns_reused: usize,
103 pub edge_columns_reduced: usize,
105 pub triangle_columns_reused: usize,
107 pub triangle_columns_reduced: usize,
109 pub column_additions: usize,
111}
112
113impl ReductionRepairWork {
114 pub fn columns(&self) -> usize {
116 self.edge_columns_reused
117 + self.edge_columns_reduced
118 + self.triangle_columns_reused
119 + self.triangle_columns_reduced
120 }
121
122 pub fn columns_reused(&self) -> usize {
124 self.edge_columns_reused + self.triangle_columns_reused
125 }
126
127 pub fn columns_reduced(&self) -> usize {
129 self.edge_columns_reduced + self.triangle_columns_reduced
130 }
131}
132
133#[derive(Debug, Clone)]
135pub struct ReductionRepair {
136 pub(super) certificate: ReductionCertificate,
137 pub(super) mode: ReductionRepairMode,
138 pub(super) work: ReductionRepairWork,
139}
140
141impl ReductionRepair {
142 pub fn certificate(&self) -> &ReductionCertificate {
144 &self.certificate
145 }
146
147 pub fn mode(&self) -> ReductionRepairMode {
149 self.mode
150 }
151
152 pub fn work(&self) -> ReductionRepairWork {
154 self.work
155 }
156
157 pub(crate) fn into_certificate(self) -> ReductionCertificate {
158 self.certificate
159 }
160}
161
162#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
164pub struct FiltrationSimplex {
165 pub(super) vertices: Vec<usize>,
166}
167
168impl FiltrationSimplex {
169 pub(super) fn new(vertices: impl Into<Vec<usize>>) -> Self {
170 Self {
171 vertices: vertices.into(),
172 }
173 }
174
175 pub fn dimension(&self) -> usize {
177 self.vertices.len().saturating_sub(1)
178 }
179
180 pub fn vertices(&self) -> &[usize] {
182 &self.vertices
183 }
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
188#[non_exhaustive]
189pub enum ReductionGuardKind {
190 ChangeOfBasis,
192 Pivot,
194}
195
196#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
198pub struct ReductionGuard {
199 pub(super) kind: ReductionGuardKind,
200 pub(super) earlier: FiltrationSimplex,
201 pub(super) later: FiltrationSimplex,
202}
203
204impl ReductionGuard {
205 pub fn kind(&self) -> ReductionGuardKind {
207 self.kind
208 }
209
210 pub fn earlier(&self) -> &FiltrationSimplex {
212 &self.earlier
213 }
214
215 pub fn later(&self) -> &FiltrationSimplex {
217 &self.later
218 }
219}
220
221#[derive(Debug, Clone, Copy, PartialEq, Eq)]
223#[non_exhaustive]
224pub enum RegionViolationKind {
225 VertexSetChanged,
227 EdgeSetChanged,
229 ThresholdCrossing,
231 GuardFailed,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq)]
237pub struct RegionViolation {
238 pub(super) kind: RegionViolationKind,
239 pub(super) guard_index: Option<usize>,
240 pub(super) first: Option<FiltrationSimplex>,
241 pub(super) second: Option<FiltrationSimplex>,
242}
243
244impl RegionViolation {
245 pub fn kind(&self) -> RegionViolationKind {
247 self.kind
248 }
249
250 pub fn guard_index(&self) -> Option<usize> {
252 self.guard_index
253 }
254
255 pub fn first(&self) -> Option<&FiltrationSimplex> {
257 self.first.as_ref()
258 }
259
260 pub fn second(&self) -> Option<&FiltrationSimplex> {
262 self.second.as_ref()
263 }
264}
265
266#[derive(Debug, Clone)]
268pub struct CertifiedRegionEvaluation {
269 pub(super) diagram: Diagram,
270 pub(super) h1_pairs: Vec<(Bar, CriticalPair)>,
271 pub(super) guards_checked: usize,
272}
273
274impl CertifiedRegionEvaluation {
275 pub fn diagram(&self) -> &Diagram {
277 &self.diagram
278 }
279
280 pub fn h1_critical_pairs(&self) -> &[(Bar, CriticalPair)] {
282 &self.h1_pairs
283 }
284
285 pub fn guards_checked(&self) -> usize {
287 self.guards_checked
288 }
289}
290#[derive(Debug, Clone)]
291pub(super) struct RegionH1Pair {
292 pub(super) birth: [usize; 2],
293 pub(super) death: Option<[usize; 3]>,
294}
295
296#[derive(Debug, Clone, Copy)]
297pub(super) enum RegionValueFormula {
298 Vertex,
299 Edge(usize),
300 Triangle([usize; 3]),
301}
302
303impl RegionValueFormula {
304 pub(super) fn value(self, edge_value: impl Fn(usize) -> f64) -> f64 {
305 match self {
306 Self::Vertex => 0.0,
307 Self::Edge(edge) => edge_value(edge),
308 Self::Triangle([first, second, third]) => edge_value(first)
309 .max(edge_value(second))
310 .max(edge_value(third)),
311 }
312 }
313}
314
315#[derive(Debug, Clone)]
321pub struct CertifiedReductionRegion {
322 pub(super) vertex_count: usize,
323 pub(super) threshold: Option<f64>,
324 pub(super) topology: Vec<[usize; 2]>,
325 pub(super) active: Vec<bool>,
326 pub(super) complete_guards: Vec<ReductionGuard>,
327 pub(super) guards: Vec<ReductionGuard>,
328 pub(super) guard_indices: Vec<(usize, usize)>,
329 pub(super) guard_ranks: Vec<u128>,
330 pub(super) guard_formulas: Vec<RegionValueFormula>,
331 pub(super) h0_deaths: Vec<[usize; 2]>,
332 pub(super) h0_essential: usize,
333 pub(super) h1_pairs: Vec<RegionH1Pair>,
334 pub(super) h1_formulas: Vec<(usize, Option<[usize; 3]>)>,
335}
336
337#[derive(Debug, Clone)]
339pub struct ReductionCertificate {
340 pub(super) vertex_count: usize,
341 pub(super) threshold: Option<f64>,
342 pub(super) modulus: u32,
343 pub(super) graph_digest: [u8; 32],
344 pub(super) edge_columns: Vec<ChangeColumn>,
345 pub(super) triangle_columns: Vec<ChangeColumn>,
346 pub(super) diagram: Diagram,
347}
348
349pub(super) type CertificateResult<T> = std::result::Result<T, CertificateError>;
350impl From<CertificateError> for Error {
351 fn from(error: CertificateError) -> Self {
352 Self::InvalidInput(error.to_string())
353 }
354}