Skip to main content

uor_foundation/
enforcement.rs

1// @generated by uor-crate from uor-ontology — do not edit manually
2
3//! Declarative enforcement types.
4//!
5//! This module contains the opaque witness types, declarative builders,
6//! the Term AST, and the v0.2.1 ergonomics surface (sealed `Grounded<T>`,
7//! the `Certify` trait, `PipelineFailure`, ring-op phantom wrappers,
8//! fragment markers, dispatch tables, and the `prelude` module).
9//!
10//! # Layers
11//!
12//! - **Layer 1** \[Opaque Witnesses\]: `Datum`, `Validated<T>`, `Derivation`,
13//!   `FreeRank` \[private fields, no public constructors\]
14//! - **Layer 2** \[Declarative Builders\]: `CompileUnitBuilder`,
15//!   `EffectDeclarationBuilder`, etc. \[produce `Validated<T>` on success\]
16//! - **Term AST**: `Term`, `TermArena`, `Binding`, `Assertion`, etc.
17//! - **v0.2.1 Ergonomics**: `OntologyTarget`, `GroundedShape`, `Grounded<T>`,
18//!   `Certify`, `PipelineFailure`, `RingOp<L>`, fragment markers,
19//!   `INHABITANCE_DISPATCH_TABLE`, and the `prelude` module.
20
21use crate::{
22    DecimalTranscendental, HostTypes, MetricAxis, PrimitiveOp, VerificationDomain, ViolationKind,
23    WittLevel,
24};
25use core::marker::PhantomData;
26
27/// Private sealed module preventing downstream implementations.
28/// Only `GroundedCoord` and `GroundedTuple<N>` implement `Sealed`.
29mod sealed {
30    /// Sealed trait. Not publicly implementable because this module is private.
31    pub trait Sealed {}
32    impl Sealed for super::GroundedCoord {}
33    impl<const N: usize> Sealed for super::GroundedTuple<N> {}
34}
35
36/// Internal level-tagged ring value. Width determined by the Witt level.
37/// Variants are emitted parametrically from `schema:WittLevel` individuals
38/// in the ontology; adding a new level to the ontology regenerates this enum.
39/// Not publicly constructible \[sealed within the crate\].
40#[derive(Debug, Clone, PartialEq, Eq)]
41#[allow(clippy::large_enum_variant, dead_code)]
42pub(crate) enum DatumInner {
43    /// W8: 8-bit ring Z/(2^8)Z.
44    W8([u8; 1]),
45    /// W16: 16-bit ring Z/(2^16)Z.
46    W16([u8; 2]),
47    /// W24: 24-bit ring Z/(2^24)Z.
48    W24([u8; 3]),
49    /// W32: 32-bit ring Z/(2^32)Z.
50    W32([u8; 4]),
51    /// W40: 40-bit ring Z/(2^40)Z.
52    W40([u8; 5]),
53    /// W48: 48-bit ring Z/(2^48)Z.
54    W48([u8; 6]),
55    /// W56: 56-bit ring Z/(2^56)Z.
56    W56([u8; 7]),
57    /// W64: 64-bit ring Z/(2^64)Z.
58    W64([u8; 8]),
59    /// W72: 72-bit ring Z/(2^72)Z.
60    W72([u8; 9]),
61    /// W80: 80-bit ring Z/(2^80)Z.
62    W80([u8; 10]),
63    /// W88: 88-bit ring Z/(2^88)Z.
64    W88([u8; 11]),
65    /// W96: 96-bit ring Z/(2^96)Z.
66    W96([u8; 12]),
67    /// W104: 104-bit ring Z/(2^104)Z.
68    W104([u8; 13]),
69    /// W112: 112-bit ring Z/(2^112)Z.
70    W112([u8; 14]),
71    /// W120: 120-bit ring Z/(2^120)Z.
72    W120([u8; 15]),
73    /// W128: 128-bit ring Z/(2^128)Z.
74    W128([u8; 16]),
75}
76
77/// A ring element at its minting Witt level.
78/// Cannot be constructed outside the `uor_foundation` crate.
79/// The only way to obtain a `Datum` is through reduction evaluation
80/// or the two-phase minting boundary (`validate_and_mint_coord` /
81/// `validate_and_mint_tuple`).
82/// # Examples
83/// ```no_run
84/// // A Datum is produced by reduction evaluation or the minting boundary —
85/// // you never construct one directly.
86/// fn inspect_datum(d: &uor_foundation::enforcement::Datum) {
87///     // Query its Witt level (W8 = 8-bit, W32 = 32-bit, etc.)
88///     let _level = d.level();
89///     // Datum width is determined by its level:
90///     //   W8 → 1 byte,  W16 → 2 bytes,  W24 → 3 bytes,  W32 → 4 bytes.
91///     let _bytes = d.as_bytes();
92/// }
93/// ```
94#[derive(Debug, Clone, PartialEq, Eq)]
95pub struct Datum {
96    /// Level-tagged ring value \[sealed\].
97    inner: DatumInner,
98}
99
100impl Datum {
101    /// Returns the Witt level at which this datum was minted.
102    #[inline]
103    #[must_use]
104    pub const fn level(&self) -> WittLevel {
105        match self.inner {
106            DatumInner::W8(_) => WittLevel::W8,
107            DatumInner::W16(_) => WittLevel::W16,
108            DatumInner::W24(_) => WittLevel::new(24),
109            DatumInner::W32(_) => WittLevel::new(32),
110            DatumInner::W40(_) => WittLevel::new(40),
111            DatumInner::W48(_) => WittLevel::new(48),
112            DatumInner::W56(_) => WittLevel::new(56),
113            DatumInner::W64(_) => WittLevel::new(64),
114            DatumInner::W72(_) => WittLevel::new(72),
115            DatumInner::W80(_) => WittLevel::new(80),
116            DatumInner::W88(_) => WittLevel::new(88),
117            DatumInner::W96(_) => WittLevel::new(96),
118            DatumInner::W104(_) => WittLevel::new(104),
119            DatumInner::W112(_) => WittLevel::new(112),
120            DatumInner::W120(_) => WittLevel::new(120),
121            DatumInner::W128(_) => WittLevel::new(128),
122        }
123    }
124
125    /// Returns the raw byte representation of this datum.
126    #[inline]
127    #[must_use]
128    pub fn as_bytes(&self) -> &[u8] {
129        match &self.inner {
130            DatumInner::W8(b) => b,
131            DatumInner::W16(b) => b,
132            DatumInner::W24(b) => b,
133            DatumInner::W32(b) => b,
134            DatumInner::W40(b) => b,
135            DatumInner::W48(b) => b,
136            DatumInner::W56(b) => b,
137            DatumInner::W64(b) => b,
138            DatumInner::W72(b) => b,
139            DatumInner::W80(b) => b,
140            DatumInner::W88(b) => b,
141            DatumInner::W96(b) => b,
142            DatumInner::W104(b) => b,
143            DatumInner::W112(b) => b,
144            DatumInner::W120(b) => b,
145            DatumInner::W128(b) => b,
146        }
147    }
148}
149
150/// Internal level-tagged coordinate value for grounding intermediates.
151/// Variant set mirrors `DatumInner`: one per `schema:WittLevel`.
152#[derive(Debug, Clone, PartialEq, Eq)]
153#[allow(clippy::large_enum_variant, dead_code)]
154pub(crate) enum GroundedCoordInner {
155    /// W8: 8-bit coordinate.
156    W8([u8; 1]),
157    /// W16: 16-bit coordinate.
158    W16([u8; 2]),
159    /// W24: 24-bit coordinate.
160    W24([u8; 3]),
161    /// W32: 32-bit coordinate.
162    W32([u8; 4]),
163    /// W40: 40-bit coordinate.
164    W40([u8; 5]),
165    /// W48: 48-bit coordinate.
166    W48([u8; 6]),
167    /// W56: 56-bit coordinate.
168    W56([u8; 7]),
169    /// W64: 64-bit coordinate.
170    W64([u8; 8]),
171    /// W72: 72-bit coordinate.
172    W72([u8; 9]),
173    /// W80: 80-bit coordinate.
174    W80([u8; 10]),
175    /// W88: 88-bit coordinate.
176    W88([u8; 11]),
177    /// W96: 96-bit coordinate.
178    W96([u8; 12]),
179    /// W104: 104-bit coordinate.
180    W104([u8; 13]),
181    /// W112: 112-bit coordinate.
182    W112([u8; 14]),
183    /// W120: 120-bit coordinate.
184    W120([u8; 15]),
185    /// W128: 128-bit coordinate.
186    W128([u8; 16]),
187}
188
189/// A single grounded coordinate value.
190/// Not a `Datum` \[this is the narrow intermediate that a `Grounding`
191/// impl produces\]. The foundation validates and mints it into a `Datum`.
192/// Uses the same closed level-tagged family as `Datum`, ensuring that
193/// coordinate width matches the target Witt level.
194/// # Examples
195/// ```rust
196/// use uor_foundation::enforcement::GroundedCoord;
197///
198/// // W8: 8-bit ring Z/256Z — lightweight, exhaustive-verification baseline
199/// let byte_coord = GroundedCoord::w8(42);
200///
201/// // W16: 16-bit ring Z/65536Z — audio samples, small indices
202/// let short_coord = GroundedCoord::w16(1000);
203///
204/// // W32: 32-bit ring Z/2^32Z — pixel data, general-purpose integers
205/// let word_coord = GroundedCoord::w32(70_000);
206/// ```
207#[derive(Debug, Clone, PartialEq, Eq)]
208pub struct GroundedCoord {
209    /// Level-tagged coordinate bytes.
210    pub(crate) inner: GroundedCoordInner,
211}
212
213impl GroundedCoord {
214    /// Construct a W8 coordinate from a `u8` value (little-endian).
215    #[inline]
216    #[must_use]
217    pub const fn w8(value: u8) -> Self {
218        Self {
219            inner: GroundedCoordInner::W8(value.to_le_bytes()),
220        }
221    }
222
223    /// Construct a W16 coordinate from a `u16` value (little-endian).
224    #[inline]
225    #[must_use]
226    pub const fn w16(value: u16) -> Self {
227        Self {
228            inner: GroundedCoordInner::W16(value.to_le_bytes()),
229        }
230    }
231
232    /// Construct a W24 coordinate from a `u32` value (little-endian).
233    #[inline]
234    #[must_use]
235    pub const fn w24(value: u32) -> Self {
236        let full = value.to_le_bytes();
237        let mut out = [0u8; 3];
238        let mut i = 0;
239        while i < 3 {
240            out[i] = full[i];
241            i += 1;
242        }
243        Self {
244            inner: GroundedCoordInner::W24(out),
245        }
246    }
247
248    /// Construct a W32 coordinate from a `u32` value (little-endian).
249    #[inline]
250    #[must_use]
251    pub const fn w32(value: u32) -> Self {
252        Self {
253            inner: GroundedCoordInner::W32(value.to_le_bytes()),
254        }
255    }
256
257    /// Construct a W40 coordinate from a `u64` value (little-endian).
258    #[inline]
259    #[must_use]
260    pub const fn w40(value: u64) -> Self {
261        let full = value.to_le_bytes();
262        let mut out = [0u8; 5];
263        let mut i = 0;
264        while i < 5 {
265            out[i] = full[i];
266            i += 1;
267        }
268        Self {
269            inner: GroundedCoordInner::W40(out),
270        }
271    }
272
273    /// Construct a W48 coordinate from a `u64` value (little-endian).
274    #[inline]
275    #[must_use]
276    pub const fn w48(value: u64) -> Self {
277        let full = value.to_le_bytes();
278        let mut out = [0u8; 6];
279        let mut i = 0;
280        while i < 6 {
281            out[i] = full[i];
282            i += 1;
283        }
284        Self {
285            inner: GroundedCoordInner::W48(out),
286        }
287    }
288
289    /// Construct a W56 coordinate from a `u64` value (little-endian).
290    #[inline]
291    #[must_use]
292    pub const fn w56(value: u64) -> Self {
293        let full = value.to_le_bytes();
294        let mut out = [0u8; 7];
295        let mut i = 0;
296        while i < 7 {
297            out[i] = full[i];
298            i += 1;
299        }
300        Self {
301            inner: GroundedCoordInner::W56(out),
302        }
303    }
304
305    /// Construct a W64 coordinate from a `u64` value (little-endian).
306    #[inline]
307    #[must_use]
308    pub const fn w64(value: u64) -> Self {
309        Self {
310            inner: GroundedCoordInner::W64(value.to_le_bytes()),
311        }
312    }
313
314    /// Construct a W72 coordinate from a `u128` value (little-endian).
315    #[inline]
316    #[must_use]
317    pub const fn w72(value: u128) -> Self {
318        let full = value.to_le_bytes();
319        let mut out = [0u8; 9];
320        let mut i = 0;
321        while i < 9 {
322            out[i] = full[i];
323            i += 1;
324        }
325        Self {
326            inner: GroundedCoordInner::W72(out),
327        }
328    }
329
330    /// Construct a W80 coordinate from a `u128` value (little-endian).
331    #[inline]
332    #[must_use]
333    pub const fn w80(value: u128) -> Self {
334        let full = value.to_le_bytes();
335        let mut out = [0u8; 10];
336        let mut i = 0;
337        while i < 10 {
338            out[i] = full[i];
339            i += 1;
340        }
341        Self {
342            inner: GroundedCoordInner::W80(out),
343        }
344    }
345
346    /// Construct a W88 coordinate from a `u128` value (little-endian).
347    #[inline]
348    #[must_use]
349    pub const fn w88(value: u128) -> Self {
350        let full = value.to_le_bytes();
351        let mut out = [0u8; 11];
352        let mut i = 0;
353        while i < 11 {
354            out[i] = full[i];
355            i += 1;
356        }
357        Self {
358            inner: GroundedCoordInner::W88(out),
359        }
360    }
361
362    /// Construct a W96 coordinate from a `u128` value (little-endian).
363    #[inline]
364    #[must_use]
365    pub const fn w96(value: u128) -> Self {
366        let full = value.to_le_bytes();
367        let mut out = [0u8; 12];
368        let mut i = 0;
369        while i < 12 {
370            out[i] = full[i];
371            i += 1;
372        }
373        Self {
374            inner: GroundedCoordInner::W96(out),
375        }
376    }
377
378    /// Construct a W104 coordinate from a `u128` value (little-endian).
379    #[inline]
380    #[must_use]
381    pub const fn w104(value: u128) -> Self {
382        let full = value.to_le_bytes();
383        let mut out = [0u8; 13];
384        let mut i = 0;
385        while i < 13 {
386            out[i] = full[i];
387            i += 1;
388        }
389        Self {
390            inner: GroundedCoordInner::W104(out),
391        }
392    }
393
394    /// Construct a W112 coordinate from a `u128` value (little-endian).
395    #[inline]
396    #[must_use]
397    pub const fn w112(value: u128) -> Self {
398        let full = value.to_le_bytes();
399        let mut out = [0u8; 14];
400        let mut i = 0;
401        while i < 14 {
402            out[i] = full[i];
403            i += 1;
404        }
405        Self {
406            inner: GroundedCoordInner::W112(out),
407        }
408    }
409
410    /// Construct a W120 coordinate from a `u128` value (little-endian).
411    #[inline]
412    #[must_use]
413    pub const fn w120(value: u128) -> Self {
414        let full = value.to_le_bytes();
415        let mut out = [0u8; 15];
416        let mut i = 0;
417        while i < 15 {
418            out[i] = full[i];
419            i += 1;
420        }
421        Self {
422            inner: GroundedCoordInner::W120(out),
423        }
424    }
425
426    /// Construct a W128 coordinate from a `u128` value (little-endian).
427    #[inline]
428    #[must_use]
429    pub const fn w128(value: u128) -> Self {
430        let full = value.to_le_bytes();
431        let mut out = [0u8; 16];
432        let mut i = 0;
433        while i < 16 {
434            out[i] = full[i];
435            i += 1;
436        }
437        Self {
438            inner: GroundedCoordInner::W128(out),
439        }
440    }
441}
442
443/// A grounded tuple: a fixed-size array of `GroundedCoord` values.
444/// Represents a structured type (e.g., the 8 coordinates of an E8
445/// lattice point). Not a `Datum` until the foundation validates and
446/// mints it. Stack-resident, no heap allocation.
447/// # Examples
448/// ```rust
449/// use uor_foundation::enforcement::{GroundedCoord, GroundedTuple};
450///
451/// // A 2D pixel: (red, green) at W8 (8-bit per channel)
452/// let pixel = GroundedTuple::new([
453///     GroundedCoord::w8(255), // red channel
454///     GroundedCoord::w8(128), // green channel
455/// ]);
456///
457/// // An E8 lattice point: 8 coordinates at W8
458/// let lattice_point = GroundedTuple::new([
459///     GroundedCoord::w8(2), GroundedCoord::w8(0),
460///     GroundedCoord::w8(0), GroundedCoord::w8(0),
461///     GroundedCoord::w8(0), GroundedCoord::w8(0),
462///     GroundedCoord::w8(0), GroundedCoord::w8(0),
463/// ]);
464/// ```
465#[derive(Debug, Clone, PartialEq, Eq)]
466pub struct GroundedTuple<const N: usize> {
467    /// The coordinate array.
468    pub(crate) coords: [GroundedCoord; N],
469}
470
471impl<const N: usize> GroundedTuple<N> {
472    /// Construct a tuple from a fixed-size array of coordinates.
473    #[inline]
474    #[must_use]
475    pub const fn new(coords: [GroundedCoord; N]) -> Self {
476        Self { coords }
477    }
478}
479
480/// Sealed marker trait for grounded intermediates.
481/// Implemented only for `GroundedCoord` and `GroundedTuple<N>`.
482/// Prism code cannot implement this \[the sealed module pattern
483/// prevents it\].
484pub trait GroundedValue: sealed::Sealed {}
485impl GroundedValue for GroundedCoord {}
486impl<const N: usize> GroundedValue for GroundedTuple<N> {}
487
488/// Target §3: sealed marker trait shared by all morphism kinds.
489/// `GroundingMapKind` (inbound) and `ProjectionMapKind` (outbound) both
490/// extend this trait; the four structural markers (`Total`, `Invertible`,
491/// `PreservesStructure`, `PreservesMetric`) are bounded on `MorphismKind`.
492pub trait MorphismKind: morphism_kind_sealed::Sealed {
493    /// The ontology IRI of this morphism kind.
494    const ONTOLOGY_IRI: &'static str;
495}
496
497/// v0.2.2 W4: sealed marker trait for the kind of a `Grounding` map.
498/// Implemented by exactly the `morphism:GroundingMap` individuals declared in
499/// the ontology; downstream cannot extend the kind set.
500pub trait GroundingMapKind: MorphismKind + grounding_map_kind_sealed::Sealed {}
501
502/// Target §3: sealed marker trait for the kind of a `Sinking` projection.
503/// Implemented by exactly the `morphism:ProjectionMap` individuals declared
504/// in the ontology; downstream cannot extend the kind set.
505pub trait ProjectionMapKind: MorphismKind + projection_map_kind_sealed::Sealed {}
506
507/// v0.2.2 W4: kinds whose image is total over the input domain
508/// (every input maps successfully).
509pub trait Total: MorphismKind {}
510
511/// v0.2.2 W4: kinds whose map is injective and admits an inverse on its image.
512pub trait Invertible: MorphismKind {}
513
514/// v0.2.2 W4: kinds whose map preserves the algebraic structure of the
515/// source domain (homomorphism-like).
516pub trait PreservesStructure: MorphismKind {}
517
518/// v0.2.2 W4: kinds whose map preserves the metric of the source domain
519/// (isometry-like).
520pub trait PreservesMetric: MorphismKind {}
521
522/// v0.2.2 W4: kind for raw byte ingestion. Total and invertible; preserves bit identity only.
523#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
524pub struct BinaryGroundingMap;
525
526/// v0.2.2 W4: kind for one-way digest functions (e.g., SHA-256). Total but not invertible; preserves no structure.
527#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
528pub struct DigestGroundingMap;
529
530/// v0.2.2 W4: kind for integer surface symbols. Total, invertible, structure-preserving.
531#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
532pub struct IntegerGroundingMap;
533
534/// v0.2.2 W4: kind for JSON host strings. Invertible on its image, structure-preserving.
535#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
536pub struct JsonGroundingMap;
537
538/// v0.2.2 W4: kind for UTF-8 host strings. Invertible on its image, structure-preserving.
539#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
540pub struct Utf8GroundingMap;
541
542/// Target §3: kind for raw byte projections. Total and invertible; preserves bit identity only.
543#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
544pub struct BinaryProjectionMap;
545
546/// Target §3: kind for fixed-size digests projected outward. Total but not invertible; preserves no structure.
547#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
548pub struct DigestProjectionMap;
549
550/// Target §3: kind for integer surface symbols projected outward. Invertible, structure-preserving.
551#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
552pub struct IntegerProjectionMap;
553
554/// Target §3: kind for JSON host strings projected outward. Invertible, structure-preserving.
555#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
556pub struct JsonProjectionMap;
557
558/// Target §3: kind for UTF-8 host strings projected outward. Invertible, structure-preserving.
559#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
560pub struct Utf8ProjectionMap;
561
562mod morphism_kind_sealed {
563    /// Private supertrait for MorphismKind. Not implementable outside this crate.
564    pub trait Sealed {}
565    impl Sealed for super::BinaryGroundingMap {}
566    impl Sealed for super::DigestGroundingMap {}
567    impl Sealed for super::IntegerGroundingMap {}
568    impl Sealed for super::JsonGroundingMap {}
569    impl Sealed for super::Utf8GroundingMap {}
570    impl Sealed for super::BinaryProjectionMap {}
571    impl Sealed for super::DigestProjectionMap {}
572    impl Sealed for super::IntegerProjectionMap {}
573    impl Sealed for super::JsonProjectionMap {}
574    impl Sealed for super::Utf8ProjectionMap {}
575}
576
577mod grounding_map_kind_sealed {
578    /// Private supertrait. Not implementable outside this crate.
579    pub trait Sealed {}
580    impl Sealed for super::BinaryGroundingMap {}
581    impl Sealed for super::DigestGroundingMap {}
582    impl Sealed for super::IntegerGroundingMap {}
583    impl Sealed for super::JsonGroundingMap {}
584    impl Sealed for super::Utf8GroundingMap {}
585}
586
587mod projection_map_kind_sealed {
588    /// Private supertrait. Not implementable outside this crate.
589    pub trait Sealed {}
590    impl Sealed for super::BinaryProjectionMap {}
591    impl Sealed for super::DigestProjectionMap {}
592    impl Sealed for super::IntegerProjectionMap {}
593    impl Sealed for super::JsonProjectionMap {}
594    impl Sealed for super::Utf8ProjectionMap {}
595}
596
597impl MorphismKind for BinaryGroundingMap {
598    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/BinaryGroundingMap";
599}
600
601impl MorphismKind for DigestGroundingMap {
602    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/DigestGroundingMap";
603}
604
605impl MorphismKind for IntegerGroundingMap {
606    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/IntegerGroundingMap";
607}
608
609impl MorphismKind for JsonGroundingMap {
610    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/JsonGroundingMap";
611}
612
613impl MorphismKind for Utf8GroundingMap {
614    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/Utf8GroundingMap";
615}
616
617impl MorphismKind for BinaryProjectionMap {
618    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/BinaryProjectionMap";
619}
620
621impl MorphismKind for DigestProjectionMap {
622    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/DigestProjectionMap";
623}
624
625impl MorphismKind for IntegerProjectionMap {
626    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/IntegerProjectionMap";
627}
628
629impl MorphismKind for JsonProjectionMap {
630    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/JsonProjectionMap";
631}
632
633impl MorphismKind for Utf8ProjectionMap {
634    const ONTOLOGY_IRI: &'static str = "https://uor.foundation/morphism/Utf8ProjectionMap";
635}
636
637impl GroundingMapKind for BinaryGroundingMap {}
638impl GroundingMapKind for DigestGroundingMap {}
639impl GroundingMapKind for IntegerGroundingMap {}
640impl GroundingMapKind for JsonGroundingMap {}
641impl GroundingMapKind for Utf8GroundingMap {}
642
643impl ProjectionMapKind for BinaryProjectionMap {}
644impl ProjectionMapKind for DigestProjectionMap {}
645impl ProjectionMapKind for IntegerProjectionMap {}
646impl ProjectionMapKind for JsonProjectionMap {}
647impl ProjectionMapKind for Utf8ProjectionMap {}
648
649impl Total for IntegerGroundingMap {}
650impl Invertible for IntegerGroundingMap {}
651impl PreservesStructure for IntegerGroundingMap {}
652
653impl Invertible for Utf8GroundingMap {}
654impl PreservesStructure for Utf8GroundingMap {}
655
656impl Invertible for JsonGroundingMap {}
657impl PreservesStructure for JsonGroundingMap {}
658
659impl Total for DigestGroundingMap {}
660
661impl Total for BinaryGroundingMap {}
662impl Invertible for BinaryGroundingMap {}
663
664impl Invertible for IntegerProjectionMap {}
665impl PreservesStructure for IntegerProjectionMap {}
666
667impl Invertible for Utf8ProjectionMap {}
668impl PreservesStructure for Utf8ProjectionMap {}
669
670impl Invertible for JsonProjectionMap {}
671impl PreservesStructure for JsonProjectionMap {}
672
673impl Total for DigestProjectionMap {}
674
675impl Total for BinaryProjectionMap {}
676impl Invertible for BinaryProjectionMap {}
677
678/// Open trait for boundary crossing: external data to grounded intermediate.
679/// The foundation validates the returned value against the declared
680/// `GroundingShape` and mints it into a `Datum` if conformant.
681/// v0.2.2 W4 adds the `Map: GroundingMapKind` associated type — every impl
682/// must declare what *kind* of grounding map it is. Foundation operations
683/// that require structure preservation gate on `<G as Grounding>::Map: PreservesStructure`,
684/// and a digest-style impl is rejected at the call site.
685/// # Examples
686/// ```no_run
687/// use uor_foundation::enforcement::{
688///     Grounding, GroundedCoord, GroundingProgram, BinaryGroundingMap, combinators,
689/// };
690///
691/// /// Byte-passthrough grounding: reads the first byte of input as a W8 Datum.
692/// struct PassthroughGrounding;
693///
694/// impl Grounding for PassthroughGrounding {
695///     type Output = GroundedCoord;
696///     type Map = BinaryGroundingMap;
697///
698///     // Phase K: provide the combinator program; the type system verifies
699///     // at compile time that its marker tuple matches Self::Map via
700///     // GroundingProgram::from_primitive's MarkersImpliedBy<Map> bound.
701///     fn program(&self) -> GroundingProgram<GroundedCoord, BinaryGroundingMap> {
702///         GroundingProgram::from_primitive(combinators::read_bytes::<GroundedCoord>())
703///     }
704///     // Foundation supplies `ground()` via the sealed `GroundingExt`
705///     // extension trait — downstream implementers provide only `program()`.
706/// }
707/// ```
708pub trait Grounding {
709    /// The grounded intermediate type. Bounded by `GroundedValue`,
710    /// which is sealed \[only `GroundedCoord` and `GroundedTuple<N>`
711    /// are permitted\].
712    type Output: GroundedValue;
713
714    /// v0.2.2 W4: the kind of grounding map this impl is. Sealed to the
715    /// set of `morphism:GroundingMap` individuals declared in the
716    /// ontology. Every impl must declare the kind explicitly; if no kind
717    /// applies, use `BinaryGroundingMap` (the most permissive — total +
718    /// invertible, no structure preservation).
719    type Map: GroundingMapKind;
720
721    /// Phase K / W4 closure (target §4.3 + §9 criterion 1): the combinator
722    /// program that decomposes this grounding. The program's `Map` parameter
723    /// equals the impl's `Map` associated type, so the kind discriminator is
724    /// mechanically verifiable from the combinator decomposition — not a
725    /// promise. This is the only required method; `ground` is foundation-
726    /// supplied via `GroundingExt`.
727    fn program(&self) -> GroundingProgram<Self::Output, Self::Map>;
728}
729
730/// W4 closure (target §4.3 + §9 criterion 1): foundation-authored
731/// extension trait that supplies `ground()` for every `Grounding`
732/// impl. Downstream implementers provide only `program()`;
733/// the foundation runs it via the blanket `impl<G: Grounding>`
734/// below. The sealed supertrait prevents downstream from
735/// implementing `GroundingExt` directly — there is no second path.
736mod grounding_ext_sealed {
737    /// Private supertrait. Not implementable outside this crate.
738    pub trait Sealed {}
739    impl<G: super::Grounding> Sealed for G {}
740}
741
742/// Crate-internal bridge from `GroundingProgram` to `Option<Out>`.
743/// Blanket-impl'd for the two `GroundedValue` members
744/// (`GroundedCoord` and `GroundedTuple<N>`) so the `GroundingExt`
745/// blanket compiles for any output in the closed set.
746pub trait GroundingProgramRun<Out> {
747    /// Run the program on external bytes.
748    fn run_program(&self, external: &[u8]) -> Option<Out>;
749}
750
751impl<Map: GroundingMapKind> GroundingProgramRun<GroundedCoord>
752    for GroundingProgram<GroundedCoord, Map>
753{
754    #[inline]
755    fn run_program(&self, external: &[u8]) -> Option<GroundedCoord> {
756        self.run(external)
757    }
758}
759
760impl<const N: usize, Map: GroundingMapKind> GroundingProgramRun<GroundedTuple<N>>
761    for GroundingProgram<GroundedTuple<N>, Map>
762{
763    #[inline]
764    fn run_program(&self, external: &[u8]) -> Option<GroundedTuple<N>> {
765        self.run(external)
766    }
767}
768
769/// Foundation-supplied `ground()` for every `Grounding` impl.
770/// The blanket `impl<G: Grounding> GroundingExt for G` below
771/// routes every call of `.ground(bytes)` through
772/// `self.program().run_program(bytes)`. Downstream cannot
773/// override this path: `GroundingExt` has a sealed supertrait
774/// and downstream cannot impl `GroundingExt` directly.
775pub trait GroundingExt: Grounding + grounding_ext_sealed::Sealed {
776    /// Map external bytes into a grounded value via this impl's combinator program.
777    /// Returns `None` when the combinator chain rejects the input (e.g. empty slice
778    /// for `ReadBytes`, malformed UTF-8 for `DecodeUtf8`).
779    fn ground(&self, external: &[u8]) -> Option<Self::Output>;
780}
781
782impl<G: Grounding> GroundingExt for G
783where
784    GroundingProgram<G::Output, G::Map>: GroundingProgramRun<G::Output>,
785{
786    #[inline]
787    fn ground(&self, external: &[u8]) -> Option<Self::Output> {
788        self.program().run_program(external)
789    }
790}
791
792/// Target §3 + §4.6: the foundation-owned operational contract for outbound
793/// boundary crossings. Dual of `Grounding`.
794/// A `Sinking` impl projects a `Grounded<Source>` value to a host-side
795/// `Output` through a specific `ProjectionMap` kind. The `&Grounded<Source>`
796/// input is structurally unforgeable (sealed per §2) — no raw data can be
797/// laundered through this contract. Downstream authors implement `Sinking`
798/// for their projection types; the foundation guarantees the input pedigree.
799/// # Examples
800/// ```no_run
801/// use uor_foundation::enforcement::{
802///     Grounded, Sinking, Utf8ProjectionMap, ConstrainedTypeInput,
803/// };
804///
805/// struct MyJsonSink;
806///
807/// impl Sinking for MyJsonSink {
808///     type Source = ConstrainedTypeInput;
809///     type ProjectionMap = Utf8ProjectionMap;
810///     type Output = String;
811///
812///     fn project(&self, grounded: &Grounded<ConstrainedTypeInput>) -> String {
813///         format!("{:?}", grounded.unit_address())
814///     }
815/// }
816/// ```
817pub trait Sinking {
818    /// The ring-side shape `T` carried by the `Grounded<T>` being projected.
819    /// Sealed via `GroundedShape` — downstream cannot forge an admissible Source.
820    type Source: GroundedShape;
821
822    /// The ontology-declared ProjectionMap kind this impl serves. Sealed to
823    /// the closed set of `morphism:ProjectionMap` individuals.
824    type ProjectionMap: ProjectionMapKind;
825
826    /// The host-side output type of this projection. Intentionally generic —
827    /// downstream chooses `String`, `Vec<u8>`, `serde_json::Value`, or any
828    /// host-appropriate carrier.
829    type Output;
830
831    /// Project a grounded ring value to the host output. The `&Grounded<Source>`
832    /// input is unforgeable (Grounded is sealed per §2) — no raw data can be
833    /// laundered through this contract.
834    fn project(&self, grounded: &Grounded<Self::Source>) -> Self::Output;
835}
836
837/// Target §4.6: extension trait tying `EmitEffect<H>` (ontology-declarative)
838/// to `Sinking` (Rust-operational). Emit-effect implementations carry a
839/// specific `Sinking` impl; the emit operation threads a sealed
840/// `Grounded<Source>` through the projection.
841pub trait EmitThrough<H: crate::HostTypes>: crate::bridge::boundary::EmitEffect<H> {
842    /// The `Sinking` implementation this emit-effect routes through.
843    type Sinking: Sinking;
844
845    /// Emit a grounded value through this effect's bound `Sinking`. The
846    /// input type is the sealed `Grounded<Source>` of the bound `Sinking`;
847    /// nothing else is admissible.
848    fn emit(
849        &self,
850        grounded: &Grounded<<Self::Sinking as Sinking>::Source>,
851    ) -> <Self::Sinking as Sinking>::Output;
852}
853
854/// v0.2.2 W13: sealed marker trait for the validation phase at which a
855/// `Validated<T, Phase>` was witnessed. Implemented only by `CompileTime`
856/// and `Runtime`; downstream cannot extend.
857pub trait ValidationPhase: validation_phase_sealed::Sealed {}
858
859mod validation_phase_sealed {
860    /// Private supertrait. Not implementable outside this crate.
861    pub trait Sealed {}
862    impl Sealed for super::CompileTime {}
863    impl Sealed for super::Runtime {}
864}
865
866/// v0.2.2 W13: marker for compile-time validated witnesses produced by
867/// `validate_const()` and usable in `const` contexts. Convertible to
868/// `Validated<T, Runtime>` via `From`.
869#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
870pub struct CompileTime;
871impl ValidationPhase for CompileTime {}
872
873/// v0.2.2 W13: marker for runtime-validated witnesses produced by
874/// `validate()`. The default phase of `Validated<T>` so v0.2.1 call
875/// sites continue to compile.
876#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
877pub struct Runtime;
878impl ValidationPhase for Runtime {}
879
880/// Proof that a value was produced by the conformance checker,
881/// not fabricated by Prism code.
882/// The inner value and `_sealed` field are private, so `Validated<T>`
883/// can only be constructed within this crate.
884/// v0.2.2 W13: parameterized by a `Phase: ValidationPhase` discriminator.
885/// `Validated<T, CompileTime>` was witnessed by `validate_const()` and is
886/// usable in const contexts. `Validated<T, Runtime>` (the default) was
887/// witnessed by `validate()`. A `CompileTime` witness is convertible to
888/// a `Runtime` witness via `From`.
889/// # Examples
890/// ```no_run
891/// use uor_foundation::enforcement::{CompileUnitBuilder, ConstrainedTypeInput, Term};
892/// use uor_foundation::{WittLevel, VerificationDomain};
893///
894/// // Validated<T> proves that a value passed conformance checking.
895/// // You cannot construct one directly — only builder validate() methods
896/// // and the minting boundary produce them.
897/// let terms = [uor_foundation::pipeline::literal_u64(1, WittLevel::W8)];
898/// let domains = [VerificationDomain::Enumerative];
899///
900/// let validated = CompileUnitBuilder::new()
901///     .root_term(&terms)
902///     .witt_level_ceiling(WittLevel::W8)
903///     .thermodynamic_budget(1024)
904///     .target_domains(&domains)
905///     .result_type::<ConstrainedTypeInput>()
906///     .validate()
907///     .expect("all fields set");
908///
909/// // Access the inner value through the proof wrapper:
910/// let _compile_unit = validated.inner();
911/// ```
912#[derive(Debug, Clone, PartialEq, Eq)]
913pub struct Validated<T, Phase: ValidationPhase = Runtime> {
914    /// The validated inner value.
915    inner: T,
916    /// Phantom marker for the validation phase (`CompileTime` or `Runtime`).
917    _phase: PhantomData<Phase>,
918    /// Prevents external construction.
919    _sealed: (),
920}
921
922impl<T, Phase: ValidationPhase> Validated<T, Phase> {
923    /// Returns a reference to the validated inner value.
924    #[inline]
925    #[must_use]
926    pub const fn inner(&self) -> &T {
927        &self.inner
928    }
929
930    /// Creates a new `Validated<T, Phase>` wrapper. Only callable within the crate.
931    #[inline]
932    #[allow(dead_code)]
933    pub(crate) const fn new(inner: T) -> Self {
934        Self {
935            inner,
936            _phase: PhantomData,
937            _sealed: (),
938        }
939    }
940}
941
942/// v0.2.2 W13: a compile-time witness is usable wherever a runtime witness is required.
943impl<T> From<Validated<T, CompileTime>> for Validated<T, Runtime> {
944    #[inline]
945    fn from(value: Validated<T, CompileTime>) -> Self {
946        Self {
947            inner: value.inner,
948            _phase: PhantomData,
949            _sealed: (),
950        }
951    }
952}
953
954/// An opaque derivation trace that can only be extended by the rewrite engine.
955/// Records the rewrite-step count, the source `witt_level_bits`, and the
956/// parametric `content_fingerprint`. Private fields prevent external
957/// construction; produced exclusively by `Grounded::derivation()` so the
958/// verify path can re-derive the source certificate via
959/// `Derivation::replay() -> Trace -> verify_trace`.
960#[derive(Debug, Clone, PartialEq, Eq)]
961pub struct Derivation {
962    /// Number of rewrite steps in this derivation.
963    step_count: u32,
964    /// v0.2.2 T5: Witt level the source grounding was minted at. Carried
965    /// through replay so the verifier can reconstruct the certificate.
966    witt_level_bits: u16,
967    /// v0.2.2 T5: parametric content fingerprint of the source unit's
968    /// full state, computed at grounding time by the consumer-supplied
969    /// `Hasher`. Carried through replay so the verifier can reproduce
970    /// the source certificate via passthrough.
971    content_fingerprint: ContentFingerprint,
972}
973
974impl Derivation {
975    /// Returns the number of rewrite steps.
976    #[inline]
977    #[must_use]
978    pub const fn step_count(&self) -> u32 {
979        self.step_count
980    }
981
982    /// v0.2.2 T5: returns the Witt level the source grounding was minted at.
983    #[inline]
984    #[must_use]
985    pub const fn witt_level_bits(&self) -> u16 {
986        self.witt_level_bits
987    }
988
989    /// v0.2.2 T5: returns the parametric content fingerprint of the source
990    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
991    #[inline]
992    #[must_use]
993    pub const fn content_fingerprint(&self) -> ContentFingerprint {
994        self.content_fingerprint
995    }
996
997    /// Creates a new derivation. Only callable within the crate.
998    #[inline]
999    #[must_use]
1000    #[allow(dead_code)]
1001    pub(crate) const fn new(
1002        step_count: u32,
1003        witt_level_bits: u16,
1004        content_fingerprint: ContentFingerprint,
1005    ) -> Self {
1006        Self {
1007            step_count,
1008            witt_level_bits,
1009            content_fingerprint,
1010        }
1011    }
1012}
1013
1014/// An opaque free rank that can only be decremented by `PinningEffect`
1015/// and incremented by `UnbindingEffect` \[never by direct mutation\].
1016#[derive(Debug, Clone, PartialEq, Eq)]
1017pub struct FreeRank {
1018    /// Total site capacity at the Witt level.
1019    total: u32,
1020    /// Currently pinned sites.
1021    pinned: u32,
1022}
1023
1024impl FreeRank {
1025    /// Returns the total site capacity.
1026    #[inline]
1027    #[must_use]
1028    pub const fn total(&self) -> u32 {
1029        self.total
1030    }
1031
1032    /// Returns the number of currently pinned sites.
1033    #[inline]
1034    #[must_use]
1035    pub const fn pinned(&self) -> u32 {
1036        self.pinned
1037    }
1038
1039    /// Returns the number of remaining (unpinned) sites.
1040    #[inline]
1041    #[must_use]
1042    pub const fn remaining(&self) -> u32 {
1043        self.total - self.pinned
1044    }
1045
1046    /// Creates a new free rank. Only callable within the crate.
1047    #[inline]
1048    #[allow(dead_code)]
1049    pub(crate) const fn new(total: u32, pinned: u32) -> Self {
1050        Self { total, pinned }
1051    }
1052}
1053
1054/// v0.2.2 Phase A: sealed `H::Decimal`-backed newtype carrying the
1055/// `observable:LandauerCost` accumulator in `observable:Nats`.
1056/// Monotonic within a pipeline invocation. The UOR ring operates
1057/// at the Landauer temperature (β* = ln 2), so this observable is
1058/// a direct measure of irreversible bit-erasure performed.
1059/// Phase 9: parameterized over `H: HostTypes` so the underlying
1060/// decimal type tracks the host's chosen precision.
1061#[derive(Debug)]
1062pub struct LandauerBudget<H: HostTypes = crate::DefaultHostTypes> {
1063    /// Accumulated Landauer cost in nats. Non-negative, finite.
1064    nats: H::Decimal,
1065    /// Phantom marker pinning the host type.
1066    _phantom: core::marker::PhantomData<H>,
1067    /// Prevents external construction.
1068    _sealed: (),
1069}
1070
1071impl<H: HostTypes> LandauerBudget<H> {
1072    /// Returns the accumulated Landauer cost in nats.
1073    #[inline]
1074    #[must_use]
1075    pub const fn nats(&self) -> H::Decimal {
1076        self.nats
1077    }
1078
1079    /// Crate-internal constructor. Caller guarantees `nats` is
1080    /// non-negative and finite (i.e. not NaN, not infinite).
1081    #[inline]
1082    #[must_use]
1083    #[allow(dead_code)]
1084    pub(crate) const fn new(nats: H::Decimal) -> Self {
1085        Self {
1086            nats,
1087            _phantom: core::marker::PhantomData,
1088            _sealed: (),
1089        }
1090    }
1091
1092    /// Crate-internal constructor for the zero-cost initial budget.
1093    #[inline]
1094    #[must_use]
1095    #[allow(dead_code)]
1096    pub(crate) const fn zero() -> Self {
1097        Self {
1098            nats: H::EMPTY_DECIMAL,
1099            _phantom: core::marker::PhantomData,
1100            _sealed: (),
1101        }
1102    }
1103}
1104
1105impl<H: HostTypes> Copy for LandauerBudget<H> {}
1106impl<H: HostTypes> Clone for LandauerBudget<H> {
1107    #[inline]
1108    fn clone(&self) -> Self {
1109        *self
1110    }
1111}
1112impl<H: HostTypes> PartialEq for LandauerBudget<H> {
1113    #[inline]
1114    fn eq(&self, other: &Self) -> bool {
1115        self.nats == other.nats
1116    }
1117}
1118impl<H: HostTypes> Eq for LandauerBudget<H> {}
1119impl<H: HostTypes> PartialOrd for LandauerBudget<H> {
1120    #[inline]
1121    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1122        Some(self.cmp(other))
1123    }
1124}
1125impl<H: HostTypes> Ord for LandauerBudget<H> {
1126    #[inline]
1127    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1128        // Total order on H::Decimal with NaN excluded by construction.
1129        self.nats
1130            .partial_cmp(&other.nats)
1131            .unwrap_or(core::cmp::Ordering::Equal)
1132    }
1133}
1134impl<H: HostTypes> core::hash::Hash for LandauerBudget<H> {
1135    #[inline]
1136    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
1137        // DecimalTranscendental::to_bits gives a stable u64 fingerprint
1138        // for any in-range Decimal value.
1139        self.nats.to_bits().hash(state);
1140    }
1141}
1142
1143/// v0.2.2 Phase A: foundation-internal deterministic two-clock value
1144/// carried by every `Grounded<T>` and `Certified<C>`. The two clocks are
1145/// `landauer_nats` (a `LandauerBudget` value backed by `observable:LandauerCost`)
1146/// and `rewrite_steps` (a `u64` backed by `derivation:stepCount` on
1147/// `derivation:TermMetrics`). Each clock is monotonic within a pipeline
1148/// invocation, content-deterministic, ontology-grounded, and binds to a
1149/// physical wall-clock lower bound through established physics (Landauer's
1150/// principle for nats; Margolus-Levitin for rewrite steps). Two clocks
1151/// because exactly two physical lower-bound theorems are grounded; adding
1152/// a third clock would require grounding a third physical theorem.
1153/// `PartialOrd` is component-wise: `a < b` iff every field of `a` is `<=`
1154/// the corresponding field of `b` and at least one is strictly `<`. Two
1155/// `UorTime` values from unrelated computations are genuinely incomparable,
1156/// so `UorTime` is `PartialOrd` but **not** `Ord`.
1157#[derive(Debug)]
1158pub struct UorTime<H: HostTypes = crate::DefaultHostTypes> {
1159    /// Landauer budget consumed, in `observable:Nats`.
1160    landauer_nats: LandauerBudget<H>,
1161    /// Total rewrite steps taken (`derivation:stepCount`).
1162    rewrite_steps: u64,
1163    /// Prevents external construction.
1164    _sealed: (),
1165}
1166
1167impl<H: HostTypes> UorTime<H> {
1168    /// Returns the Landauer budget consumed, in `observable:Nats`.
1169    /// Maps to `observable:LandauerCost`.
1170    #[inline]
1171    #[must_use]
1172    pub const fn landauer_nats(&self) -> LandauerBudget<H> {
1173        self.landauer_nats
1174    }
1175
1176    /// Returns the total rewrite steps taken.
1177    /// Maps to `derivation:stepCount` on `derivation:TermMetrics`.
1178    #[inline]
1179    #[must_use]
1180    pub const fn rewrite_steps(&self) -> u64 {
1181        self.rewrite_steps
1182    }
1183
1184    /// Crate-internal constructor. Reachable only from the pipeline at witness mint time.
1185    #[inline]
1186    #[must_use]
1187    #[allow(dead_code)]
1188    pub(crate) const fn new(landauer_nats: LandauerBudget<H>, rewrite_steps: u64) -> Self {
1189        Self {
1190            landauer_nats,
1191            rewrite_steps,
1192            _sealed: (),
1193        }
1194    }
1195
1196    /// Crate-internal constructor for the zero initial value.
1197    #[inline]
1198    #[must_use]
1199    #[allow(dead_code)]
1200    pub(crate) const fn zero() -> Self {
1201        Self {
1202            landauer_nats: LandauerBudget::<H>::zero(),
1203            rewrite_steps: 0,
1204            _sealed: (),
1205        }
1206    }
1207
1208    /// Returns the provable minimum wall-clock duration that the
1209    /// computation producing this witness could have taken under the
1210    /// given calibration. Returns `max(Landauer-bound, Margolus-Levitin-bound)`.
1211    /// The Landauer bound is `landauer_nats × k_B·T / thermal_power`.
1212    /// The Margolus-Levitin bound is `π·ℏ·rewrite_steps / (2·characteristic_energy)`.
1213    /// Pure arithmetic — no transcendentals, no state. Const-evaluable
1214    /// where the `UorTime` value is known at compile time.
1215    #[inline]
1216    #[must_use]
1217    pub fn min_wall_clock(&self, cal: &Calibration<H>) -> Nanos {
1218        // Landauer bound: nats × k_B·T / thermal_power = seconds.
1219        let landauer_seconds = self.landauer_nats.nats() * cal.k_b_t() / cal.thermal_power();
1220        // Margolus-Levitin bound: π·ℏ / (2·E) per orthogonal state transition.
1221        // π·ℏ ≈ 3.31194e-34 J·s; encoded as the f64 bit pattern of
1222        // `core::f64::consts::PI * 1.054_571_817e-34` so the constant is
1223        // representable across host Decimal types.
1224        let pi_times_h_bar =
1225            <H::Decimal as DecimalTranscendental>::from_bits(crate::PI_TIMES_H_BAR_BITS);
1226        let two = <H::Decimal as DecimalTranscendental>::from_u32(2);
1227        let ml_seconds_per_step = pi_times_h_bar / (two * cal.characteristic_energy());
1228        let steps = <H::Decimal as DecimalTranscendental>::from_u64(self.rewrite_steps);
1229        let ml_seconds = ml_seconds_per_step * steps;
1230        let max_seconds = if landauer_seconds > ml_seconds {
1231            landauer_seconds
1232        } else {
1233            ml_seconds
1234        };
1235        // Convert seconds to nanoseconds, saturate on overflow.
1236        let nanos_per_second =
1237            <H::Decimal as DecimalTranscendental>::from_bits(crate::NANOS_PER_SECOND_BITS);
1238        let nanos = max_seconds * nanos_per_second;
1239        Nanos {
1240            ns: <H::Decimal as DecimalTranscendental>::as_u64_saturating(nanos),
1241            _sealed: (),
1242        }
1243    }
1244}
1245
1246impl<H: HostTypes> Copy for UorTime<H> {}
1247impl<H: HostTypes> Clone for UorTime<H> {
1248    #[inline]
1249    fn clone(&self) -> Self {
1250        *self
1251    }
1252}
1253impl<H: HostTypes> PartialEq for UorTime<H> {
1254    #[inline]
1255    fn eq(&self, other: &Self) -> bool {
1256        self.landauer_nats == other.landauer_nats && self.rewrite_steps == other.rewrite_steps
1257    }
1258}
1259impl<H: HostTypes> Eq for UorTime<H> {}
1260impl<H: HostTypes> core::hash::Hash for UorTime<H> {
1261    #[inline]
1262    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
1263        self.landauer_nats.hash(state);
1264        self.rewrite_steps.hash(state);
1265    }
1266}
1267impl<H: HostTypes> PartialOrd for UorTime<H> {
1268    #[inline]
1269    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1270        let l = self.landauer_nats.cmp(&other.landauer_nats);
1271        let r = self.rewrite_steps.cmp(&other.rewrite_steps);
1272        match (l, r) {
1273            (core::cmp::Ordering::Equal, core::cmp::Ordering::Equal) => {
1274                Some(core::cmp::Ordering::Equal)
1275            }
1276            (core::cmp::Ordering::Less, core::cmp::Ordering::Less)
1277            | (core::cmp::Ordering::Less, core::cmp::Ordering::Equal)
1278            | (core::cmp::Ordering::Equal, core::cmp::Ordering::Less) => {
1279                Some(core::cmp::Ordering::Less)
1280            }
1281            (core::cmp::Ordering::Greater, core::cmp::Ordering::Greater)
1282            | (core::cmp::Ordering::Greater, core::cmp::Ordering::Equal)
1283            | (core::cmp::Ordering::Equal, core::cmp::Ordering::Greater) => {
1284                Some(core::cmp::Ordering::Greater)
1285            }
1286            _ => None,
1287        }
1288    }
1289}
1290
1291/// v0.2.2 Phase A: sealed lower-bound carrier for wall-clock duration.
1292/// Produced only by `UorTime::min_wall_clock` and similar foundation
1293/// time conversions. The sealing guarantees that any `Nanos` value is
1294/// a provable physical bound, not a raw integer. Developers who need
1295/// the underlying `u64` call `.as_u64()`; the sealing prevents
1296/// accidentally passing a host-measured duration where the type system
1297/// expects "a provable minimum".
1298#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1299pub struct Nanos {
1300    /// The provable lower-bound duration in nanoseconds.
1301    ns: u64,
1302    /// Prevents external construction.
1303    _sealed: (),
1304}
1305
1306impl Nanos {
1307    /// Returns the underlying nanosecond count. The value is a provable
1308    /// physical lower bound under whatever calibration produced it.
1309    #[inline]
1310    #[must_use]
1311    pub const fn as_u64(self) -> u64 {
1312        self.ns
1313    }
1314}
1315
1316/// v0.2.2 Phase A: error returned by `Calibration::new` when the supplied
1317/// physical parameters fail plausibility validation.
1318#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1319pub enum CalibrationError {
1320    /// `k_b_t` was non-positive, NaN, or outside the known-universe
1321    /// temperature range (`1e-30 ≤ k_b_t ≤ 1e-15` joules).
1322    ThermalEnergy,
1323    /// `thermal_power` was non-positive, NaN, or above the thermodynamic maximum (`1e9` W).
1324    ThermalPower,
1325    /// `characteristic_energy` was non-positive, NaN, or above the
1326    /// k_B·T × Avogadro-class bound (`1e3` joules).
1327    CharacteristicEnergy,
1328}
1329
1330impl core::fmt::Display for CalibrationError {
1331    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1332        match self {
1333            Self::ThermalEnergy => {
1334                f.write_str("calibration k_b_t out of range (must be in [1e-30, 1e-15] joules)")
1335            }
1336            Self::ThermalPower => {
1337                f.write_str("calibration thermal_power out of range (must be > 0 and <= 1e9 W)")
1338            }
1339            Self::CharacteristicEnergy => f.write_str(
1340                "calibration characteristic_energy out of range (must be > 0 and <= 1e3 J)",
1341            ),
1342        }
1343    }
1344}
1345
1346impl core::error::Error for CalibrationError {}
1347
1348/// v0.2.2 Phase A: physical-substrate calibration for wall-clock binding.
1349/// Construction is open via [`Calibration::new`], but the fields are
1350/// private and validated for physical plausibility. Used to convert
1351/// `UorTime` to a provable wall-clock lower bound via
1352/// [`UorTime::min_wall_clock`].
1353/// **A `Calibration` is never passed into `pipeline::run`,
1354/// `resolver::*::certify`, `validate_const`, or any other foundation entry
1355/// point.** The foundation computes `UorTime` without physical
1356/// interpretation; the developer applies a `Calibration` after the fact.
1357#[derive(Debug)]
1358pub struct Calibration<H: HostTypes = crate::DefaultHostTypes> {
1359    /// Boltzmann constant times temperature, in joules.
1360    k_b_t: H::Decimal,
1361    /// Sustained dissipation in watts.
1362    thermal_power: H::Decimal,
1363    /// Mean energy above ground state, in joules.
1364    characteristic_energy: H::Decimal,
1365    /// Phantom marker pinning the host type.
1366    _phantom: core::marker::PhantomData<H>,
1367}
1368
1369impl<H: HostTypes> Copy for Calibration<H> {}
1370impl<H: HostTypes> Clone for Calibration<H> {
1371    #[inline]
1372    fn clone(&self) -> Self {
1373        *self
1374    }
1375}
1376impl<H: HostTypes> PartialEq for Calibration<H> {
1377    #[inline]
1378    fn eq(&self, other: &Self) -> bool {
1379        self.k_b_t == other.k_b_t
1380            && self.thermal_power == other.thermal_power
1381            && self.characteristic_energy == other.characteristic_energy
1382    }
1383}
1384
1385impl<H: HostTypes> Calibration<H> {
1386    /// Construct a calibration with physically plausible parameters.
1387    /// Validation: every parameter must be positive and finite. `k_b_t`
1388    /// must lie within the known-universe temperature range
1389    /// (`1e-30 <= k_b_t <= 1e-15` joules covers ~1 nK to ~1e8 K).
1390    /// `thermal_power` must be at most `1e9` W (gigawatt class — far above
1391    /// any plausible single-compute envelope). `characteristic_energy`
1392    /// must be at most `1e3` J (kilojoule class — astronomically generous).
1393    /// # Errors
1394    /// Returns `CalibrationError::InvalidThermalEnergy` when `k_b_t` is
1395    /// non-positive, NaN, or outside the temperature range.
1396    /// Returns `CalibrationError::InvalidThermalPower` when `thermal_power`
1397    /// is non-positive, NaN, or above the maximum.
1398    /// Returns `CalibrationError::InvalidCharacteristicEnergy` when
1399    /// `characteristic_energy` is non-positive, NaN, or above the maximum.
1400    /// # Example
1401    /// ```
1402    /// use uor_foundation::enforcement::Calibration;
1403    /// use uor_foundation::DefaultHostTypes;
1404    /// // X86 server-class envelope at room temperature.
1405    /// // k_B·T at 300 K = 4.14e-21 J; 85 W sustained TDP; ~1e-15 J/op.
1406    /// let cal = Calibration::<DefaultHostTypes>::new(4.14e-21, 85.0, 1.0e-15)
1407    ///     .expect("physically plausible server calibration");
1408    /// # let _ = cal;
1409    /// ```
1410    #[inline]
1411    pub fn new(
1412        k_b_t: H::Decimal,
1413        thermal_power: H::Decimal,
1414        characteristic_energy: H::Decimal,
1415    ) -> Result<Self, CalibrationError> {
1416        // Bit-pattern bounds for the validation envelope. Reading them
1417        // through `from_bits` lets the host's chosen Decimal precision
1418        // resolve the comparison without any hardcoded f64 in source.
1419        let zero = <H::Decimal as Default>::default();
1420        let kbt_lo =
1421            <H::Decimal as DecimalTranscendental>::from_bits(crate::CALIBRATION_KBT_LO_BITS);
1422        let kbt_hi =
1423            <H::Decimal as DecimalTranscendental>::from_bits(crate::CALIBRATION_KBT_HI_BITS);
1424        let tp_hi = <H::Decimal as DecimalTranscendental>::from_bits(
1425            crate::CALIBRATION_THERMAL_POWER_HI_BITS,
1426        );
1427        let ce_hi = <H::Decimal as DecimalTranscendental>::from_bits(
1428            crate::CALIBRATION_CHAR_ENERGY_HI_BITS,
1429        );
1430        // NaN identity: NaN != NaN. PartialEq is the defining bound.
1431        #[allow(clippy::eq_op)]
1432        let k_b_t_nan = k_b_t != k_b_t;
1433        if k_b_t_nan || k_b_t <= zero || k_b_t < kbt_lo || k_b_t > kbt_hi {
1434            return Err(CalibrationError::ThermalEnergy);
1435        }
1436        #[allow(clippy::eq_op)]
1437        let tp_nan = thermal_power != thermal_power;
1438        if tp_nan || thermal_power <= zero || thermal_power > tp_hi {
1439            return Err(CalibrationError::ThermalPower);
1440        }
1441        #[allow(clippy::eq_op)]
1442        let ce_nan = characteristic_energy != characteristic_energy;
1443        if ce_nan || characteristic_energy <= zero || characteristic_energy > ce_hi {
1444            return Err(CalibrationError::CharacteristicEnergy);
1445        }
1446        Ok(Self {
1447            k_b_t,
1448            thermal_power,
1449            characteristic_energy,
1450            _phantom: core::marker::PhantomData,
1451        })
1452    }
1453
1454    /// Returns the Boltzmann constant times temperature, in joules.
1455    #[inline]
1456    #[must_use]
1457    pub const fn k_b_t(&self) -> H::Decimal {
1458        self.k_b_t
1459    }
1460
1461    /// Returns the sustained thermal power dissipation, in watts.
1462    #[inline]
1463    #[must_use]
1464    pub const fn thermal_power(&self) -> H::Decimal {
1465        self.thermal_power
1466    }
1467
1468    /// Returns the characteristic energy above ground state, in joules.
1469    #[inline]
1470    #[must_use]
1471    pub const fn characteristic_energy(&self) -> H::Decimal {
1472        self.characteristic_energy
1473    }
1474
1475    /// v0.2.2 T5.5: zero sentinel. All three fields are 0.0 — physically
1476    /// meaningless but safely constructible. Used as the unreachable-branch
1477    /// placeholder in the const-context preset literals (`X86_SERVER`,
1478    /// `ARM_MOBILE`, `CORTEX_M_EMBEDDED`, `CONSERVATIVE_WORST_CASE`). The
1479    /// `meta/calibration_presets_valid` conformance check verifies the
1480    /// preset literals always succeed in `Calibration::new`, so this
1481    /// sentinel is never produced in practice. Do not use it directly;
1482    /// it is exposed only because Rust's const-eval needs a fallback for
1483    /// the impossible `Err` arm of the preset match.
1484    pub const ZERO_SENTINEL: Calibration<H> = Self {
1485        k_b_t: H::EMPTY_DECIMAL,
1486        thermal_power: H::EMPTY_DECIMAL,
1487        characteristic_energy: H::EMPTY_DECIMAL,
1488        _phantom: core::marker::PhantomData,
1489    };
1490}
1491
1492impl Calibration<crate::DefaultHostTypes> {
1493    /// Const constructor for the default-host (f64) path. Bypasses runtime validation; use only for the spec-shipped preset literals where the envelope is statically guaranteed. Parameter types are written as `<DefaultHostTypes as HostTypes>::Decimal` so no `: f64` annotation appears in the public-API surface — the host-type alias is the canonical name; downstream that swaps the host gets the matching decimal automatically.
1494    #[inline]
1495    #[must_use]
1496    pub(crate) const fn from_f64_unchecked(
1497        k_b_t: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1498        thermal_power: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1499        characteristic_energy: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1500    ) -> Self {
1501        Self {
1502            k_b_t,
1503            thermal_power,
1504            characteristic_energy,
1505            _phantom: core::marker::PhantomData,
1506        }
1507    }
1508}
1509
1510/// v0.2.2 Phase A: foundation-shipped preset calibrations covering common
1511/// substrates. The values are derived from published substrate thermals at
1512/// T=300 K (room temperature, where k_B·T ≈ 4.14e-21 J).
1513pub mod calibrations {
1514    use super::Calibration;
1515    use crate::DefaultHostTypes;
1516
1517    /// Server-class x86 (Xeon/EPYC sustained envelope).
1518    /// k_B·T = 4.14e-21 J (T = 300 K), thermal_power = 85 W (typical TDP),
1519    /// characteristic_energy = 1e-15 J/op (~1 fJ/op for modern CMOS).
1520    pub const X86_SERVER: Calibration<DefaultHostTypes> =
1521        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 85.0, 1.0e-15);
1522
1523    /// Mobile ARM SoC (Apple M-series, Snapdragon 8-series sustained envelope).
1524    /// k_B·T = 4.14e-21 J, thermal_power = 5 W, characteristic_energy = 1e-16 J/op.
1525    pub const ARM_MOBILE: Calibration<DefaultHostTypes> =
1526        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 5.0, 1.0e-16);
1527
1528    /// Cortex-M embedded (STM32/nRF52 at 80 MHz).
1529    /// k_B·T = 4.14e-21 J, thermal_power = 0.1 W, characteristic_energy = 1e-17 J/op.
1530    pub const CORTEX_M_EMBEDDED: Calibration<DefaultHostTypes> =
1531        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 0.1, 1.0e-17);
1532
1533    /// The tightest provable lower bound that requires no trust in the
1534    /// issuer's claimed substrate. Values are physically sound but maximally
1535    /// generous: k_B·T at 300 K floor, thermal_power at 1 GW (above any
1536    /// plausible single-compute envelope), characteristic_energy at 1 J
1537    /// (astronomically generous).
1538    /// Applying this calibration yields the smallest `Nanos` physically
1539    /// possible for the computation regardless of substrate claims.
1540    pub const CONSERVATIVE_WORST_CASE: Calibration<DefaultHostTypes> =
1541        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 1.0e9, 1.0);
1542}
1543
1544/// v0.2.2 Phase B (target §1.7): timing-policy carrier. Parametric over host tuning.
1545/// Supplies the preflight / runtime Nanos budgets (canonical values from
1546/// `reduction:PreflightTimingBound` and `reduction:RuntimeTimingBound`) plus
1547/// the `Calibration` used to convert an input's a-priori `UorTime` estimate
1548/// into a Nanos lower bound for comparison against the budget.
1549/// The foundation-canonical default [`CanonicalTimingPolicy`] uses
1550/// `calibrations::CONSERVATIVE_WORST_CASE` (the tightest provable lower-bound
1551/// calibration) and the 10 ms budget from the ontology. Host code overrides by
1552/// implementing `TimingPolicy` on a marker struct and substituting at the
1553/// preflight-function call site.
1554pub trait TimingPolicy {
1555    /// Preflight Nanos budget. Inputs whose a-priori UorTime → min_wall_clock
1556    /// under `Self::CALIBRATION` exceeds this value are rejected at preflight.
1557    const PREFLIGHT_BUDGET_NS: u64;
1558    /// Runtime Nanos budget for post-admission reduction.
1559    const RUNTIME_BUDGET_NS: u64;
1560    /// Canonical Calibration used to convert a-priori UorTime estimates to Nanos.
1561    /// Phase 9: pinned to `Calibration<DefaultHostTypes>` because the trait's `const` slot can't carry a non-DefaultHost generic. Polymorphic consumers build a `Calibration<H>` at runtime via `Calibration::new`.
1562    const CALIBRATION: &'static Calibration<crate::DefaultHostTypes>;
1563}
1564
1565/// v0.2.2 Phase B: foundation-canonical [`TimingPolicy`]. Budget values mirror
1566/// `reduction:PreflightTimingBound` and `reduction:RuntimeTimingBound`; calibration
1567/// is `calibrations::CONSERVATIVE_WORST_CASE` so the Nanos lower bound from any
1568/// input UorTime is the tightest physically-defensible value.
1569#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1570pub struct CanonicalTimingPolicy;
1571
1572impl TimingPolicy for CanonicalTimingPolicy {
1573    const PREFLIGHT_BUDGET_NS: u64 = 10_000_000;
1574    const RUNTIME_BUDGET_NS: u64 = 10_000_000;
1575    const CALIBRATION: &'static Calibration<crate::DefaultHostTypes> =
1576        &calibrations::CONSERVATIVE_WORST_CASE;
1577}
1578
1579/// Phase H (target §1.6): foundation-owned transcendental-arithmetic entry points.
1580/// Routes through the always-on `libm` dependency so every build — std, alloc,
1581/// and strict no_std — has access to `ln` / `exp` / `sqrt` for `xsd:decimal`
1582/// observables. Gating these behind an optional feature flag was considered and
1583/// rejected per target §1.6: an observable that exists in one build and not
1584/// another violates the foundation's "one surface" discipline.
1585/// Downstream code that needs transcendentals should call these wrappers —
1586/// they are the canonical entry point for the four observables target §3 enumerates
1587/// (`convergenceRate`, `residualEntropy`, `collapseAmplitude`, and `op:OA_5` pricing)
1588/// and for any future observable whose implementation admits transcendentals.
1589pub mod transcendentals {
1590    use crate::DecimalTranscendental;
1591
1592    /// Natural logarithm. Dispatches via `DecimalTranscendental::ln`; the foundation's f64 / f32 impls route through `libm::log` / `logf`.
1593    /// Returns `NaN` for `x <= 0.0`, preserving `libm`'s contract.
1594    #[inline]
1595    #[must_use]
1596    pub fn ln<D: DecimalTranscendental>(x: D) -> D {
1597        x.ln()
1598    }
1599
1600    /// Exponential `e^x`. Dispatches via `DecimalTranscendental::exp`.
1601    #[inline]
1602    #[must_use]
1603    pub fn exp<D: DecimalTranscendental>(x: D) -> D {
1604        x.exp()
1605    }
1606
1607    /// Square root. Dispatches via `DecimalTranscendental::sqrt`. Returns `NaN` for `x < 0.0`.
1608    #[inline]
1609    #[must_use]
1610    pub fn sqrt<D: DecimalTranscendental>(x: D) -> D {
1611        x.sqrt()
1612    }
1613
1614    /// Shannon entropy term `-p · ln(p)` in nats. Returns 0 for `p = 0` by
1615    /// continuous extension. Used by `observable:residualEntropy`.
1616    #[inline]
1617    #[must_use]
1618    pub fn entropy_term_nats<D: DecimalTranscendental>(p: D) -> D {
1619        let zero = <D as Default>::default();
1620        if p <= zero {
1621            zero
1622        } else {
1623            zero - p * p.ln()
1624        }
1625    }
1626}
1627
1628/// Fixed-capacity term list for `#![no_std]`. Indices into a `TermArena`.
1629#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1630pub struct TermList {
1631    /// Start index in the arena.
1632    pub start: u32,
1633    /// Number of terms in this list.
1634    pub len: u32,
1635}
1636
1637/// Stack-resident arena for `Term` trees.
1638/// Fixed capacity determined by the const generic `CAP`.
1639/// All `Term` child references are `u32` indices into this arena.
1640/// `#![no_std]`-safe: no heap allocation.
1641/// # Examples
1642/// ```rust
1643/// use uor_foundation::enforcement::{TermArena, Term, TermList};
1644/// use uor_foundation::{WittLevel, PrimitiveOp};
1645///
1646/// // Build the expression `add(3, 5)` bottom-up in an arena.
1647/// let mut arena = TermArena::<4>::new();
1648///
1649/// // Push leaves first:
1650/// let idx_3 = arena.push(uor_foundation::pipeline::literal_u64(3, WittLevel::W8));
1651/// let idx_5 = arena.push(uor_foundation::pipeline::literal_u64(5, WittLevel::W8));
1652///
1653/// // Push the application node, referencing the leaves by index:
1654/// let idx_add = arena.push(Term::Application {
1655///     operator: PrimitiveOp::Add,
1656///     args: TermList { start: idx_3.unwrap_or(0), len: 2 },
1657/// });
1658///
1659/// assert_eq!(arena.len(), 3);
1660/// // Retrieve a node by index:
1661/// let node = arena.get(idx_add.unwrap_or(0));
1662/// assert!(node.is_some());
1663/// ```
1664#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1665pub struct TermArena<const CAP: usize> {
1666    /// Node storage. `None` slots are unused.
1667    nodes: [Option<Term>; CAP],
1668    /// Number of allocated nodes.
1669    len: u32,
1670}
1671
1672impl<const CAP: usize> TermArena<CAP> {
1673    /// Creates an empty arena.
1674    #[inline]
1675    #[must_use]
1676    pub const fn new() -> Self {
1677        // v0.2.2 T4.5.a: const-stable on MSRV 1.70 via the `[None; CAP]`
1678        // initializer (Term is Copy as of T4.5.a, so Option<Term> is Copy).
1679        Self {
1680            nodes: [None; CAP],
1681            len: 0,
1682        }
1683    }
1684
1685    /// Push a term into the arena and return its index.
1686    /// # Errors
1687    /// Returns `None` if the arena is full.
1688    #[must_use]
1689    pub fn push(&mut self, term: Term) -> Option<u32> {
1690        let idx = self.len;
1691        if (idx as usize) >= CAP {
1692            return None;
1693        }
1694        self.nodes[idx as usize] = Some(term);
1695        self.len = idx + 1;
1696        Some(idx)
1697    }
1698
1699    /// Returns a reference to the term at `index`, or `None` if out of bounds.
1700    #[inline]
1701    #[must_use]
1702    pub fn get(&self, index: u32) -> Option<&Term> {
1703        self.nodes
1704            .get(index as usize)
1705            .and_then(|slot| slot.as_ref())
1706    }
1707
1708    /// Returns the number of allocated nodes.
1709    #[inline]
1710    #[must_use]
1711    pub const fn len(&self) -> u32 {
1712        self.len
1713    }
1714
1715    /// Returns `true` if the arena has no allocated nodes.
1716    #[inline]
1717    #[must_use]
1718    pub const fn is_empty(&self) -> bool {
1719        self.len == 0
1720    }
1721
1722    /// v0.2.2 T4.5.b: returns the populated prefix of the arena as a slice.
1723    /// Each entry is `Some(term)` for the populated indices `0..len()`;
1724    /// downstream consumers index into this slice via `TermList::start` and
1725    /// `TermList::len` to walk the children of an Application/Match node.
1726    #[inline]
1727    #[must_use]
1728    pub fn as_slice(&self) -> &[Option<Term>] {
1729        &self.nodes[..self.len as usize]
1730    }
1731
1732    /// Wiki ADR-022 D2: const constructor that copies a static term slice
1733    /// into the arena. Used by the `prism_model!` proc-macro to emit a
1734    /// `const ROUTE: TermArena<CAP> = TermArena::from_slice(ROUTE_SLICE)`
1735    /// declaration alongside the model — the `const ROUTE_SLICE` carrying
1736    /// the term tree, this `from_slice` wrapping it into the arena form
1737    /// [`crate::pipeline::run_route`] consumes.
1738    /// `CAP` MUST be at least `slice.len()`; if the slice exceeds the
1739    /// arena's capacity the trailing terms are silently dropped (the
1740    /// `prism_model!` macro emits an arena sized to fit the route's term
1741    /// count plus headroom, so this case is unreachable from the macro's
1742    /// output).
1743    #[inline]
1744    #[must_use]
1745    pub const fn from_slice(slice: &'static [Term]) -> Self {
1746        let mut nodes: [Option<Term>; CAP] = [None; CAP];
1747        let mut i = 0usize;
1748        while i < slice.len() && i < CAP {
1749            nodes[i] = Some(slice[i]);
1750            i += 1;
1751        }
1752        // Cap at min(slice.len(), CAP) so a too-large slice doesn't
1753        // overrun. The macro emits arena CAP >= slice.len() so the
1754        // truncation branch is unreachable in practice.
1755        #[allow(clippy::cast_possible_truncation)]
1756        let len = if slice.len() > CAP {
1757            CAP as u32
1758        } else {
1759            slice.len() as u32
1760        };
1761        Self { nodes, len }
1762    }
1763}
1764
1765impl<const CAP: usize> Default for TermArena<CAP> {
1766    fn default() -> Self {
1767        Self::new()
1768    }
1769}
1770
1771/// Concrete AST node for the UOR term language.
1772/// Mirrors the EBNF grammar productions. All child references are
1773/// indices into a `TermArena`, keeping the AST stack-resident and
1774/// `#![no_std]`-safe.
1775/// # Examples
1776/// ```rust
1777/// use uor_foundation::enforcement::{Term, TermList};
1778/// use uor_foundation::{WittLevel, PrimitiveOp};
1779///
1780/// // Literal: an integer value tagged with a Witt level.
1781/// let lit = uor_foundation::pipeline::literal_u64(42, WittLevel::W8);
1782///
1783/// // Application: an operation applied to arguments.
1784/// // `args` is a TermList { start, len } pointing into a TermArena.
1785/// let app = Term::Application {
1786///     operator: PrimitiveOp::Mul,
1787///     args: TermList { start: 0, len: 2 },
1788/// };
1789///
1790/// // Lift: canonical injection from a lower to a higher Witt level.
1791/// let lift = Term::Lift { operand_index: 0, target: WittLevel::new(32) };
1792///
1793/// // Project: canonical surjection from a higher to a lower level.
1794/// let proj = Term::Project { operand_index: 0, target: WittLevel::W8 };
1795/// ```
1796#[allow(clippy::large_enum_variant)]
1797#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1798pub enum Term {
1799    /// Integer literal with Witt level annotation. Per ADR-051 the value
1800    /// carrier is a `TermValue` byte sequence whose length matches the declared
1801    /// `level`'s byte width. Use `uor_foundation::pipeline::literal_u64(value, level)`
1802    /// to construct a literal from a `u64` value (the narrow form).
1803    Literal {
1804        /// The literal value as a byte sequence (ADR-051). Length equals
1805        /// `level.witt_length() / 8`. Wider widths (W128, W256, …) are
1806        /// natively representable without `Concat` composition.
1807        value: crate::pipeline::TermValue,
1808        /// The Witt level of this literal.
1809        level: WittLevel,
1810    },
1811    /// Variable reference by name index.
1812    Variable {
1813        /// Index into the name table.
1814        name_index: u32,
1815    },
1816    /// Operation application: operator applied to arguments.
1817    Application {
1818        /// The primitive operation to apply.
1819        operator: PrimitiveOp,
1820        /// Argument list (indices into arena).
1821        args: TermList,
1822    },
1823    /// Lift: canonical injection W_n to W_m (n < m, lossless).
1824    Lift {
1825        /// Index of the operand term in the arena.
1826        operand_index: u32,
1827        /// Target Witt level.
1828        target: WittLevel,
1829    },
1830    /// Project: canonical surjection W_m to W_n (m > n, lossy).
1831    Project {
1832        /// Index of the operand term in the arena.
1833        operand_index: u32,
1834        /// Target Witt level.
1835        target: WittLevel,
1836    },
1837    /// Match expression with pattern-result pairs.
1838    Match {
1839        /// Index of the scrutinee term in the arena.
1840        scrutinee_index: u32,
1841        /// Match arms (indices into arena).
1842        arms: TermList,
1843    },
1844    /// Bounded recursion with descent measure.
1845    Recurse {
1846        /// Index of the descent measure term.
1847        measure_index: u32,
1848        /// Index of the base case term.
1849        base_index: u32,
1850        /// Index of the recursive step term.
1851        step_index: u32,
1852    },
1853    /// Stream construction via unfold.
1854    Unfold {
1855        /// Index of the seed term.
1856        seed_index: u32,
1857        /// Index of the step function term.
1858        step_index: u32,
1859    },
1860    /// Try expression with failure recovery.
1861    Try {
1862        /// Index of the body term.
1863        body_index: u32,
1864        /// Index of the handler term.
1865        handler_index: u32,
1866    },
1867    /// Substitution-axis-realized verb projection (wiki ADR-029 + ADR-030).
1868    /// Delegates evaluation to the application's `AxisTuple` substitution-axis
1869    /// impl: the catamorphism evaluates the input subtree, dispatches the
1870    /// axis at `axis_index` to the kernel identified by `kernel_id`, and
1871    /// emits the kernel's output as the result. Emitted by
1872    /// `prism_model!` from the closure-body form `hash(input)` (ADR-026 G19,
1873    /// which lowers to AxisInvocation against the application's HashAxis).
1874    AxisInvocation {
1875        /// Position of the axis in the application's `AxisTuple`.
1876        axis_index: u32,
1877        /// Per-axis kernel id (the SDK macro emits per-method `KERNEL_*` consts).
1878        kernel_id: u32,
1879        /// Input subtree's arena index (single input — current axes are 1-arg).
1880        input_index: u32,
1881    },
1882    /// Field-access projection over a partition_product input (wiki
1883    /// ADR-033 G20). The catamorphism's fold-rule evaluates `source`
1884    /// and slices `[byte_offset .. byte_offset + byte_length]` from
1885    /// the resulting bytes. Emitted by `prism_model!` and `verb!`
1886    /// from the closure-body forms `<expr>.<index>` and
1887    /// `<expr>.<field_name>` (named-field access requires the
1888    /// `partition_product!` declaration to use the named-field form).
1889    /// Coproduct field-access is rejected at macro-expansion time.
1890    ProjectField {
1891        /// Arena index of the source expression's term tree.
1892        source_index: u32,
1893        /// Byte offset into the source's evaluated bytes (proc-
1894        /// macro-computed from factor MAX_BYTES).
1895        byte_offset: u32,
1896        /// Length of the projected slice in bytes.
1897        byte_length: u32,
1898    },
1899    /// Bounded search with structural early termination (wiki ADR-034).
1900    /// The catamorphism iterates `idx` from 0 up to (but excluding) the
1901    /// evaluated `domain_size`; for each iteration it evaluates
1902    /// `predicate` with `FIRST_ADMIT_IDX_NAME_INDEX` bound to `idx`.
1903    /// On the first non-zero predicate result the fold emits the
1904    /// coproduct value `(0x01, idx_bytes)` and terminates iteration; if
1905    /// no `idx` admits, the fold emits `(0x00, idx-width zero bytes)`.
1906    /// Emitted by `prism_model!` and `verb!` from the closure-body
1907    /// form `first_admit(<DomainTy>, |idx| <pred>)` (ADR-026 G16; the
1908    /// lowering target shifted from `Term::Recurse` to `Term::FirstAdmit`
1909    /// per ADR-034's structural-search commitment).
1910    FirstAdmit {
1911        /// Arena index of the domain-cardinality term (typically a
1912        /// `Term::Literal` carrying `<DomainTy as ConstrainedTypeShape>::CYCLE_SIZE`).
1913        domain_size_index: u32,
1914        /// Arena index of the predicate body. Evaluation visits
1915        /// `predicate` with `FIRST_ADMIT_IDX_NAME_INDEX` bound to the
1916        /// current candidate `idx`.
1917        predicate_index: u32,
1918    },
1919    /// ψ_1 (wiki ADR-035): nerve construction — Constraints → SimplicialComplex.
1920    /// Lowered from the closure-body form `nerve(<value_expr>)` (G21).
1921    /// Resolver-bound: consults the ResolverTuple's NerveResolver per ADR-036.
1922    Nerve {
1923        /// Arena index of the value-bytes operand (typically a
1924        /// `Term::Variable` for the route input or a `Term::ProjectField`).
1925        value_index: u32,
1926    },
1927    /// ψ_2 (wiki ADR-035): chain functor — SimplicialComplex → ChainComplex.
1928    /// Lowered from `chain_complex(<simplicial_expr>)` (G22).
1929    /// Resolver-bound: ChainComplexResolver per ADR-036.
1930    ChainComplex { simplicial_index: u32 },
1931    /// ψ_3 (wiki ADR-035): homology functor — ChainComplex → HomologyGroups.
1932    /// `H_k(C) = ker(∂_k) / im(∂_{k+1})`.
1933    /// Lowered from `homology_groups(<chain_expr>)` (G23).
1934    /// Resolver-bound: HomologyGroupResolver per ADR-036.
1935    HomologyGroups { chain_index: u32 },
1936    /// ψ_4 (wiki ADR-035): Betti-number extraction — HomologyGroups → BettiNumbers.
1937    /// Pure computation on resolved homology groups; no resolver consultation.
1938    /// Lowered from `betti(<homology_expr>)` (G24).
1939    Betti { homology_index: u32 },
1940    /// ψ_5 (wiki ADR-035): dualization functor — ChainComplex → CochainComplex.
1941    /// `C^k = Hom(C_k, R)`.
1942    /// Lowered from `cochain_complex(<chain_expr>)` (G25).
1943    /// Resolver-bound: CochainComplexResolver per ADR-036.
1944    CochainComplex { chain_index: u32 },
1945    /// ψ_6 (wiki ADR-035): cohomology functor — CochainComplex → CohomologyGroups.
1946    /// `H^k(C) = ker(δ^k) / im(δ^{k-1})`.
1947    /// Lowered from `cohomology_groups(<cochain_expr>)` (G26).
1948    /// Resolver-bound: CohomologyGroupResolver per ADR-036.
1949    CohomologyGroups { cochain_index: u32 },
1950    /// ψ_7 (wiki ADR-035): Kan-completion + Postnikov truncation —
1951    /// SimplicialComplex → PostnikovTower. The PostnikovResolver performs
1952    /// the Kan-completion internally; verb authors do not need to construct
1953    /// KanComplex values explicitly.
1954    /// Lowered from `postnikov_tower(<simplicial_expr>)` (G27).
1955    /// Resolver-bound: PostnikovResolver per ADR-036.
1956    PostnikovTower { simplicial_index: u32 },
1957    /// ψ_8 (wiki ADR-035): homotopy extraction — PostnikovTower → HomotopyGroups.
1958    /// π_k from each truncation stage.
1959    /// Lowered from `homotopy_groups(<postnikov_expr>)` (G28).
1960    /// Resolver-bound: HomotopyGroupResolver per ADR-036.
1961    HomotopyGroups { postnikov_index: u32 },
1962    /// ψ_9 (wiki ADR-035): k-invariant computation — HomotopyGroups → KInvariants.
1963    /// κ_k classifying the Postnikov tower.
1964    /// Lowered from `k_invariants(<homotopy_expr>)` (G29).
1965    /// Resolver-bound: KInvariantResolver per ADR-036.
1966    KInvariants { homotopy_index: u32 },
1967}
1968
1969/// Wiki ADR-024 verb-graph compile-time inlining: shift the arena-index
1970/// fields of `term` by `offset`. Used by [`inline_verb_fragment`] to
1971/// inline a verb's term-tree fragment into a host arena at compile time.
1972/// `Term::Variable`'s `name_index` is a binding-name reference (not an
1973/// arena index) and is preserved unchanged. `Term::Try`'s `handler_index`
1974/// is preserved unchanged when it equals `u32::MAX` (the default-
1975/// propagation sentinel per ADR-022 D3 G9).
1976#[must_use]
1977pub const fn shift_term(term: Term, offset: u32) -> Term {
1978    match term {
1979        Term::Literal { value, level } => Term::Literal { value, level },
1980        // name_index is a binding-name reference, not an arena index.
1981        Term::Variable { name_index } => Term::Variable { name_index },
1982        Term::Application { operator, args } => Term::Application {
1983            operator,
1984            args: TermList {
1985                start: args.start + offset,
1986                len: args.len,
1987            },
1988        },
1989        Term::Lift {
1990            operand_index,
1991            target,
1992        } => Term::Lift {
1993            operand_index: operand_index + offset,
1994            target,
1995        },
1996        Term::Project {
1997            operand_index,
1998            target,
1999        } => Term::Project {
2000            operand_index: operand_index + offset,
2001            target,
2002        },
2003        Term::Match {
2004            scrutinee_index,
2005            arms,
2006        } => Term::Match {
2007            scrutinee_index: scrutinee_index + offset,
2008            arms: TermList {
2009                start: arms.start + offset,
2010                len: arms.len,
2011            },
2012        },
2013        Term::Recurse {
2014            measure_index,
2015            base_index,
2016            step_index,
2017        } => Term::Recurse {
2018            measure_index: measure_index + offset,
2019            base_index: base_index + offset,
2020            step_index: step_index + offset,
2021        },
2022        Term::Unfold {
2023            seed_index,
2024            step_index,
2025        } => Term::Unfold {
2026            seed_index: seed_index + offset,
2027            step_index: step_index + offset,
2028        },
2029        Term::Try {
2030            body_index,
2031            handler_index,
2032        } => Term::Try {
2033            body_index: body_index + offset,
2034            handler_index: if handler_index == u32::MAX {
2035                u32::MAX
2036            } else {
2037                handler_index + offset
2038            },
2039        },
2040        Term::AxisInvocation {
2041            axis_index,
2042            kernel_id,
2043            input_index,
2044        } => Term::AxisInvocation {
2045            axis_index,
2046            kernel_id,
2047            input_index: input_index + offset,
2048        },
2049        Term::ProjectField {
2050            source_index,
2051            byte_offset,
2052            byte_length,
2053        } => Term::ProjectField {
2054            source_index: source_index + offset,
2055            byte_offset,
2056            byte_length,
2057        },
2058        Term::FirstAdmit {
2059            domain_size_index,
2060            predicate_index,
2061        } => Term::FirstAdmit {
2062            domain_size_index: domain_size_index + offset,
2063            predicate_index: predicate_index + offset,
2064        },
2065        Term::Nerve { value_index } => Term::Nerve {
2066            value_index: value_index + offset,
2067        },
2068        Term::ChainComplex { simplicial_index } => Term::ChainComplex {
2069            simplicial_index: simplicial_index + offset,
2070        },
2071        Term::HomologyGroups { chain_index } => Term::HomologyGroups {
2072            chain_index: chain_index + offset,
2073        },
2074        Term::Betti { homology_index } => Term::Betti {
2075            homology_index: homology_index + offset,
2076        },
2077        Term::CochainComplex { chain_index } => Term::CochainComplex {
2078            chain_index: chain_index + offset,
2079        },
2080        Term::CohomologyGroups { cochain_index } => Term::CohomologyGroups {
2081            cochain_index: cochain_index + offset,
2082        },
2083        Term::PostnikovTower { simplicial_index } => Term::PostnikovTower {
2084            simplicial_index: simplicial_index + offset,
2085        },
2086        Term::HomotopyGroups { postnikov_index } => Term::HomotopyGroups {
2087            postnikov_index: postnikov_index + offset,
2088        },
2089        Term::KInvariants { homotopy_index } => Term::KInvariants {
2090            homotopy_index: homotopy_index + offset,
2091        },
2092    }
2093}
2094
2095/// Wiki ADR-024 compile-time verb-fragment inlining helper.
2096/// Copies the verb `fragment` slice into `buf` starting at `len` while applying
2097/// two simultaneous transformations per term so the verb body becomes part of
2098/// the calling route's flat arena: Variable(0) substitution (the verb's `input`
2099/// parameter binds to the caller's argument expression by replacing each
2100/// `Variable { name_index: 0 }` with a copy of `buf[arg_root_idx]`), and arena-
2101/// index shifting (every non-Variable(0) term has its arena-index fields shifted
2102/// by `len` so internal references resolve correctly within the host).
2103/// The combined transformation realises ADR-024's compile-time inlining: the
2104/// verb body lands in the host arena with its `input` bound to the caller's
2105/// argument expression — verb-graph acyclicity is checked at const-eval time,
2106/// no `Term::VerbReference` variant or runtime depth guard is required.
2107/// # Panics
2108/// Panics at const-eval time if `len + fragment.len() > CAP` or if
2109/// `arg_root_idx as usize >= len`.
2110#[must_use]
2111pub const fn inline_verb_fragment<const CAP: usize>(
2112    mut buf: [Term; CAP],
2113    mut len: usize,
2114    fragment: &[Term],
2115    arg_root_idx: u32,
2116) -> ([Term; CAP], usize) {
2117    let offset = len as u32;
2118    // Capture a copy of the caller's argument root term; `Variable { name_index: 0 }`
2119    // occurrences in the fragment are replaced by this copy per ADR-024.
2120    let arg_root_term = buf[arg_root_idx as usize];
2121    let mut i = 0;
2122    while i < fragment.len() {
2123        let term = fragment[i];
2124        let new_term = match term {
2125            Term::Variable { name_index: 0 } => arg_root_term,
2126            other => shift_term(other, offset),
2127        };
2128        buf[len] = new_term;
2129        len += 1;
2130        i += 1;
2131    }
2132    (buf, len)
2133}
2134
2135/// A type declaration with constraint kinds.
2136#[derive(Debug, Clone, PartialEq, Eq)]
2137pub struct TypeDeclaration {
2138    /// Name index for this type.
2139    pub name_index: u32,
2140    /// Constraint terms (indices into arena).
2141    pub constraints: TermList,
2142}
2143
2144/// A named binding: `let name : Type = term`.
2145#[derive(Debug, Clone, PartialEq, Eq)]
2146pub struct Binding {
2147    /// Name index for this binding.
2148    pub name_index: u32,
2149    /// Index of the type declaration.
2150    pub type_index: u32,
2151    /// Index of the value term in the arena.
2152    pub value_index: u32,
2153    /// EBNF surface syntax (compile-time constant).
2154    pub surface: &'static str,
2155    /// FNV-1a content address (compile-time constant).
2156    pub content_address: u64,
2157}
2158
2159impl Binding {
2160    /// v0.2.2 Phase P.3: lift this binding to the `BindingEntry` shape consumed by
2161    /// `BindingsTable`. `address` is derived from `content_address` via
2162    /// `ContentAddress::from_u64_fingerprint`; `bytes` re-uses the `surface` slice.
2163    /// Content-deterministic; const-compatible since all fields are `'static`.
2164    #[inline]
2165    #[must_use]
2166    pub const fn to_binding_entry(&self) -> BindingEntry {
2167        BindingEntry {
2168            address: ContentAddress::from_u64_fingerprint(self.content_address),
2169            bytes: self.surface.as_bytes(),
2170        }
2171    }
2172}
2173
2174/// An assertion: `assert lhs = rhs`.
2175#[derive(Debug, Clone, PartialEq, Eq)]
2176pub struct Assertion {
2177    /// Index of the left-hand side term.
2178    pub lhs_index: u32,
2179    /// Index of the right-hand side term.
2180    pub rhs_index: u32,
2181    /// EBNF surface syntax (compile-time constant).
2182    pub surface: &'static str,
2183}
2184
2185/// Boundary source declaration: `source name : Type via grounding`.
2186#[derive(Debug, Clone, PartialEq, Eq)]
2187pub struct SourceDeclaration {
2188    /// Name index for the source.
2189    pub name_index: u32,
2190    /// Index of the type declaration.
2191    pub type_index: u32,
2192    /// Name index of the grounding map.
2193    pub grounding_name_index: u32,
2194}
2195
2196/// Boundary sink declaration: `sink name : Type via projection`.
2197#[derive(Debug, Clone, PartialEq, Eq)]
2198pub struct SinkDeclaration {
2199    /// Name index for the sink.
2200    pub name_index: u32,
2201    /// Index of the type declaration.
2202    pub type_index: u32,
2203    /// Name index of the projection map.
2204    pub projection_name_index: u32,
2205}
2206
2207/// Structured violation diagnostic carrying metadata from the
2208/// conformance namespace. Every field is machine-readable.
2209/// # Examples
2210/// ```rust
2211/// use uor_foundation::enforcement::ShapeViolation;
2212/// use uor_foundation::ViolationKind;
2213///
2214/// // ShapeViolation carries structured metadata from the ontology.
2215/// // Every field is machine-readable — IRIs, counts, and a typed kind.
2216/// let violation = ShapeViolation {
2217///     shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2218///     constraint_iri: "https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
2219///     property_iri: "https://uor.foundation/reduction/rootTerm",
2220///     expected_range: "https://uor.foundation/schema/Term",
2221///     min_count: 1,
2222///     max_count: 1,
2223///     kind: ViolationKind::Missing,
2224/// };
2225///
2226/// // Machine-readable for tooling (IDE plugins, CI pipelines):
2227/// assert_eq!(violation.kind, ViolationKind::Missing);
2228/// assert!(violation.shape_iri.ends_with("CompileUnitShape"));
2229/// assert_eq!(violation.min_count, 1);
2230/// ```
2231#[derive(Debug, Clone, PartialEq, Eq)]
2232pub struct ShapeViolation {
2233    /// IRI of the `conformance:Shape` that was validated against.
2234    pub shape_iri: &'static str,
2235    /// IRI of the specific `conformance:PropertyConstraint` that failed.
2236    pub constraint_iri: &'static str,
2237    /// IRI of the property that was missing or invalid.
2238    pub property_iri: &'static str,
2239    /// The expected range class IRI.
2240    pub expected_range: &'static str,
2241    /// Minimum cardinality from the constraint.
2242    pub min_count: u32,
2243    /// Maximum cardinality (0 = unbounded).
2244    pub max_count: u32,
2245    /// What went wrong.
2246    pub kind: ViolationKind,
2247}
2248
2249impl core::fmt::Display for ShapeViolation {
2250    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2251        write!(
2252            f,
2253            "shape violation: {} (constraint {}, property {}, kind {:?})",
2254            self.shape_iri, self.constraint_iri, self.property_iri, self.kind,
2255        )
2256    }
2257}
2258
2259impl core::error::Error for ShapeViolation {}
2260
2261impl ShapeViolation {
2262    /// Phase C.3: returns the shape IRI as a `&'static str` suitable for
2263    /// `const fn` panic messages. The IRI uniquely identifies the violated
2264    /// constraint in the conformance catalog.
2265    #[inline]
2266    #[must_use]
2267    pub const fn const_message(&self) -> &'static str {
2268        self.shape_iri
2269    }
2270}
2271
2272/// Builder for `CompileUnit` admission into the reduction pipeline.
2273/// Collects `rootTerm`, `wittLevelCeiling`, `thermodynamicBudget`,
2274/// and `targetDomains`. The `validate()` method checks structural
2275/// constraints (Tier 1) and value-dependent constraints (Tier 2).
2276/// # Examples
2277/// ```rust
2278/// use uor_foundation::enforcement::{CompileUnitBuilder, ConstrainedTypeInput, Term};
2279/// use uor_foundation::{WittLevel, VerificationDomain, ViolationKind};
2280///
2281/// // A CompileUnit packages a term graph for reduction admission.
2282/// // The builder enforces that all required fields are present.
2283/// let terms = [uor_foundation::pipeline::literal_u64(1, WittLevel::W8)];
2284/// let domains = [VerificationDomain::Enumerative];
2285///
2286/// let unit = CompileUnitBuilder::new()
2287///     .root_term(&terms)
2288///     .witt_level_ceiling(WittLevel::W8)
2289///     .thermodynamic_budget(1024)
2290///     .target_domains(&domains)
2291///     .result_type::<ConstrainedTypeInput>()
2292///     .validate();
2293/// assert!(unit.is_ok());
2294///
2295/// // Omitting a required field produces a ShapeViolation
2296/// // with the exact conformance IRI that failed:
2297/// let err = CompileUnitBuilder::new()
2298///     .witt_level_ceiling(WittLevel::W8)
2299///     .thermodynamic_budget(1024)
2300///     .target_domains(&domains)
2301///     .result_type::<ConstrainedTypeInput>()
2302///     .validate();
2303/// assert!(err.is_err());
2304/// if let Err(violation) = err {
2305///     assert_eq!(violation.kind, ViolationKind::Missing);
2306///     assert!(violation.property_iri.contains("rootTerm"));
2307/// }
2308/// ```
2309#[derive(Debug, Clone)]
2310pub struct CompileUnitBuilder<'a> {
2311    /// The root term expression.
2312    root_term: Option<&'a [Term]>,
2313    /// v0.2.2 Phase H1: named bindings (`let name : Type = term` forms)
2314    /// declared by the compile unit. Stage 5 extracts these into a `BindingsTable`
2315    /// for grounding-aware and session resolvers; an empty slice declares no bindings.
2316    bindings: Option<&'a [Binding]>,
2317    /// The widest Witt level the computation may reference.
2318    witt_level_ceiling: Option<WittLevel>,
2319    /// Landauer-bounded energy budget.
2320    thermodynamic_budget: Option<u64>,
2321    /// Verification domains targeted.
2322    target_domains: Option<&'a [VerificationDomain]>,
2323    /// v0.2.2 T6.11: result-type IRI for ShapeMismatch detection.
2324    /// Set via `result_type::<T: ConstrainedTypeShape>()`. Required by
2325    /// `validate()` and `validate_compile_unit_const`. The pipeline checks
2326    /// `unit.result_type_iri() == T::IRI` at `pipeline::run` invocation
2327    /// time, returning `PipelineFailure::ShapeMismatch` on mismatch.
2328    result_type_iri: Option<&'static str>,
2329}
2330
2331/// A validated compile unit ready for reduction admission.
2332/// v0.2.2 Phase A (carrier widening): the lifetime parameter `'a` ties
2333/// the post-validation carrier to its builder's borrow. The `root_term`
2334/// and `target_domains` slices are retained through validation so
2335/// resolvers can inspect declared structure — previously these fields
2336/// were discarded at `validate()` and every resolver received a
2337/// 3-field scalar witness with no walkable structure.
2338/// Const-constructed compile units use the trivial specialization
2339/// `CompileUnit<'static>` — borrow-free and usable in const contexts.
2340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2341pub struct CompileUnit<'a> {
2342    /// The Witt level ceiling.
2343    level: WittLevel,
2344    /// The thermodynamic budget.
2345    budget: u64,
2346    /// v0.2.2 T6.11: result-type IRI. The pipeline matches this against
2347    /// the caller's `T::IRI` to detect shape mismatches.
2348    result_type_iri: &'static str,
2349    /// v0.2.2 Phase A: root term expression, retained from the builder.
2350    /// Stage 5 (extract bindings) and the grounding-aware resolver walk
2351    /// this slice. Empty slice for the trivial `CompileUnit<'static>`
2352    /// specialization produced by builders that don't carry a term AST.
2353    root_term: &'a [Term],
2354    /// v0.2.2 Phase H1: named bindings retained from the builder. Consumed by Stage 5
2355    /// (`bindings_from_unit`) to materialize the `BindingsTable` for grounding-aware,
2356    /// session, and superposition resolvers. Empty slice declares no bindings.
2357    bindings: &'a [Binding],
2358    /// v0.2.2 Phase A: verification domains targeted, retained from the builder.
2359    target_domains: &'a [VerificationDomain],
2360}
2361
2362impl<'a> CompileUnit<'a> {
2363    /// Returns the Witt level ceiling declared at validation time.
2364    #[inline]
2365    #[must_use]
2366    pub const fn witt_level(&self) -> WittLevel {
2367        self.level
2368    }
2369
2370    /// Returns the thermodynamic budget declared at validation time.
2371    #[inline]
2372    #[must_use]
2373    pub const fn thermodynamic_budget(&self) -> u64 {
2374        self.budget
2375    }
2376
2377    /// v0.2.2 T6.11: returns the result-type IRI declared at validation
2378    /// time. The pipeline matches this against the caller's `T::IRI` to
2379    /// detect shape mismatches.
2380    #[inline]
2381    #[must_use]
2382    pub const fn result_type_iri(&self) -> &'static str {
2383        self.result_type_iri
2384    }
2385
2386    /// v0.2.2 Phase A: returns the root term slice declared at validation time.
2387    /// Empty for builders that did not supply a term AST.
2388    #[inline]
2389    #[must_use]
2390    pub const fn root_term(&self) -> &'a [Term] {
2391        self.root_term
2392    }
2393
2394    /// v0.2.2 Phase H1: returns the named bindings declared at validation time.
2395    /// Consumed by Stage 5 (`bindings_from_unit`) to materialize the `BindingsTable`.
2396    /// Empty slice for compile units that declare no bindings.
2397    #[inline]
2398    #[must_use]
2399    pub const fn bindings(&self) -> &'a [Binding] {
2400        self.bindings
2401    }
2402
2403    /// v0.2.2 Phase A: returns the verification domains declared at validation time.
2404    #[inline]
2405    #[must_use]
2406    pub const fn target_domains(&self) -> &'a [VerificationDomain] {
2407        self.target_domains
2408    }
2409
2410    /// v0.2.2 Phase G / T2.8 + T6.11: const-constructible parts form used
2411    /// by `validate_compile_unit_const` — the const-fn path reads the
2412    /// builder's fields and packs them into the `Validated` result.
2413    /// v0.2.2 Phase H1: bindings slice is retained alongside root_term;
2414    /// empty slice declares no bindings.
2415    #[inline]
2416    #[must_use]
2417    pub(crate) const fn from_parts_const(
2418        level: WittLevel,
2419        budget: u64,
2420        result_type_iri: &'static str,
2421        root_term: &'a [Term],
2422        bindings: &'a [Binding],
2423        target_domains: &'a [VerificationDomain],
2424    ) -> Self {
2425        Self {
2426            level,
2427            budget,
2428            result_type_iri,
2429            root_term,
2430            bindings,
2431            target_domains,
2432        }
2433    }
2434}
2435
2436impl<'a> CompileUnitBuilder<'a> {
2437    /// Creates a new empty builder.
2438    #[must_use]
2439    pub const fn new() -> Self {
2440        Self {
2441            root_term: None,
2442            bindings: None,
2443            witt_level_ceiling: None,
2444            thermodynamic_budget: None,
2445            target_domains: None,
2446            result_type_iri: None,
2447        }
2448    }
2449
2450    /// Set the root term expression.
2451    #[must_use]
2452    pub const fn root_term(mut self, terms: &'a [Term]) -> Self {
2453        self.root_term = Some(terms);
2454        self
2455    }
2456
2457    /// v0.2.2 Phase H1: set the named bindings declared by this compile unit.
2458    /// Consumed by Stage 5 (`bindings_from_unit`) to materialize the
2459    /// `BindingsTable` for grounding-aware, session, and superposition resolvers.
2460    /// Omit for compile units without bindings; the default is the empty slice.
2461    #[must_use]
2462    pub const fn bindings(mut self, bindings: &'a [Binding]) -> Self {
2463        self.bindings = Some(bindings);
2464        self
2465    }
2466
2467    /// Set the Witt level ceiling.
2468    #[must_use]
2469    pub const fn witt_level_ceiling(mut self, level: WittLevel) -> Self {
2470        self.witt_level_ceiling = Some(level);
2471        self
2472    }
2473
2474    /// Set the thermodynamic budget.
2475    #[must_use]
2476    pub const fn thermodynamic_budget(mut self, budget: u64) -> Self {
2477        self.thermodynamic_budget = Some(budget);
2478        self
2479    }
2480
2481    /// Set the target verification domains.
2482    #[must_use]
2483    pub const fn target_domains(mut self, domains: &'a [VerificationDomain]) -> Self {
2484        self.target_domains = Some(domains);
2485        self
2486    }
2487
2488    /// v0.2.2 T6.11: set the result-type IRI from a `ConstrainedTypeShape`
2489    /// type parameter. The pipeline matches this against the caller's
2490    /// `T::IRI` at `pipeline::run` invocation time, returning
2491    /// `PipelineFailure::ShapeMismatch` on mismatch.
2492    /// Required: `validate()` and `validate_compile_unit_const` reject
2493    /// builders without a result type set.
2494    #[must_use]
2495    pub const fn result_type<T: crate::pipeline::ConstrainedTypeShape>(mut self) -> Self {
2496        self.result_type_iri = Some(T::IRI);
2497        self
2498    }
2499
2500    /// v0.2.2 T2.8: const-fn accessor exposing the stored Witt level
2501    /// ceiling (or `None` if unset). Used by `validate_compile_unit_const`.
2502    #[inline]
2503    #[must_use]
2504    pub const fn witt_level_option(&self) -> Option<WittLevel> {
2505        self.witt_level_ceiling
2506    }
2507
2508    /// v0.2.2 T2.8: const-fn accessor exposing the stored thermodynamic
2509    /// budget (or `None` if unset).
2510    #[inline]
2511    #[must_use]
2512    pub const fn budget_option(&self) -> Option<u64> {
2513        self.thermodynamic_budget
2514    }
2515
2516    /// v0.2.2 T6.13: const-fn accessor — `true` iff `root_term` is set.
2517    #[inline]
2518    #[must_use]
2519    pub const fn has_root_term_const(&self) -> bool {
2520        self.root_term.is_some()
2521    }
2522
2523    /// v0.2.2 T6.13: const-fn accessor — `true` iff `target_domains` is
2524    /// set and non-empty.
2525    #[inline]
2526    #[must_use]
2527    pub const fn has_target_domains_const(&self) -> bool {
2528        match self.target_domains {
2529            Some(d) => !d.is_empty(),
2530            None => false,
2531        }
2532    }
2533
2534    /// v0.2.2 T6.13: const-fn accessor exposing the stored result-type IRI
2535    /// (or `None` if unset). Used by `validate_compile_unit_const`.
2536    #[inline]
2537    #[must_use]
2538    pub const fn result_type_iri_const(&self) -> Option<&'static str> {
2539        self.result_type_iri
2540    }
2541
2542    /// v0.2.2 Phase A: const-fn accessor exposing the stored root-term slice,
2543    /// or an empty slice if unset. Used by `validate_compile_unit_const` to
2544    /// propagate the AST into the widened `CompileUnit<'a>` carrier.
2545    #[inline]
2546    #[must_use]
2547    pub const fn root_term_slice_const(&self) -> &'a [Term] {
2548        match self.root_term {
2549            Some(terms) => terms,
2550            None => &[],
2551        }
2552    }
2553
2554    /// v0.2.2 Phase H1: const-fn accessor exposing the stored bindings slice,
2555    /// or an empty slice if unset. Used by `validate_compile_unit_const` to
2556    /// propagate the bindings declaration into the widened `CompileUnit<'a>` carrier.
2557    #[inline]
2558    #[must_use]
2559    pub const fn bindings_slice_const(&self) -> &'a [Binding] {
2560        match self.bindings {
2561            Some(bindings) => bindings,
2562            None => &[],
2563        }
2564    }
2565
2566    /// v0.2.2 Phase A: const-fn accessor exposing the stored target-domains
2567    /// slice, or an empty slice if unset. Used by `validate_compile_unit_const`.
2568    #[inline]
2569    #[must_use]
2570    pub const fn target_domains_slice_const(&self) -> &'a [VerificationDomain] {
2571        match self.target_domains {
2572            Some(d) => d,
2573            None => &[],
2574        }
2575    }
2576
2577    /// Validate against `CompileUnitShape`.
2578    /// Tier 1: checks presence and cardinality of all required fields.
2579    /// Tier 2: checks budget solvency and level coherence.
2580    /// # Errors
2581    /// Returns `ShapeViolation` if any constraint is not satisfied.
2582    pub fn validate(self) -> Result<Validated<CompileUnit<'a>>, ShapeViolation> {
2583        let root_term = match self.root_term {
2584            Some(terms) => terms,
2585            None => {
2586                return Err(ShapeViolation {
2587                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2588                    constraint_iri:
2589                        "https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
2590                    property_iri: "https://uor.foundation/reduction/rootTerm",
2591                    expected_range: "https://uor.foundation/schema/Term",
2592                    min_count: 1,
2593                    max_count: 1,
2594                    kind: ViolationKind::Missing,
2595                })
2596            }
2597        };
2598        let level =
2599            match self.witt_level_ceiling {
2600                Some(l) => l,
2601                None => return Err(ShapeViolation {
2602                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2603                    constraint_iri:
2604                        "https://uor.foundation/conformance/compileUnit_unitWittLevel_constraint",
2605                    property_iri: "https://uor.foundation/reduction/unitWittLevel",
2606                    expected_range: "https://uor.foundation/schema/WittLevel",
2607                    min_count: 1,
2608                    max_count: 1,
2609                    kind: ViolationKind::Missing,
2610                }),
2611            };
2612        let budget = match self.thermodynamic_budget {
2613            Some(b) => b,
2614            None => return Err(ShapeViolation {
2615                shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2616                constraint_iri:
2617                    "https://uor.foundation/conformance/compileUnit_thermodynamicBudget_constraint",
2618                property_iri: "https://uor.foundation/reduction/thermodynamicBudget",
2619                expected_range: "http://www.w3.org/2001/XMLSchema#decimal",
2620                min_count: 1,
2621                max_count: 1,
2622                kind: ViolationKind::Missing,
2623            }),
2624        };
2625        let target_domains =
2626            match self.target_domains {
2627                Some(d) if !d.is_empty() => d,
2628                _ => return Err(ShapeViolation {
2629                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2630                    constraint_iri:
2631                        "https://uor.foundation/conformance/compileUnit_targetDomains_constraint",
2632                    property_iri: "https://uor.foundation/reduction/targetDomains",
2633                    expected_range: "https://uor.foundation/op/VerificationDomain",
2634                    min_count: 1,
2635                    max_count: 0,
2636                    kind: ViolationKind::Missing,
2637                }),
2638            };
2639        let result_type_iri = match self.result_type_iri {
2640            Some(iri) => iri,
2641            None => {
2642                return Err(ShapeViolation {
2643                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2644                    constraint_iri:
2645                        "https://uor.foundation/conformance/compileUnit_resultType_constraint",
2646                    property_iri: "https://uor.foundation/reduction/resultType",
2647                    expected_range: "https://uor.foundation/type/ConstrainedType",
2648                    min_count: 1,
2649                    max_count: 1,
2650                    kind: ViolationKind::Missing,
2651                })
2652            }
2653        };
2654        // v0.2.2 Phase H1: bindings is optional; absent declares no bindings.
2655        let bindings: &'a [Binding] = match self.bindings {
2656            Some(b) => b,
2657            None => &[],
2658        };
2659        Ok(Validated::new(CompileUnit {
2660            level,
2661            budget,
2662            result_type_iri,
2663            root_term,
2664            bindings,
2665            target_domains,
2666        }))
2667    }
2668}
2669
2670impl<'a> Default for CompileUnitBuilder<'a> {
2671    fn default() -> Self {
2672        Self::new()
2673    }
2674}
2675
2676/// Builder for `EffectDeclaration`. Validates against `EffectShape`.
2677#[derive(Debug, Clone)]
2678pub struct EffectDeclarationBuilder<'a> {
2679    /// The `name` field.
2680    name: Option<&'a str>,
2681    /// The `target_sites` field.
2682    target_sites: Option<&'a [u32]>,
2683    /// The `budget_delta` field.
2684    budget_delta: Option<i64>,
2685    /// The `commutes` field.
2686    commutes: Option<bool>,
2687}
2688
2689/// Declared effect validated against `EffectShape`.
2690#[derive(Debug, Clone, PartialEq, Eq)]
2691pub struct EffectDeclaration {
2692    /// Shape IRI this declaration was validated against.
2693    pub shape_iri: &'static str,
2694}
2695
2696impl EffectDeclaration {
2697    /// v0.2.2 Phase G: const-constructible empty form used by
2698    /// `validate_*_const` companion functions.
2699    #[inline]
2700    #[must_use]
2701    #[allow(dead_code)]
2702    pub(crate) const fn empty_const() -> Self {
2703        Self {
2704            shape_iri: "https://uor.foundation/conformance/EffectShape",
2705        }
2706    }
2707}
2708
2709impl<'a> EffectDeclarationBuilder<'a> {
2710    /// Creates a new empty builder.
2711    #[must_use]
2712    pub const fn new() -> Self {
2713        Self {
2714            name: None,
2715            target_sites: None,
2716            budget_delta: None,
2717            commutes: None,
2718        }
2719    }
2720
2721    /// Set the `name` field.
2722    #[must_use]
2723    pub const fn name(mut self, value: &'a str) -> Self {
2724        self.name = Some(value);
2725        self
2726    }
2727
2728    /// Set the `target_sites` field.
2729    #[must_use]
2730    pub const fn target_sites(mut self, value: &'a [u32]) -> Self {
2731        self.target_sites = Some(value);
2732        self
2733    }
2734
2735    /// Set the `budget_delta` field.
2736    #[must_use]
2737    pub const fn budget_delta(mut self, value: i64) -> Self {
2738        self.budget_delta = Some(value);
2739        self
2740    }
2741
2742    /// Set the `commutes` field.
2743    #[must_use]
2744    pub const fn commutes(mut self, value: bool) -> Self {
2745        self.commutes = Some(value);
2746        self
2747    }
2748
2749    /// Validate against `EffectShape`.
2750    /// # Errors
2751    /// Returns `ShapeViolation` if any required field is missing.
2752    pub fn validate(self) -> Result<Validated<EffectDeclaration>, ShapeViolation> {
2753        if self.name.is_none() {
2754            return Err(ShapeViolation {
2755                shape_iri: "https://uor.foundation/conformance/EffectShape",
2756                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2757                property_iri: "https://uor.foundation/conformance/name",
2758                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2759                min_count: 1,
2760                max_count: 1,
2761                kind: ViolationKind::Missing,
2762            });
2763        }
2764        if self.target_sites.is_none() {
2765            return Err(ShapeViolation {
2766                shape_iri: "https://uor.foundation/conformance/EffectShape",
2767                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2768                property_iri: "https://uor.foundation/conformance/target_sites",
2769                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2770                min_count: 1,
2771                max_count: 1,
2772                kind: ViolationKind::Missing,
2773            });
2774        }
2775        if self.budget_delta.is_none() {
2776            return Err(ShapeViolation {
2777                shape_iri: "https://uor.foundation/conformance/EffectShape",
2778                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2779                property_iri: "https://uor.foundation/conformance/budget_delta",
2780                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2781                min_count: 1,
2782                max_count: 1,
2783                kind: ViolationKind::Missing,
2784            });
2785        }
2786        if self.commutes.is_none() {
2787            return Err(ShapeViolation {
2788                shape_iri: "https://uor.foundation/conformance/EffectShape",
2789                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2790                property_iri: "https://uor.foundation/conformance/commutes",
2791                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2792                min_count: 1,
2793                max_count: 1,
2794                kind: ViolationKind::Missing,
2795            });
2796        }
2797        Ok(Validated::new(EffectDeclaration {
2798            shape_iri: "https://uor.foundation/conformance/EffectShape",
2799        }))
2800    }
2801
2802    /// Phase C.1: const-fn companion for `EffectDeclarationBuilder::validate`.
2803    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
2804    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
2805    /// # Errors
2806    /// Returns `ShapeViolation` if any required field is missing.
2807    pub const fn validate_const(
2808        &self,
2809    ) -> Result<Validated<EffectDeclaration, CompileTime>, ShapeViolation> {
2810        if self.name.is_none() {
2811            return Err(ShapeViolation {
2812                shape_iri: "https://uor.foundation/conformance/EffectShape",
2813                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2814                property_iri: "https://uor.foundation/conformance/name",
2815                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2816                min_count: 1,
2817                max_count: 1,
2818                kind: ViolationKind::Missing,
2819            });
2820        }
2821        if self.target_sites.is_none() {
2822            return Err(ShapeViolation {
2823                shape_iri: "https://uor.foundation/conformance/EffectShape",
2824                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2825                property_iri: "https://uor.foundation/conformance/target_sites",
2826                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2827                min_count: 1,
2828                max_count: 1,
2829                kind: ViolationKind::Missing,
2830            });
2831        }
2832        if self.budget_delta.is_none() {
2833            return Err(ShapeViolation {
2834                shape_iri: "https://uor.foundation/conformance/EffectShape",
2835                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2836                property_iri: "https://uor.foundation/conformance/budget_delta",
2837                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2838                min_count: 1,
2839                max_count: 1,
2840                kind: ViolationKind::Missing,
2841            });
2842        }
2843        if self.commutes.is_none() {
2844            return Err(ShapeViolation {
2845                shape_iri: "https://uor.foundation/conformance/EffectShape",
2846                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2847                property_iri: "https://uor.foundation/conformance/commutes",
2848                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2849                min_count: 1,
2850                max_count: 1,
2851                kind: ViolationKind::Missing,
2852            });
2853        }
2854        Ok(Validated::new(EffectDeclaration {
2855            shape_iri: "https://uor.foundation/conformance/EffectShape",
2856        }))
2857    }
2858}
2859
2860impl<'a> Default for EffectDeclarationBuilder<'a> {
2861    fn default() -> Self {
2862        Self::new()
2863    }
2864}
2865
2866/// Builder for `GroundingDeclaration`. Validates against `GroundingShape`.
2867#[derive(Debug, Clone)]
2868pub struct GroundingDeclarationBuilder<'a> {
2869    /// The `source_type` field.
2870    source_type: Option<&'a str>,
2871    /// The `ring_mapping` field.
2872    ring_mapping: Option<&'a str>,
2873    /// The `invertibility` field.
2874    invertibility: Option<bool>,
2875}
2876
2877/// Declared grounding validated against `GroundingShape`.
2878#[derive(Debug, Clone, PartialEq, Eq)]
2879pub struct GroundingDeclaration {
2880    /// Shape IRI this declaration was validated against.
2881    pub shape_iri: &'static str,
2882}
2883
2884impl GroundingDeclaration {
2885    /// v0.2.2 Phase G: const-constructible empty form used by
2886    /// `validate_*_const` companion functions.
2887    #[inline]
2888    #[must_use]
2889    #[allow(dead_code)]
2890    pub(crate) const fn empty_const() -> Self {
2891        Self {
2892            shape_iri: "https://uor.foundation/conformance/GroundingShape",
2893        }
2894    }
2895}
2896
2897impl<'a> GroundingDeclarationBuilder<'a> {
2898    /// Creates a new empty builder.
2899    #[must_use]
2900    pub const fn new() -> Self {
2901        Self {
2902            source_type: None,
2903            ring_mapping: None,
2904            invertibility: None,
2905        }
2906    }
2907
2908    /// Set the `source_type` field.
2909    #[must_use]
2910    pub const fn source_type(mut self, value: &'a str) -> Self {
2911        self.source_type = Some(value);
2912        self
2913    }
2914
2915    /// Set the `ring_mapping` field.
2916    #[must_use]
2917    pub const fn ring_mapping(mut self, value: &'a str) -> Self {
2918        self.ring_mapping = Some(value);
2919        self
2920    }
2921
2922    /// Set the `invertibility` field.
2923    #[must_use]
2924    pub const fn invertibility(mut self, value: bool) -> Self {
2925        self.invertibility = Some(value);
2926        self
2927    }
2928
2929    /// Validate against `GroundingShape`.
2930    /// # Errors
2931    /// Returns `ShapeViolation` if any required field is missing.
2932    pub fn validate(self) -> Result<Validated<GroundingDeclaration>, ShapeViolation> {
2933        if self.source_type.is_none() {
2934            return Err(ShapeViolation {
2935                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2936                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2937                property_iri: "https://uor.foundation/conformance/source_type",
2938                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2939                min_count: 1,
2940                max_count: 1,
2941                kind: ViolationKind::Missing,
2942            });
2943        }
2944        if self.ring_mapping.is_none() {
2945            return Err(ShapeViolation {
2946                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2947                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2948                property_iri: "https://uor.foundation/conformance/ring_mapping",
2949                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2950                min_count: 1,
2951                max_count: 1,
2952                kind: ViolationKind::Missing,
2953            });
2954        }
2955        if self.invertibility.is_none() {
2956            return Err(ShapeViolation {
2957                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2958                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2959                property_iri: "https://uor.foundation/conformance/invertibility",
2960                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2961                min_count: 1,
2962                max_count: 1,
2963                kind: ViolationKind::Missing,
2964            });
2965        }
2966        Ok(Validated::new(GroundingDeclaration {
2967            shape_iri: "https://uor.foundation/conformance/GroundingShape",
2968        }))
2969    }
2970
2971    /// Phase C.1: const-fn companion for `GroundingDeclarationBuilder::validate`.
2972    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
2973    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
2974    /// # Errors
2975    /// Returns `ShapeViolation` if any required field is missing.
2976    pub const fn validate_const(
2977        &self,
2978    ) -> Result<Validated<GroundingDeclaration, CompileTime>, ShapeViolation> {
2979        if self.source_type.is_none() {
2980            return Err(ShapeViolation {
2981                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2982                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2983                property_iri: "https://uor.foundation/conformance/source_type",
2984                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2985                min_count: 1,
2986                max_count: 1,
2987                kind: ViolationKind::Missing,
2988            });
2989        }
2990        if self.ring_mapping.is_none() {
2991            return Err(ShapeViolation {
2992                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2993                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2994                property_iri: "https://uor.foundation/conformance/ring_mapping",
2995                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2996                min_count: 1,
2997                max_count: 1,
2998                kind: ViolationKind::Missing,
2999            });
3000        }
3001        if self.invertibility.is_none() {
3002            return Err(ShapeViolation {
3003                shape_iri: "https://uor.foundation/conformance/GroundingShape",
3004                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
3005                property_iri: "https://uor.foundation/conformance/invertibility",
3006                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3007                min_count: 1,
3008                max_count: 1,
3009                kind: ViolationKind::Missing,
3010            });
3011        }
3012        Ok(Validated::new(GroundingDeclaration {
3013            shape_iri: "https://uor.foundation/conformance/GroundingShape",
3014        }))
3015    }
3016}
3017
3018impl<'a> Default for GroundingDeclarationBuilder<'a> {
3019    fn default() -> Self {
3020        Self::new()
3021    }
3022}
3023
3024/// Builder for `DispatchDeclaration`. Validates against `DispatchShape`.
3025#[derive(Debug, Clone)]
3026pub struct DispatchDeclarationBuilder<'a> {
3027    /// The `predicate` field.
3028    predicate: Option<&'a [Term]>,
3029    /// The `target_resolver` field.
3030    target_resolver: Option<&'a str>,
3031    /// The `priority` field.
3032    priority: Option<u32>,
3033}
3034
3035/// Declared dispatch rule validated against `DispatchShape`.
3036#[derive(Debug, Clone, PartialEq, Eq)]
3037pub struct DispatchDeclaration {
3038    /// Shape IRI this declaration was validated against.
3039    pub shape_iri: &'static str,
3040}
3041
3042impl DispatchDeclaration {
3043    /// v0.2.2 Phase G: const-constructible empty form used by
3044    /// `validate_*_const` companion functions.
3045    #[inline]
3046    #[must_use]
3047    #[allow(dead_code)]
3048    pub(crate) const fn empty_const() -> Self {
3049        Self {
3050            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3051        }
3052    }
3053}
3054
3055impl<'a> DispatchDeclarationBuilder<'a> {
3056    /// Creates a new empty builder.
3057    #[must_use]
3058    pub const fn new() -> Self {
3059        Self {
3060            predicate: None,
3061            target_resolver: None,
3062            priority: None,
3063        }
3064    }
3065
3066    /// Set the `predicate` field.
3067    #[must_use]
3068    pub const fn predicate(mut self, value: &'a [Term]) -> Self {
3069        self.predicate = Some(value);
3070        self
3071    }
3072
3073    /// Set the `target_resolver` field.
3074    #[must_use]
3075    pub const fn target_resolver(mut self, value: &'a str) -> Self {
3076        self.target_resolver = Some(value);
3077        self
3078    }
3079
3080    /// Set the `priority` field.
3081    #[must_use]
3082    pub const fn priority(mut self, value: u32) -> Self {
3083        self.priority = Some(value);
3084        self
3085    }
3086
3087    /// Validate against `DispatchShape`.
3088    /// # Errors
3089    /// Returns `ShapeViolation` if any required field is missing.
3090    pub fn validate(self) -> Result<Validated<DispatchDeclaration>, ShapeViolation> {
3091        if self.predicate.is_none() {
3092            return Err(ShapeViolation {
3093                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3094                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3095                property_iri: "https://uor.foundation/conformance/predicate",
3096                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3097                min_count: 1,
3098                max_count: 1,
3099                kind: ViolationKind::Missing,
3100            });
3101        }
3102        if self.target_resolver.is_none() {
3103            return Err(ShapeViolation {
3104                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3105                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3106                property_iri: "https://uor.foundation/conformance/target_resolver",
3107                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3108                min_count: 1,
3109                max_count: 1,
3110                kind: ViolationKind::Missing,
3111            });
3112        }
3113        if self.priority.is_none() {
3114            return Err(ShapeViolation {
3115                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3116                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3117                property_iri: "https://uor.foundation/conformance/priority",
3118                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3119                min_count: 1,
3120                max_count: 1,
3121                kind: ViolationKind::Missing,
3122            });
3123        }
3124        Ok(Validated::new(DispatchDeclaration {
3125            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3126        }))
3127    }
3128
3129    /// Phase C.1: const-fn companion for `DispatchDeclarationBuilder::validate`.
3130    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3131    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3132    /// # Errors
3133    /// Returns `ShapeViolation` if any required field is missing.
3134    pub const fn validate_const(
3135        &self,
3136    ) -> Result<Validated<DispatchDeclaration, CompileTime>, ShapeViolation> {
3137        if self.predicate.is_none() {
3138            return Err(ShapeViolation {
3139                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3140                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3141                property_iri: "https://uor.foundation/conformance/predicate",
3142                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3143                min_count: 1,
3144                max_count: 1,
3145                kind: ViolationKind::Missing,
3146            });
3147        }
3148        if self.target_resolver.is_none() {
3149            return Err(ShapeViolation {
3150                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3151                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3152                property_iri: "https://uor.foundation/conformance/target_resolver",
3153                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3154                min_count: 1,
3155                max_count: 1,
3156                kind: ViolationKind::Missing,
3157            });
3158        }
3159        if self.priority.is_none() {
3160            return Err(ShapeViolation {
3161                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3162                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3163                property_iri: "https://uor.foundation/conformance/priority",
3164                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3165                min_count: 1,
3166                max_count: 1,
3167                kind: ViolationKind::Missing,
3168            });
3169        }
3170        Ok(Validated::new(DispatchDeclaration {
3171            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3172        }))
3173    }
3174}
3175
3176impl<'a> Default for DispatchDeclarationBuilder<'a> {
3177    fn default() -> Self {
3178        Self::new()
3179    }
3180}
3181
3182/// Builder for `LeaseDeclaration`. Validates against `LeaseShape`.
3183#[derive(Debug, Clone)]
3184pub struct LeaseDeclarationBuilder<'a> {
3185    /// The `linear_site` field.
3186    linear_site: Option<u32>,
3187    /// The `scope` field.
3188    scope: Option<&'a str>,
3189}
3190
3191/// Declared lease validated against `LeaseShape`.
3192#[derive(Debug, Clone, PartialEq, Eq)]
3193pub struct LeaseDeclaration {
3194    /// Shape IRI this declaration was validated against.
3195    pub shape_iri: &'static str,
3196}
3197
3198impl LeaseDeclaration {
3199    /// v0.2.2 Phase G: const-constructible empty form used by
3200    /// `validate_*_const` companion functions.
3201    #[inline]
3202    #[must_use]
3203    #[allow(dead_code)]
3204    pub(crate) const fn empty_const() -> Self {
3205        Self {
3206            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3207        }
3208    }
3209}
3210
3211impl<'a> LeaseDeclarationBuilder<'a> {
3212    /// Creates a new empty builder.
3213    #[must_use]
3214    pub const fn new() -> Self {
3215        Self {
3216            linear_site: None,
3217            scope: None,
3218        }
3219    }
3220
3221    /// Set the `linear_site` field.
3222    #[must_use]
3223    pub const fn linear_site(mut self, value: u32) -> Self {
3224        self.linear_site = Some(value);
3225        self
3226    }
3227
3228    /// Set the `scope` field.
3229    #[must_use]
3230    pub const fn scope(mut self, value: &'a str) -> Self {
3231        self.scope = Some(value);
3232        self
3233    }
3234
3235    /// Validate against `LeaseShape`.
3236    /// # Errors
3237    /// Returns `ShapeViolation` if any required field is missing.
3238    pub fn validate(self) -> Result<Validated<LeaseDeclaration>, ShapeViolation> {
3239        if self.linear_site.is_none() {
3240            return Err(ShapeViolation {
3241                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3242                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3243                property_iri: "https://uor.foundation/conformance/linear_site",
3244                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3245                min_count: 1,
3246                max_count: 1,
3247                kind: ViolationKind::Missing,
3248            });
3249        }
3250        if self.scope.is_none() {
3251            return Err(ShapeViolation {
3252                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3253                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3254                property_iri: "https://uor.foundation/conformance/scope",
3255                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3256                min_count: 1,
3257                max_count: 1,
3258                kind: ViolationKind::Missing,
3259            });
3260        }
3261        Ok(Validated::new(LeaseDeclaration {
3262            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3263        }))
3264    }
3265
3266    /// Phase C.1: const-fn companion for `LeaseDeclarationBuilder::validate`.
3267    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3268    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3269    /// # Errors
3270    /// Returns `ShapeViolation` if any required field is missing.
3271    pub const fn validate_const(
3272        &self,
3273    ) -> Result<Validated<LeaseDeclaration, CompileTime>, ShapeViolation> {
3274        if self.linear_site.is_none() {
3275            return Err(ShapeViolation {
3276                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3277                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3278                property_iri: "https://uor.foundation/conformance/linear_site",
3279                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3280                min_count: 1,
3281                max_count: 1,
3282                kind: ViolationKind::Missing,
3283            });
3284        }
3285        if self.scope.is_none() {
3286            return Err(ShapeViolation {
3287                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3288                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3289                property_iri: "https://uor.foundation/conformance/scope",
3290                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3291                min_count: 1,
3292                max_count: 1,
3293                kind: ViolationKind::Missing,
3294            });
3295        }
3296        Ok(Validated::new(LeaseDeclaration {
3297            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3298        }))
3299    }
3300}
3301
3302impl<'a> Default for LeaseDeclarationBuilder<'a> {
3303    fn default() -> Self {
3304        Self::new()
3305    }
3306}
3307
3308/// Builder for `StreamDeclaration`. Validates against `StreamShape`.
3309#[derive(Debug, Clone)]
3310pub struct StreamDeclarationBuilder<'a> {
3311    /// The `seed` field.
3312    seed: Option<&'a [Term]>,
3313    /// The `step` field.
3314    step: Option<&'a [Term]>,
3315    /// The `productivity_witness` field.
3316    productivity_witness: Option<&'a str>,
3317}
3318
3319/// Declared stream validated against `StreamShape`.
3320#[derive(Debug, Clone, PartialEq, Eq)]
3321pub struct StreamDeclaration {
3322    /// Shape IRI this declaration was validated against.
3323    pub shape_iri: &'static str,
3324}
3325
3326impl StreamDeclaration {
3327    /// v0.2.2 Phase G: const-constructible empty form used by
3328    /// `validate_*_const` companion functions.
3329    #[inline]
3330    #[must_use]
3331    #[allow(dead_code)]
3332    pub(crate) const fn empty_const() -> Self {
3333        Self {
3334            shape_iri: "https://uor.foundation/conformance/StreamShape",
3335        }
3336    }
3337}
3338
3339impl<'a> StreamDeclarationBuilder<'a> {
3340    /// Creates a new empty builder.
3341    #[must_use]
3342    pub const fn new() -> Self {
3343        Self {
3344            seed: None,
3345            step: None,
3346            productivity_witness: None,
3347        }
3348    }
3349
3350    /// Set the `seed` field.
3351    #[must_use]
3352    pub const fn seed(mut self, value: &'a [Term]) -> Self {
3353        self.seed = Some(value);
3354        self
3355    }
3356
3357    /// Set the `step` field.
3358    #[must_use]
3359    pub const fn step(mut self, value: &'a [Term]) -> Self {
3360        self.step = Some(value);
3361        self
3362    }
3363
3364    /// Set the `productivity_witness` field.
3365    #[must_use]
3366    pub const fn productivity_witness(mut self, value: &'a str) -> Self {
3367        self.productivity_witness = Some(value);
3368        self
3369    }
3370
3371    /// Validate against `StreamShape`.
3372    /// # Errors
3373    /// Returns `ShapeViolation` if any required field is missing.
3374    pub fn validate(self) -> Result<Validated<StreamDeclaration>, ShapeViolation> {
3375        if self.seed.is_none() {
3376            return Err(ShapeViolation {
3377                shape_iri: "https://uor.foundation/conformance/StreamShape",
3378                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3379                property_iri: "https://uor.foundation/conformance/seed",
3380                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3381                min_count: 1,
3382                max_count: 1,
3383                kind: ViolationKind::Missing,
3384            });
3385        }
3386        if self.step.is_none() {
3387            return Err(ShapeViolation {
3388                shape_iri: "https://uor.foundation/conformance/StreamShape",
3389                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3390                property_iri: "https://uor.foundation/conformance/step",
3391                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3392                min_count: 1,
3393                max_count: 1,
3394                kind: ViolationKind::Missing,
3395            });
3396        }
3397        if self.productivity_witness.is_none() {
3398            return Err(ShapeViolation {
3399                shape_iri: "https://uor.foundation/conformance/StreamShape",
3400                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3401                property_iri: "https://uor.foundation/conformance/productivity_witness",
3402                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3403                min_count: 1,
3404                max_count: 1,
3405                kind: ViolationKind::Missing,
3406            });
3407        }
3408        Ok(Validated::new(StreamDeclaration {
3409            shape_iri: "https://uor.foundation/conformance/StreamShape",
3410        }))
3411    }
3412
3413    /// Phase C.1: const-fn companion for `StreamDeclarationBuilder::validate`.
3414    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3415    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3416    /// # Errors
3417    /// Returns `ShapeViolation` if any required field is missing.
3418    pub const fn validate_const(
3419        &self,
3420    ) -> Result<Validated<StreamDeclaration, CompileTime>, ShapeViolation> {
3421        if self.seed.is_none() {
3422            return Err(ShapeViolation {
3423                shape_iri: "https://uor.foundation/conformance/StreamShape",
3424                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3425                property_iri: "https://uor.foundation/conformance/seed",
3426                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3427                min_count: 1,
3428                max_count: 1,
3429                kind: ViolationKind::Missing,
3430            });
3431        }
3432        if self.step.is_none() {
3433            return Err(ShapeViolation {
3434                shape_iri: "https://uor.foundation/conformance/StreamShape",
3435                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3436                property_iri: "https://uor.foundation/conformance/step",
3437                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3438                min_count: 1,
3439                max_count: 1,
3440                kind: ViolationKind::Missing,
3441            });
3442        }
3443        if self.productivity_witness.is_none() {
3444            return Err(ShapeViolation {
3445                shape_iri: "https://uor.foundation/conformance/StreamShape",
3446                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3447                property_iri: "https://uor.foundation/conformance/productivity_witness",
3448                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3449                min_count: 1,
3450                max_count: 1,
3451                kind: ViolationKind::Missing,
3452            });
3453        }
3454        Ok(Validated::new(StreamDeclaration {
3455            shape_iri: "https://uor.foundation/conformance/StreamShape",
3456        }))
3457    }
3458}
3459
3460impl<'a> Default for StreamDeclarationBuilder<'a> {
3461    fn default() -> Self {
3462        Self::new()
3463    }
3464}
3465
3466/// Builder for `PredicateDeclaration`. Validates against `PredicateShape`.
3467#[derive(Debug, Clone)]
3468pub struct PredicateDeclarationBuilder<'a> {
3469    /// The `input_type` field.
3470    input_type: Option<&'a str>,
3471    /// The `evaluator` field.
3472    evaluator: Option<&'a [Term]>,
3473    /// The `termination_witness` field.
3474    termination_witness: Option<&'a str>,
3475}
3476
3477/// Declared predicate validated against `PredicateShape`.
3478#[derive(Debug, Clone, PartialEq, Eq)]
3479pub struct PredicateDeclaration {
3480    /// Shape IRI this declaration was validated against.
3481    pub shape_iri: &'static str,
3482}
3483
3484impl PredicateDeclaration {
3485    /// v0.2.2 Phase G: const-constructible empty form used by
3486    /// `validate_*_const` companion functions.
3487    #[inline]
3488    #[must_use]
3489    #[allow(dead_code)]
3490    pub(crate) const fn empty_const() -> Self {
3491        Self {
3492            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3493        }
3494    }
3495}
3496
3497impl<'a> PredicateDeclarationBuilder<'a> {
3498    /// Creates a new empty builder.
3499    #[must_use]
3500    pub const fn new() -> Self {
3501        Self {
3502            input_type: None,
3503            evaluator: None,
3504            termination_witness: None,
3505        }
3506    }
3507
3508    /// Set the `input_type` field.
3509    #[must_use]
3510    pub const fn input_type(mut self, value: &'a str) -> Self {
3511        self.input_type = Some(value);
3512        self
3513    }
3514
3515    /// Set the `evaluator` field.
3516    #[must_use]
3517    pub const fn evaluator(mut self, value: &'a [Term]) -> Self {
3518        self.evaluator = Some(value);
3519        self
3520    }
3521
3522    /// Set the `termination_witness` field.
3523    #[must_use]
3524    pub const fn termination_witness(mut self, value: &'a str) -> Self {
3525        self.termination_witness = Some(value);
3526        self
3527    }
3528
3529    /// Validate against `PredicateShape`.
3530    /// # Errors
3531    /// Returns `ShapeViolation` if any required field is missing.
3532    pub fn validate(self) -> Result<Validated<PredicateDeclaration>, ShapeViolation> {
3533        if self.input_type.is_none() {
3534            return Err(ShapeViolation {
3535                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3536                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3537                property_iri: "https://uor.foundation/conformance/input_type",
3538                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3539                min_count: 1,
3540                max_count: 1,
3541                kind: ViolationKind::Missing,
3542            });
3543        }
3544        if self.evaluator.is_none() {
3545            return Err(ShapeViolation {
3546                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3547                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3548                property_iri: "https://uor.foundation/conformance/evaluator",
3549                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3550                min_count: 1,
3551                max_count: 1,
3552                kind: ViolationKind::Missing,
3553            });
3554        }
3555        if self.termination_witness.is_none() {
3556            return Err(ShapeViolation {
3557                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3558                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3559                property_iri: "https://uor.foundation/conformance/termination_witness",
3560                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3561                min_count: 1,
3562                max_count: 1,
3563                kind: ViolationKind::Missing,
3564            });
3565        }
3566        Ok(Validated::new(PredicateDeclaration {
3567            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3568        }))
3569    }
3570
3571    /// Phase C.1: const-fn companion for `PredicateDeclarationBuilder::validate`.
3572    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3573    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3574    /// # Errors
3575    /// Returns `ShapeViolation` if any required field is missing.
3576    pub const fn validate_const(
3577        &self,
3578    ) -> Result<Validated<PredicateDeclaration, CompileTime>, ShapeViolation> {
3579        if self.input_type.is_none() {
3580            return Err(ShapeViolation {
3581                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3582                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3583                property_iri: "https://uor.foundation/conformance/input_type",
3584                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3585                min_count: 1,
3586                max_count: 1,
3587                kind: ViolationKind::Missing,
3588            });
3589        }
3590        if self.evaluator.is_none() {
3591            return Err(ShapeViolation {
3592                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3593                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3594                property_iri: "https://uor.foundation/conformance/evaluator",
3595                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3596                min_count: 1,
3597                max_count: 1,
3598                kind: ViolationKind::Missing,
3599            });
3600        }
3601        if self.termination_witness.is_none() {
3602            return Err(ShapeViolation {
3603                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3604                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3605                property_iri: "https://uor.foundation/conformance/termination_witness",
3606                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3607                min_count: 1,
3608                max_count: 1,
3609                kind: ViolationKind::Missing,
3610            });
3611        }
3612        Ok(Validated::new(PredicateDeclaration {
3613            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3614        }))
3615    }
3616}
3617
3618impl<'a> Default for PredicateDeclarationBuilder<'a> {
3619    fn default() -> Self {
3620        Self::new()
3621    }
3622}
3623
3624/// Builder for `ParallelDeclaration`. Validates against `ParallelShape`.
3625#[derive(Debug, Clone)]
3626pub struct ParallelDeclarationBuilder<'a> {
3627    /// The `site_partition` field.
3628    site_partition: Option<&'a [u32]>,
3629    /// The `disjointness_witness` field.
3630    disjointness_witness: Option<&'a str>,
3631}
3632
3633/// Declared parallel composition validated against `ParallelShape`.
3634#[derive(Debug, Clone, PartialEq, Eq)]
3635pub struct ParallelDeclaration {
3636    /// Shape IRI this declaration was validated against.
3637    pub shape_iri: &'static str,
3638}
3639
3640impl ParallelDeclaration {
3641    /// v0.2.2 Phase G: const-constructible empty form used by
3642    /// `validate_*_const` companion functions.
3643    #[inline]
3644    #[must_use]
3645    #[allow(dead_code)]
3646    pub(crate) const fn empty_const() -> Self {
3647        Self {
3648            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3649        }
3650    }
3651}
3652
3653impl<'a> ParallelDeclarationBuilder<'a> {
3654    /// Creates a new empty builder.
3655    #[must_use]
3656    pub const fn new() -> Self {
3657        Self {
3658            site_partition: None,
3659            disjointness_witness: None,
3660        }
3661    }
3662
3663    /// Set the `site_partition` field.
3664    #[must_use]
3665    pub const fn site_partition(mut self, value: &'a [u32]) -> Self {
3666        self.site_partition = Some(value);
3667        self
3668    }
3669
3670    /// Set the `disjointness_witness` field.
3671    #[must_use]
3672    pub const fn disjointness_witness(mut self, value: &'a str) -> Self {
3673        self.disjointness_witness = Some(value);
3674        self
3675    }
3676
3677    /// Validate against `ParallelShape`.
3678    /// # Errors
3679    /// Returns `ShapeViolation` if any required field is missing.
3680    pub fn validate(self) -> Result<Validated<ParallelDeclaration>, ShapeViolation> {
3681        if self.site_partition.is_none() {
3682            return Err(ShapeViolation {
3683                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3684                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3685                property_iri: "https://uor.foundation/conformance/site_partition",
3686                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3687                min_count: 1,
3688                max_count: 1,
3689                kind: ViolationKind::Missing,
3690            });
3691        }
3692        if self.disjointness_witness.is_none() {
3693            return Err(ShapeViolation {
3694                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3695                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3696                property_iri: "https://uor.foundation/conformance/disjointness_witness",
3697                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3698                min_count: 1,
3699                max_count: 1,
3700                kind: ViolationKind::Missing,
3701            });
3702        }
3703        Ok(Validated::new(ParallelDeclaration {
3704            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3705        }))
3706    }
3707
3708    /// Phase C.1: const-fn companion for `ParallelDeclarationBuilder::validate`.
3709    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3710    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3711    /// # Errors
3712    /// Returns `ShapeViolation` if any required field is missing.
3713    pub const fn validate_const(
3714        &self,
3715    ) -> Result<Validated<ParallelDeclaration, CompileTime>, ShapeViolation> {
3716        if self.site_partition.is_none() {
3717            return Err(ShapeViolation {
3718                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3719                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3720                property_iri: "https://uor.foundation/conformance/site_partition",
3721                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3722                min_count: 1,
3723                max_count: 1,
3724                kind: ViolationKind::Missing,
3725            });
3726        }
3727        if self.disjointness_witness.is_none() {
3728            return Err(ShapeViolation {
3729                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3730                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3731                property_iri: "https://uor.foundation/conformance/disjointness_witness",
3732                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3733                min_count: 1,
3734                max_count: 1,
3735                kind: ViolationKind::Missing,
3736            });
3737        }
3738        Ok(Validated::new(ParallelDeclaration {
3739            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3740        }))
3741    }
3742}
3743
3744impl<'a> Default for ParallelDeclarationBuilder<'a> {
3745    fn default() -> Self {
3746        Self::new()
3747    }
3748}
3749
3750impl<'a> ParallelDeclarationBuilder<'a> {
3751    /// v0.2.2 T2.7: const-fn accessor returning the length of the
3752    /// declared site partition (or 0 if unset).
3753    #[inline]
3754    #[must_use]
3755    pub const fn site_partition_len(&self) -> usize {
3756        match self.site_partition {
3757            Some(p) => p.len(),
3758            None => 0,
3759        }
3760    }
3761
3762    /// v0.2.2 Phase A: const-fn accessor returning the declared site-partition
3763    /// slice, or an empty slice if unset. Used by `validate_parallel_const`
3764    /// to propagate the partition into the widened `ParallelDeclaration<'a>`.
3765    #[inline]
3766    #[must_use]
3767    pub const fn site_partition_slice_const(&self) -> &'a [u32] {
3768        match self.site_partition {
3769            Some(p) => p,
3770            None => &[],
3771        }
3772    }
3773
3774    /// v0.2.2 Phase A: const-fn accessor returning the declared disjointness-witness
3775    /// IRI string, or an empty string if unset.
3776    #[inline]
3777    #[must_use]
3778    pub const fn disjointness_witness_const(&self) -> &'a str {
3779        match self.disjointness_witness {
3780            Some(s) => s,
3781            None => "",
3782        }
3783    }
3784}
3785
3786impl<'a> StreamDeclarationBuilder<'a> {
3787    /// v0.2.2 canonical: productivity bound is 1 if a `productivityWitness`
3788    /// IRI is declared (the stream attests termination via a `proof:Proof`
3789    /// individual), 0 otherwise. The witness's IRI points to the termination
3790    /// proof; downstream resolvers dereference it for detailed bound
3791    /// information. This two-level split (presence flag here, IRI dereference
3792    /// elsewhere) is the canonical foundation-level shape.
3793    #[inline]
3794    #[must_use]
3795    pub const fn productivity_bound_const(&self) -> u64 {
3796        match self.productivity_witness {
3797            Some(_) => 1,
3798            None => 0,
3799        }
3800    }
3801
3802    /// v0.2.2 Phase A: const-fn accessor returning the declared seed term slice,
3803    /// or an empty slice if unset.
3804    #[inline]
3805    #[must_use]
3806    pub const fn seed_slice_const(&self) -> &'a [Term] {
3807        match self.seed {
3808            Some(t) => t,
3809            None => &[],
3810        }
3811    }
3812
3813    /// v0.2.2 Phase A: const-fn accessor returning the declared step term slice,
3814    /// or an empty slice if unset.
3815    #[inline]
3816    #[must_use]
3817    pub const fn step_slice_const(&self) -> &'a [Term] {
3818        match self.step {
3819            Some(t) => t,
3820            None => &[],
3821        }
3822    }
3823
3824    /// v0.2.2 Phase A: const-fn accessor returning the declared productivity-witness
3825    /// IRI, or an empty string if unset.
3826    #[inline]
3827    #[must_use]
3828    pub const fn productivity_witness_const(&self) -> &'a str {
3829        match self.productivity_witness {
3830            Some(s) => s,
3831            None => "",
3832        }
3833    }
3834}
3835
3836/// Builder for declaring a new Witt level beyond W32.
3837/// Validates against `WittLevelShape`.
3838#[derive(Debug, Clone)]
3839pub struct WittLevelDeclarationBuilder {
3840    /// The declared bit width.
3841    bit_width: Option<u32>,
3842    /// The declared cycle size.
3843    cycle_size: Option<u128>,
3844    /// The predecessor level.
3845    predecessor: Option<WittLevel>,
3846}
3847
3848/// Validated Witt level declaration.
3849#[derive(Debug, Clone, PartialEq, Eq)]
3850pub struct WittLevelDeclaration {
3851    /// The declared bit width.
3852    pub bit_width: u32,
3853    /// The predecessor level.
3854    pub predecessor: WittLevel,
3855}
3856
3857impl WittLevelDeclarationBuilder {
3858    /// Creates a new empty builder.
3859    #[must_use]
3860    pub const fn new() -> Self {
3861        Self {
3862            bit_width: None,
3863            cycle_size: None,
3864            predecessor: None,
3865        }
3866    }
3867
3868    /// Set the declared bit width.
3869    #[must_use]
3870    pub const fn bit_width(mut self, w: u32) -> Self {
3871        self.bit_width = Some(w);
3872        self
3873    }
3874
3875    /// Set the declared cycle size.
3876    #[must_use]
3877    pub const fn cycle_size(mut self, s: u128) -> Self {
3878        self.cycle_size = Some(s);
3879        self
3880    }
3881
3882    /// Set the predecessor Witt level.
3883    #[must_use]
3884    pub const fn predecessor(mut self, level: WittLevel) -> Self {
3885        self.predecessor = Some(level);
3886        self
3887    }
3888
3889    /// Validate against `WittLevelShape`.
3890    /// # Errors
3891    /// Returns `ShapeViolation` if any required field is missing.
3892    pub fn validate(self) -> Result<Validated<WittLevelDeclaration>, ShapeViolation> {
3893        let bw = match self.bit_width {
3894            Some(w) => w,
3895            None => {
3896                return Err(ShapeViolation {
3897                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3898                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3899                    property_iri: "https://uor.foundation/conformance/declaredBitWidth",
3900                    expected_range: "http://www.w3.org/2001/XMLSchema#positiveInteger",
3901                    min_count: 1,
3902                    max_count: 1,
3903                    kind: ViolationKind::Missing,
3904                })
3905            }
3906        };
3907        let pred = match self.predecessor {
3908            Some(p) => p,
3909            None => {
3910                return Err(ShapeViolation {
3911                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3912                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3913                    property_iri: "https://uor.foundation/conformance/predecessorLevel",
3914                    expected_range: "https://uor.foundation/schema/WittLevel",
3915                    min_count: 1,
3916                    max_count: 1,
3917                    kind: ViolationKind::Missing,
3918                })
3919            }
3920        };
3921        Ok(Validated::new(WittLevelDeclaration {
3922            bit_width: bw,
3923            predecessor: pred,
3924        }))
3925    }
3926
3927    /// Phase C.1: const-fn companion for `WittLevelDeclarationBuilder::validate`.
3928    /// # Errors
3929    /// Returns `ShapeViolation` if any required field is missing.
3930    pub const fn validate_const(
3931        &self,
3932    ) -> Result<Validated<WittLevelDeclaration, CompileTime>, ShapeViolation> {
3933        let bw = match self.bit_width {
3934            Some(w) => w,
3935            None => {
3936                return Err(ShapeViolation {
3937                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3938                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3939                    property_iri: "https://uor.foundation/conformance/declaredBitWidth",
3940                    expected_range: "http://www.w3.org/2001/XMLSchema#positiveInteger",
3941                    min_count: 1,
3942                    max_count: 1,
3943                    kind: ViolationKind::Missing,
3944                })
3945            }
3946        };
3947        let pred = match self.predecessor {
3948            Some(p) => p,
3949            None => {
3950                return Err(ShapeViolation {
3951                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3952                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3953                    property_iri: "https://uor.foundation/conformance/predecessorLevel",
3954                    expected_range: "https://uor.foundation/schema/WittLevel",
3955                    min_count: 1,
3956                    max_count: 1,
3957                    kind: ViolationKind::Missing,
3958                })
3959            }
3960        };
3961        Ok(Validated::new(WittLevelDeclaration {
3962            bit_width: bw,
3963            predecessor: pred,
3964        }))
3965    }
3966}
3967
3968impl Default for WittLevelDeclarationBuilder {
3969    fn default() -> Self {
3970        Self::new()
3971    }
3972}
3973
3974/// Boundary session state tracker for the two-phase minting boundary.
3975/// Records crossing count and idempotency flag. Private fields
3976/// prevent external construction.
3977#[derive(Debug, Clone, PartialEq, Eq)]
3978pub struct BoundarySession {
3979    /// Total boundary crossings in this session.
3980    crossing_count: u32,
3981    /// Whether the boundary effect is idempotent.
3982    is_idempotent: bool,
3983}
3984
3985impl BoundarySession {
3986    /// Creates a new boundary session. Only callable within the crate.
3987    #[inline]
3988    #[allow(dead_code)]
3989    pub(crate) const fn new(is_idempotent: bool) -> Self {
3990        Self {
3991            crossing_count: 0,
3992            is_idempotent,
3993        }
3994    }
3995
3996    /// Returns the total boundary crossings.
3997    #[inline]
3998    #[must_use]
3999    pub const fn crossing_count(&self) -> u32 {
4000        self.crossing_count
4001    }
4002
4003    /// Returns whether the boundary effect is idempotent.
4004    #[inline]
4005    #[must_use]
4006    pub const fn is_idempotent(&self) -> bool {
4007        self.is_idempotent
4008    }
4009}
4010
4011/// Validate a scalar grounding intermediate against a `GroundingShape`
4012/// and mint it into a `Datum`. Only callable within `uor-foundation`.
4013/// # Errors
4014/// Returns `ShapeViolation` if the coordinate fails validation.
4015#[allow(dead_code)]
4016pub(crate) fn validate_and_mint_coord(
4017    grounded: GroundedCoord,
4018    shape: &Validated<GroundingDeclaration>,
4019    session: &mut BoundarySession,
4020) -> Result<Datum, ShapeViolation> {
4021    // The Validated<GroundingDeclaration> proves the shape was already
4022    // validated at builder time. The coordinate's level is guaranteed
4023    // correct by the closed GroundedCoordInner enum — the type system
4024    // enforces that only supported levels can be constructed.
4025    let _ = shape; // shape validation passed at builder time
4026    session.crossing_count += 1;
4027    let inner = match grounded.inner {
4028        GroundedCoordInner::W8(b) => DatumInner::W8(b),
4029        GroundedCoordInner::W16(b) => DatumInner::W16(b),
4030        GroundedCoordInner::W24(b) => DatumInner::W24(b),
4031        GroundedCoordInner::W32(b) => DatumInner::W32(b),
4032        GroundedCoordInner::W40(b) => DatumInner::W40(b),
4033        GroundedCoordInner::W48(b) => DatumInner::W48(b),
4034        GroundedCoordInner::W56(b) => DatumInner::W56(b),
4035        GroundedCoordInner::W64(b) => DatumInner::W64(b),
4036        GroundedCoordInner::W72(b) => DatumInner::W72(b),
4037        GroundedCoordInner::W80(b) => DatumInner::W80(b),
4038        GroundedCoordInner::W88(b) => DatumInner::W88(b),
4039        GroundedCoordInner::W96(b) => DatumInner::W96(b),
4040        GroundedCoordInner::W104(b) => DatumInner::W104(b),
4041        GroundedCoordInner::W112(b) => DatumInner::W112(b),
4042        GroundedCoordInner::W120(b) => DatumInner::W120(b),
4043        GroundedCoordInner::W128(b) => DatumInner::W128(b),
4044    };
4045    Ok(Datum { inner })
4046}
4047
4048/// Validate a tuple grounding intermediate and mint into a `Datum`.
4049/// Only callable within `uor-foundation`.
4050/// Mints the first coordinate of the tuple as the representative `Datum`.
4051/// Composite multi-coordinate `Datum` construction depends on the target
4052/// type's site decomposition, which is resolved during reduction evaluation.
4053/// # Errors
4054/// Returns `ShapeViolation` if the tuple is empty or fails validation.
4055#[allow(dead_code)]
4056pub(crate) fn validate_and_mint_tuple<const N: usize>(
4057    grounded: GroundedTuple<N>,
4058    shape: &Validated<GroundingDeclaration>,
4059    session: &mut BoundarySession,
4060) -> Result<Datum, ShapeViolation> {
4061    if N == 0 {
4062        return Err(ShapeViolation {
4063            shape_iri: shape.inner().shape_iri,
4064            constraint_iri: shape.inner().shape_iri,
4065            property_iri: "https://uor.foundation/conformance/groundingSourceType",
4066            expected_range: "https://uor.foundation/type/TypeDefinition",
4067            min_count: 1,
4068            max_count: 0,
4069            kind: ViolationKind::CardinalityViolation,
4070        });
4071    }
4072    // Mint the first coordinate as the representative Datum.
4073    // The full tuple is decomposed during reduction evaluation,
4074    // where each coordinate maps to a site in the constrained type.
4075    validate_and_mint_coord(grounded.coords[0].clone(), shape, session)
4076}
4077
4078/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Datum`.
4079/// Takes host bytes that have already passed the author's `Grounding` impl and
4080/// mints them into a sealed `Datum` at the supplied Witt level. The bytes are
4081/// decoded according to the level's byte width.
4082/// # Errors
4083/// Returns [`ShapeViolation`] if `bytes.len()` doesn't match the level's byte width
4084/// or if the level is unsupported.
4085pub fn mint_datum(level: crate::WittLevel, bytes: &[u8]) -> Result<Datum, ShapeViolation> {
4086    let expected_bytes = (level.witt_length() / 8) as usize;
4087    if bytes.len() != expected_bytes {
4088        return Err(ShapeViolation {
4089            shape_iri: "https://uor.foundation/u/Datum",
4090            constraint_iri: "https://uor.foundation/u/DatumByteWidth",
4091            property_iri: "https://uor.foundation/u/datumBytes",
4092            expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
4093            min_count: expected_bytes as u32,
4094            max_count: expected_bytes as u32,
4095            kind: crate::ViolationKind::CardinalityViolation,
4096        });
4097    }
4098    let inner = match level.witt_length() {
4099        8 => {
4100            let mut buf = [0u8; 1];
4101            let mut i = 0;
4102            while i < 1 {
4103                buf[i] = bytes[i];
4104                i += 1;
4105            }
4106            DatumInner::W8(buf)
4107        }
4108        16 => {
4109            let mut buf = [0u8; 2];
4110            let mut i = 0;
4111            while i < 2 {
4112                buf[i] = bytes[i];
4113                i += 1;
4114            }
4115            DatumInner::W16(buf)
4116        }
4117        24 => {
4118            let mut buf = [0u8; 3];
4119            let mut i = 0;
4120            while i < 3 {
4121                buf[i] = bytes[i];
4122                i += 1;
4123            }
4124            DatumInner::W24(buf)
4125        }
4126        32 => {
4127            let mut buf = [0u8; 4];
4128            let mut i = 0;
4129            while i < 4 {
4130                buf[i] = bytes[i];
4131                i += 1;
4132            }
4133            DatumInner::W32(buf)
4134        }
4135        40 => {
4136            let mut buf = [0u8; 5];
4137            let mut i = 0;
4138            while i < 5 {
4139                buf[i] = bytes[i];
4140                i += 1;
4141            }
4142            DatumInner::W40(buf)
4143        }
4144        48 => {
4145            let mut buf = [0u8; 6];
4146            let mut i = 0;
4147            while i < 6 {
4148                buf[i] = bytes[i];
4149                i += 1;
4150            }
4151            DatumInner::W48(buf)
4152        }
4153        56 => {
4154            let mut buf = [0u8; 7];
4155            let mut i = 0;
4156            while i < 7 {
4157                buf[i] = bytes[i];
4158                i += 1;
4159            }
4160            DatumInner::W56(buf)
4161        }
4162        64 => {
4163            let mut buf = [0u8; 8];
4164            let mut i = 0;
4165            while i < 8 {
4166                buf[i] = bytes[i];
4167                i += 1;
4168            }
4169            DatumInner::W64(buf)
4170        }
4171        72 => {
4172            let mut buf = [0u8; 9];
4173            let mut i = 0;
4174            while i < 9 {
4175                buf[i] = bytes[i];
4176                i += 1;
4177            }
4178            DatumInner::W72(buf)
4179        }
4180        80 => {
4181            let mut buf = [0u8; 10];
4182            let mut i = 0;
4183            while i < 10 {
4184                buf[i] = bytes[i];
4185                i += 1;
4186            }
4187            DatumInner::W80(buf)
4188        }
4189        88 => {
4190            let mut buf = [0u8; 11];
4191            let mut i = 0;
4192            while i < 11 {
4193                buf[i] = bytes[i];
4194                i += 1;
4195            }
4196            DatumInner::W88(buf)
4197        }
4198        96 => {
4199            let mut buf = [0u8; 12];
4200            let mut i = 0;
4201            while i < 12 {
4202                buf[i] = bytes[i];
4203                i += 1;
4204            }
4205            DatumInner::W96(buf)
4206        }
4207        104 => {
4208            let mut buf = [0u8; 13];
4209            let mut i = 0;
4210            while i < 13 {
4211                buf[i] = bytes[i];
4212                i += 1;
4213            }
4214            DatumInner::W104(buf)
4215        }
4216        112 => {
4217            let mut buf = [0u8; 14];
4218            let mut i = 0;
4219            while i < 14 {
4220                buf[i] = bytes[i];
4221                i += 1;
4222            }
4223            DatumInner::W112(buf)
4224        }
4225        120 => {
4226            let mut buf = [0u8; 15];
4227            let mut i = 0;
4228            while i < 15 {
4229                buf[i] = bytes[i];
4230                i += 1;
4231            }
4232            DatumInner::W120(buf)
4233        }
4234        128 => {
4235            let mut buf = [0u8; 16];
4236            let mut i = 0;
4237            while i < 16 {
4238                buf[i] = bytes[i];
4239                i += 1;
4240            }
4241            DatumInner::W128(buf)
4242        }
4243        _ => {
4244            return Err(ShapeViolation {
4245                shape_iri: "https://uor.foundation/u/Datum",
4246                constraint_iri: "https://uor.foundation/u/DatumLevel",
4247                property_iri: "https://uor.foundation/u/datumLevel",
4248                expected_range: "https://uor.foundation/schema/WittLevel",
4249                min_count: 1,
4250                max_count: 1,
4251                kind: crate::ViolationKind::ValueCheck,
4252            })
4253        }
4254    };
4255    Ok(Datum { inner })
4256}
4257
4258/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Triad<L>`.
4259/// Takes three coordinate values that satisfy the Triad shape constraint and
4260/// mints them into a sealed `Triad<L>` at the level marker `L`.
4261#[must_use]
4262pub const fn mint_triad<L>(stratum: u64, spectrum: u64, address: u64) -> Triad<L> {
4263    Triad::new(stratum, spectrum, address)
4264}
4265
4266/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Derivation`.
4267/// Takes the precursor's step count + Witt level + content fingerprint and mints
4268/// a sealed `Derivation` carrying the typed transition witness.
4269#[must_use]
4270pub const fn mint_derivation(
4271    step_count: u32,
4272    witt_level_bits: u16,
4273    content_fingerprint: ContentFingerprint,
4274) -> Derivation {
4275    Derivation::new(step_count, witt_level_bits, content_fingerprint)
4276}
4277
4278/// Wiki ADR-016 mint primitive: cross-crate construction surface for `FreeRank`.
4279/// Takes a natural-number rank witness (total site capacity at the Witt level plus
4280/// the number of currently pinned sites) and mints it into a sealed `FreeRank`.
4281#[must_use]
4282pub const fn mint_freerank(total: u32, pinned: u32) -> FreeRank {
4283    FreeRank::new(total, pinned)
4284}
4285
4286/// Evaluate a binary ring operation at compile time.
4287/// One helper is emitted per `schema:WittLevel` individual. The `uor!`
4288/// proc macro delegates to these helpers; it never performs ring
4289/// arithmetic itself.
4290/// # Examples
4291/// ```rust
4292/// use uor_foundation::enforcement::{const_ring_eval_w8, const_ring_eval_unary_w8};
4293/// use uor_foundation::PrimitiveOp;
4294///
4295/// // Ring arithmetic in Z/256Z: all operations wrap modulo 256.
4296///
4297/// // Addition wraps: 200 + 100 = 300 -> 300 - 256 = 44
4298/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Add, 200, 100), 44);
4299///
4300/// // Multiplication: 3 * 5 = 15 (no wrap needed)
4301/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Mul, 3, 5), 15);
4302///
4303/// // XOR: bitwise exclusive-or
4304/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Xor, 0b1010, 0b1100), 0b0110);
4305///
4306/// // Negation: neg(x) = 256 - x (additive inverse in Z/256Z)
4307/// assert_eq!(const_ring_eval_unary_w8(PrimitiveOp::Neg, 1), 255);
4308///
4309/// // The critical identity: neg(bnot(x)) = succ(x) for all x
4310/// let x = 42u8;
4311/// let lhs = const_ring_eval_unary_w8(PrimitiveOp::Neg,
4312///     const_ring_eval_unary_w8(PrimitiveOp::Bnot, x));
4313/// let rhs = const_ring_eval_unary_w8(PrimitiveOp::Succ, x);
4314/// assert_eq!(lhs, rhs);
4315/// ```
4316#[inline]
4317#[must_use]
4318#[allow(clippy::manual_checked_ops)]
4319pub const fn const_ring_eval_w8(op: PrimitiveOp, a: u8, b: u8) -> u8 {
4320    match op {
4321        PrimitiveOp::Add => a.wrapping_add(b),
4322        PrimitiveOp::Sub => a.wrapping_sub(b),
4323        PrimitiveOp::Mul => a.wrapping_mul(b),
4324        PrimitiveOp::Xor => a ^ b,
4325        PrimitiveOp::And => a & b,
4326        PrimitiveOp::Or => a | b,
4327        PrimitiveOp::Le => (a <= b) as u8,
4328        PrimitiveOp::Lt => (a < b) as u8,
4329        PrimitiveOp::Ge => (a >= b) as u8,
4330        PrimitiveOp::Gt => (a > b) as u8,
4331        PrimitiveOp::Concat => 0,
4332        PrimitiveOp::Div => {
4333            if b == 0 {
4334                0
4335            } else {
4336                a / b
4337            }
4338        }
4339        PrimitiveOp::Mod => {
4340            if b == 0 {
4341                0
4342            } else {
4343                a % b
4344            }
4345        }
4346        PrimitiveOp::Pow => const_pow_w8(a, b),
4347        _ => 0,
4348    }
4349}
4350
4351#[inline]
4352#[must_use]
4353pub const fn const_pow_w8(base: u8, exp: u8) -> u8 {
4354    let mut result: u8 = 1;
4355    let mut b: u8 = base;
4356    let mut e: u8 = exp;
4357    while e > 0 {
4358        if (e & 1) == 1 {
4359            result = result.wrapping_mul(b);
4360        }
4361        b = b.wrapping_mul(b);
4362        e >>= 1;
4363    }
4364    result
4365}
4366
4367#[inline]
4368#[must_use]
4369pub const fn const_ring_eval_unary_w8(op: PrimitiveOp, a: u8) -> u8 {
4370    match op {
4371        PrimitiveOp::Neg => 0u8.wrapping_sub(a),
4372        PrimitiveOp::Bnot => !a,
4373        PrimitiveOp::Succ => a.wrapping_add(1),
4374        PrimitiveOp::Pred => a.wrapping_sub(1),
4375        _ => 0,
4376    }
4377}
4378
4379#[inline]
4380#[must_use]
4381#[allow(clippy::manual_checked_ops)]
4382pub const fn const_ring_eval_w16(op: PrimitiveOp, a: u16, b: u16) -> u16 {
4383    match op {
4384        PrimitiveOp::Add => a.wrapping_add(b),
4385        PrimitiveOp::Sub => a.wrapping_sub(b),
4386        PrimitiveOp::Mul => a.wrapping_mul(b),
4387        PrimitiveOp::Xor => a ^ b,
4388        PrimitiveOp::And => a & b,
4389        PrimitiveOp::Or => a | b,
4390        PrimitiveOp::Le => (a <= b) as u16,
4391        PrimitiveOp::Lt => (a < b) as u16,
4392        PrimitiveOp::Ge => (a >= b) as u16,
4393        PrimitiveOp::Gt => (a > b) as u16,
4394        PrimitiveOp::Concat => 0,
4395        PrimitiveOp::Div => {
4396            if b == 0 {
4397                0
4398            } else {
4399                a / b
4400            }
4401        }
4402        PrimitiveOp::Mod => {
4403            if b == 0 {
4404                0
4405            } else {
4406                a % b
4407            }
4408        }
4409        PrimitiveOp::Pow => const_pow_w16(a, b),
4410        _ => 0,
4411    }
4412}
4413
4414#[inline]
4415#[must_use]
4416pub const fn const_pow_w16(base: u16, exp: u16) -> u16 {
4417    let mut result: u16 = 1;
4418    let mut b: u16 = base;
4419    let mut e: u16 = exp;
4420    while e > 0 {
4421        if (e & 1) == 1 {
4422            result = result.wrapping_mul(b);
4423        }
4424        b = b.wrapping_mul(b);
4425        e >>= 1;
4426    }
4427    result
4428}
4429
4430#[inline]
4431#[must_use]
4432pub const fn const_ring_eval_unary_w16(op: PrimitiveOp, a: u16) -> u16 {
4433    match op {
4434        PrimitiveOp::Neg => 0u16.wrapping_sub(a),
4435        PrimitiveOp::Bnot => !a,
4436        PrimitiveOp::Succ => a.wrapping_add(1),
4437        PrimitiveOp::Pred => a.wrapping_sub(1),
4438        _ => 0,
4439    }
4440}
4441
4442#[inline]
4443#[must_use]
4444#[allow(clippy::manual_checked_ops)]
4445pub const fn const_ring_eval_w24(op: PrimitiveOp, a: u32, b: u32) -> u32 {
4446    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4447    match op {
4448        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4449        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4450        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4451        PrimitiveOp::Xor => (a ^ b) & MASK,
4452        PrimitiveOp::And => (a & b) & MASK,
4453        PrimitiveOp::Or => (a | b) & MASK,
4454        PrimitiveOp::Le => (a <= b) as u32,
4455        PrimitiveOp::Lt => (a < b) as u32,
4456        PrimitiveOp::Ge => (a >= b) as u32,
4457        PrimitiveOp::Gt => (a > b) as u32,
4458        PrimitiveOp::Concat => 0,
4459        PrimitiveOp::Div => {
4460            if b == 0 {
4461                0
4462            } else {
4463                (a / b) & MASK
4464            }
4465        }
4466        PrimitiveOp::Mod => {
4467            if b == 0 {
4468                0
4469            } else {
4470                (a % b) & MASK
4471            }
4472        }
4473        PrimitiveOp::Pow => (const_pow_w24(a, b)) & MASK,
4474        _ => 0,
4475    }
4476}
4477
4478#[inline]
4479#[must_use]
4480pub const fn const_pow_w24(base: u32, exp: u32) -> u32 {
4481    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4482    let mut result: u32 = 1;
4483    let mut b: u32 = (base) & MASK;
4484    let mut e: u32 = exp;
4485    while e > 0 {
4486        if (e & 1) == 1 {
4487            result = (result.wrapping_mul(b)) & MASK;
4488        }
4489        b = (b.wrapping_mul(b)) & MASK;
4490        e >>= 1;
4491    }
4492    result
4493}
4494
4495#[inline]
4496#[must_use]
4497pub const fn const_ring_eval_unary_w24(op: PrimitiveOp, a: u32) -> u32 {
4498    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4499    match op {
4500        PrimitiveOp::Neg => (0u32.wrapping_sub(a)) & MASK,
4501        PrimitiveOp::Bnot => (!a) & MASK,
4502        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4503        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4504        _ => 0,
4505    }
4506}
4507
4508#[inline]
4509#[must_use]
4510#[allow(clippy::manual_checked_ops)]
4511pub const fn const_ring_eval_w32(op: PrimitiveOp, a: u32, b: u32) -> u32 {
4512    match op {
4513        PrimitiveOp::Add => a.wrapping_add(b),
4514        PrimitiveOp::Sub => a.wrapping_sub(b),
4515        PrimitiveOp::Mul => a.wrapping_mul(b),
4516        PrimitiveOp::Xor => a ^ b,
4517        PrimitiveOp::And => a & b,
4518        PrimitiveOp::Or => a | b,
4519        PrimitiveOp::Le => (a <= b) as u32,
4520        PrimitiveOp::Lt => (a < b) as u32,
4521        PrimitiveOp::Ge => (a >= b) as u32,
4522        PrimitiveOp::Gt => (a > b) as u32,
4523        PrimitiveOp::Concat => 0,
4524        PrimitiveOp::Div => {
4525            if b == 0 {
4526                0
4527            } else {
4528                a / b
4529            }
4530        }
4531        PrimitiveOp::Mod => {
4532            if b == 0 {
4533                0
4534            } else {
4535                a % b
4536            }
4537        }
4538        PrimitiveOp::Pow => const_pow_w32(a, b),
4539        _ => 0,
4540    }
4541}
4542
4543#[inline]
4544#[must_use]
4545pub const fn const_pow_w32(base: u32, exp: u32) -> u32 {
4546    let mut result: u32 = 1;
4547    let mut b: u32 = base;
4548    let mut e: u32 = exp;
4549    while e > 0 {
4550        if (e & 1) == 1 {
4551            result = result.wrapping_mul(b);
4552        }
4553        b = b.wrapping_mul(b);
4554        e >>= 1;
4555    }
4556    result
4557}
4558
4559#[inline]
4560#[must_use]
4561pub const fn const_ring_eval_unary_w32(op: PrimitiveOp, a: u32) -> u32 {
4562    match op {
4563        PrimitiveOp::Neg => 0u32.wrapping_sub(a),
4564        PrimitiveOp::Bnot => !a,
4565        PrimitiveOp::Succ => a.wrapping_add(1),
4566        PrimitiveOp::Pred => a.wrapping_sub(1),
4567        _ => 0,
4568    }
4569}
4570
4571#[inline]
4572#[must_use]
4573#[allow(clippy::manual_checked_ops)]
4574pub const fn const_ring_eval_w40(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4575    const MASK: u64 = u64::MAX >> (64 - 40);
4576    match op {
4577        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4578        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4579        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4580        PrimitiveOp::Xor => (a ^ b) & MASK,
4581        PrimitiveOp::And => (a & b) & MASK,
4582        PrimitiveOp::Or => (a | b) & MASK,
4583        PrimitiveOp::Le => (a <= b) as u64,
4584        PrimitiveOp::Lt => (a < b) as u64,
4585        PrimitiveOp::Ge => (a >= b) as u64,
4586        PrimitiveOp::Gt => (a > b) as u64,
4587        PrimitiveOp::Concat => 0,
4588        PrimitiveOp::Div => {
4589            if b == 0 {
4590                0
4591            } else {
4592                (a / b) & MASK
4593            }
4594        }
4595        PrimitiveOp::Mod => {
4596            if b == 0 {
4597                0
4598            } else {
4599                (a % b) & MASK
4600            }
4601        }
4602        PrimitiveOp::Pow => (const_pow_w40(a, b)) & MASK,
4603        _ => 0,
4604    }
4605}
4606
4607#[inline]
4608#[must_use]
4609pub const fn const_pow_w40(base: u64, exp: u64) -> u64 {
4610    const MASK: u64 = u64::MAX >> (64 - 40);
4611    let mut result: u64 = 1;
4612    let mut b: u64 = (base) & MASK;
4613    let mut e: u64 = exp;
4614    while e > 0 {
4615        if (e & 1) == 1 {
4616            result = (result.wrapping_mul(b)) & MASK;
4617        }
4618        b = (b.wrapping_mul(b)) & MASK;
4619        e >>= 1;
4620    }
4621    result
4622}
4623
4624#[inline]
4625#[must_use]
4626pub const fn const_ring_eval_unary_w40(op: PrimitiveOp, a: u64) -> u64 {
4627    const MASK: u64 = u64::MAX >> (64 - 40);
4628    match op {
4629        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4630        PrimitiveOp::Bnot => (!a) & MASK,
4631        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4632        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4633        _ => 0,
4634    }
4635}
4636
4637#[inline]
4638#[must_use]
4639#[allow(clippy::manual_checked_ops)]
4640pub const fn const_ring_eval_w48(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4641    const MASK: u64 = u64::MAX >> (64 - 48);
4642    match op {
4643        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4644        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4645        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4646        PrimitiveOp::Xor => (a ^ b) & MASK,
4647        PrimitiveOp::And => (a & b) & MASK,
4648        PrimitiveOp::Or => (a | b) & MASK,
4649        PrimitiveOp::Le => (a <= b) as u64,
4650        PrimitiveOp::Lt => (a < b) as u64,
4651        PrimitiveOp::Ge => (a >= b) as u64,
4652        PrimitiveOp::Gt => (a > b) as u64,
4653        PrimitiveOp::Concat => 0,
4654        PrimitiveOp::Div => {
4655            if b == 0 {
4656                0
4657            } else {
4658                (a / b) & MASK
4659            }
4660        }
4661        PrimitiveOp::Mod => {
4662            if b == 0 {
4663                0
4664            } else {
4665                (a % b) & MASK
4666            }
4667        }
4668        PrimitiveOp::Pow => (const_pow_w48(a, b)) & MASK,
4669        _ => 0,
4670    }
4671}
4672
4673#[inline]
4674#[must_use]
4675pub const fn const_pow_w48(base: u64, exp: u64) -> u64 {
4676    const MASK: u64 = u64::MAX >> (64 - 48);
4677    let mut result: u64 = 1;
4678    let mut b: u64 = (base) & MASK;
4679    let mut e: u64 = exp;
4680    while e > 0 {
4681        if (e & 1) == 1 {
4682            result = (result.wrapping_mul(b)) & MASK;
4683        }
4684        b = (b.wrapping_mul(b)) & MASK;
4685        e >>= 1;
4686    }
4687    result
4688}
4689
4690#[inline]
4691#[must_use]
4692pub const fn const_ring_eval_unary_w48(op: PrimitiveOp, a: u64) -> u64 {
4693    const MASK: u64 = u64::MAX >> (64 - 48);
4694    match op {
4695        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4696        PrimitiveOp::Bnot => (!a) & MASK,
4697        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4698        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4699        _ => 0,
4700    }
4701}
4702
4703#[inline]
4704#[must_use]
4705#[allow(clippy::manual_checked_ops)]
4706pub const fn const_ring_eval_w56(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4707    const MASK: u64 = u64::MAX >> (64 - 56);
4708    match op {
4709        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4710        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4711        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4712        PrimitiveOp::Xor => (a ^ b) & MASK,
4713        PrimitiveOp::And => (a & b) & MASK,
4714        PrimitiveOp::Or => (a | b) & MASK,
4715        PrimitiveOp::Le => (a <= b) as u64,
4716        PrimitiveOp::Lt => (a < b) as u64,
4717        PrimitiveOp::Ge => (a >= b) as u64,
4718        PrimitiveOp::Gt => (a > b) as u64,
4719        PrimitiveOp::Concat => 0,
4720        PrimitiveOp::Div => {
4721            if b == 0 {
4722                0
4723            } else {
4724                (a / b) & MASK
4725            }
4726        }
4727        PrimitiveOp::Mod => {
4728            if b == 0 {
4729                0
4730            } else {
4731                (a % b) & MASK
4732            }
4733        }
4734        PrimitiveOp::Pow => (const_pow_w56(a, b)) & MASK,
4735        _ => 0,
4736    }
4737}
4738
4739#[inline]
4740#[must_use]
4741pub const fn const_pow_w56(base: u64, exp: u64) -> u64 {
4742    const MASK: u64 = u64::MAX >> (64 - 56);
4743    let mut result: u64 = 1;
4744    let mut b: u64 = (base) & MASK;
4745    let mut e: u64 = exp;
4746    while e > 0 {
4747        if (e & 1) == 1 {
4748            result = (result.wrapping_mul(b)) & MASK;
4749        }
4750        b = (b.wrapping_mul(b)) & MASK;
4751        e >>= 1;
4752    }
4753    result
4754}
4755
4756#[inline]
4757#[must_use]
4758pub const fn const_ring_eval_unary_w56(op: PrimitiveOp, a: u64) -> u64 {
4759    const MASK: u64 = u64::MAX >> (64 - 56);
4760    match op {
4761        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4762        PrimitiveOp::Bnot => (!a) & MASK,
4763        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4764        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4765        _ => 0,
4766    }
4767}
4768
4769#[inline]
4770#[must_use]
4771#[allow(clippy::manual_checked_ops)]
4772pub const fn const_ring_eval_w64(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4773    match op {
4774        PrimitiveOp::Add => a.wrapping_add(b),
4775        PrimitiveOp::Sub => a.wrapping_sub(b),
4776        PrimitiveOp::Mul => a.wrapping_mul(b),
4777        PrimitiveOp::Xor => a ^ b,
4778        PrimitiveOp::And => a & b,
4779        PrimitiveOp::Or => a | b,
4780        PrimitiveOp::Le => (a <= b) as u64,
4781        PrimitiveOp::Lt => (a < b) as u64,
4782        PrimitiveOp::Ge => (a >= b) as u64,
4783        PrimitiveOp::Gt => (a > b) as u64,
4784        PrimitiveOp::Concat => 0,
4785        PrimitiveOp::Div => {
4786            if b == 0 {
4787                0
4788            } else {
4789                a / b
4790            }
4791        }
4792        PrimitiveOp::Mod => {
4793            if b == 0 {
4794                0
4795            } else {
4796                a % b
4797            }
4798        }
4799        PrimitiveOp::Pow => const_pow_w64(a, b),
4800        _ => 0,
4801    }
4802}
4803
4804#[inline]
4805#[must_use]
4806pub const fn const_pow_w64(base: u64, exp: u64) -> u64 {
4807    let mut result: u64 = 1;
4808    let mut b: u64 = base;
4809    let mut e: u64 = exp;
4810    while e > 0 {
4811        if (e & 1) == 1 {
4812            result = result.wrapping_mul(b);
4813        }
4814        b = b.wrapping_mul(b);
4815        e >>= 1;
4816    }
4817    result
4818}
4819
4820#[inline]
4821#[must_use]
4822pub const fn const_ring_eval_unary_w64(op: PrimitiveOp, a: u64) -> u64 {
4823    match op {
4824        PrimitiveOp::Neg => 0u64.wrapping_sub(a),
4825        PrimitiveOp::Bnot => !a,
4826        PrimitiveOp::Succ => a.wrapping_add(1),
4827        PrimitiveOp::Pred => a.wrapping_sub(1),
4828        _ => 0,
4829    }
4830}
4831
4832#[inline]
4833#[must_use]
4834#[allow(clippy::manual_checked_ops)]
4835pub const fn const_ring_eval_w72(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4836    const MASK: u128 = u128::MAX >> (128 - 72);
4837    match op {
4838        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4839        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4840        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4841        PrimitiveOp::Xor => (a ^ b) & MASK,
4842        PrimitiveOp::And => (a & b) & MASK,
4843        PrimitiveOp::Or => (a | b) & MASK,
4844        PrimitiveOp::Le => (a <= b) as u128,
4845        PrimitiveOp::Lt => (a < b) as u128,
4846        PrimitiveOp::Ge => (a >= b) as u128,
4847        PrimitiveOp::Gt => (a > b) as u128,
4848        PrimitiveOp::Concat => 0,
4849        PrimitiveOp::Div => {
4850            if b == 0 {
4851                0
4852            } else {
4853                (a / b) & MASK
4854            }
4855        }
4856        PrimitiveOp::Mod => {
4857            if b == 0 {
4858                0
4859            } else {
4860                (a % b) & MASK
4861            }
4862        }
4863        PrimitiveOp::Pow => (const_pow_w72(a, b)) & MASK,
4864        _ => 0,
4865    }
4866}
4867
4868#[inline]
4869#[must_use]
4870pub const fn const_pow_w72(base: u128, exp: u128) -> u128 {
4871    const MASK: u128 = u128::MAX >> (128 - 72);
4872    let mut result: u128 = 1;
4873    let mut b: u128 = (base) & MASK;
4874    let mut e: u128 = exp;
4875    while e > 0 {
4876        if (e & 1) == 1 {
4877            result = (result.wrapping_mul(b)) & MASK;
4878        }
4879        b = (b.wrapping_mul(b)) & MASK;
4880        e >>= 1;
4881    }
4882    result
4883}
4884
4885#[inline]
4886#[must_use]
4887pub const fn const_ring_eval_unary_w72(op: PrimitiveOp, a: u128) -> u128 {
4888    const MASK: u128 = u128::MAX >> (128 - 72);
4889    match op {
4890        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
4891        PrimitiveOp::Bnot => (!a) & MASK,
4892        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4893        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4894        _ => 0,
4895    }
4896}
4897
4898#[inline]
4899#[must_use]
4900#[allow(clippy::manual_checked_ops)]
4901pub const fn const_ring_eval_w80(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4902    const MASK: u128 = u128::MAX >> (128 - 80);
4903    match op {
4904        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4905        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4906        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4907        PrimitiveOp::Xor => (a ^ b) & MASK,
4908        PrimitiveOp::And => (a & b) & MASK,
4909        PrimitiveOp::Or => (a | b) & MASK,
4910        PrimitiveOp::Le => (a <= b) as u128,
4911        PrimitiveOp::Lt => (a < b) as u128,
4912        PrimitiveOp::Ge => (a >= b) as u128,
4913        PrimitiveOp::Gt => (a > b) as u128,
4914        PrimitiveOp::Concat => 0,
4915        PrimitiveOp::Div => {
4916            if b == 0 {
4917                0
4918            } else {
4919                (a / b) & MASK
4920            }
4921        }
4922        PrimitiveOp::Mod => {
4923            if b == 0 {
4924                0
4925            } else {
4926                (a % b) & MASK
4927            }
4928        }
4929        PrimitiveOp::Pow => (const_pow_w80(a, b)) & MASK,
4930        _ => 0,
4931    }
4932}
4933
4934#[inline]
4935#[must_use]
4936pub const fn const_pow_w80(base: u128, exp: u128) -> u128 {
4937    const MASK: u128 = u128::MAX >> (128 - 80);
4938    let mut result: u128 = 1;
4939    let mut b: u128 = (base) & MASK;
4940    let mut e: u128 = exp;
4941    while e > 0 {
4942        if (e & 1) == 1 {
4943            result = (result.wrapping_mul(b)) & MASK;
4944        }
4945        b = (b.wrapping_mul(b)) & MASK;
4946        e >>= 1;
4947    }
4948    result
4949}
4950
4951#[inline]
4952#[must_use]
4953pub const fn const_ring_eval_unary_w80(op: PrimitiveOp, a: u128) -> u128 {
4954    const MASK: u128 = u128::MAX >> (128 - 80);
4955    match op {
4956        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
4957        PrimitiveOp::Bnot => (!a) & MASK,
4958        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4959        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4960        _ => 0,
4961    }
4962}
4963
4964#[inline]
4965#[must_use]
4966#[allow(clippy::manual_checked_ops)]
4967pub const fn const_ring_eval_w88(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4968    const MASK: u128 = u128::MAX >> (128 - 88);
4969    match op {
4970        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4971        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4972        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4973        PrimitiveOp::Xor => (a ^ b) & MASK,
4974        PrimitiveOp::And => (a & b) & MASK,
4975        PrimitiveOp::Or => (a | b) & MASK,
4976        PrimitiveOp::Le => (a <= b) as u128,
4977        PrimitiveOp::Lt => (a < b) as u128,
4978        PrimitiveOp::Ge => (a >= b) as u128,
4979        PrimitiveOp::Gt => (a > b) as u128,
4980        PrimitiveOp::Concat => 0,
4981        PrimitiveOp::Div => {
4982            if b == 0 {
4983                0
4984            } else {
4985                (a / b) & MASK
4986            }
4987        }
4988        PrimitiveOp::Mod => {
4989            if b == 0 {
4990                0
4991            } else {
4992                (a % b) & MASK
4993            }
4994        }
4995        PrimitiveOp::Pow => (const_pow_w88(a, b)) & MASK,
4996        _ => 0,
4997    }
4998}
4999
5000#[inline]
5001#[must_use]
5002pub const fn const_pow_w88(base: u128, exp: u128) -> u128 {
5003    const MASK: u128 = u128::MAX >> (128 - 88);
5004    let mut result: u128 = 1;
5005    let mut b: u128 = (base) & MASK;
5006    let mut e: u128 = exp;
5007    while e > 0 {
5008        if (e & 1) == 1 {
5009            result = (result.wrapping_mul(b)) & MASK;
5010        }
5011        b = (b.wrapping_mul(b)) & MASK;
5012        e >>= 1;
5013    }
5014    result
5015}
5016
5017#[inline]
5018#[must_use]
5019pub const fn const_ring_eval_unary_w88(op: PrimitiveOp, a: u128) -> u128 {
5020    const MASK: u128 = u128::MAX >> (128 - 88);
5021    match op {
5022        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5023        PrimitiveOp::Bnot => (!a) & MASK,
5024        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5025        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5026        _ => 0,
5027    }
5028}
5029
5030#[inline]
5031#[must_use]
5032#[allow(clippy::manual_checked_ops)]
5033pub const fn const_ring_eval_w96(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5034    const MASK: u128 = u128::MAX >> (128 - 96);
5035    match op {
5036        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5037        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5038        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5039        PrimitiveOp::Xor => (a ^ b) & MASK,
5040        PrimitiveOp::And => (a & b) & MASK,
5041        PrimitiveOp::Or => (a | b) & MASK,
5042        PrimitiveOp::Le => (a <= b) as u128,
5043        PrimitiveOp::Lt => (a < b) as u128,
5044        PrimitiveOp::Ge => (a >= b) as u128,
5045        PrimitiveOp::Gt => (a > b) as u128,
5046        PrimitiveOp::Concat => 0,
5047        PrimitiveOp::Div => {
5048            if b == 0 {
5049                0
5050            } else {
5051                (a / b) & MASK
5052            }
5053        }
5054        PrimitiveOp::Mod => {
5055            if b == 0 {
5056                0
5057            } else {
5058                (a % b) & MASK
5059            }
5060        }
5061        PrimitiveOp::Pow => (const_pow_w96(a, b)) & MASK,
5062        _ => 0,
5063    }
5064}
5065
5066#[inline]
5067#[must_use]
5068pub const fn const_pow_w96(base: u128, exp: u128) -> u128 {
5069    const MASK: u128 = u128::MAX >> (128 - 96);
5070    let mut result: u128 = 1;
5071    let mut b: u128 = (base) & MASK;
5072    let mut e: u128 = exp;
5073    while e > 0 {
5074        if (e & 1) == 1 {
5075            result = (result.wrapping_mul(b)) & MASK;
5076        }
5077        b = (b.wrapping_mul(b)) & MASK;
5078        e >>= 1;
5079    }
5080    result
5081}
5082
5083#[inline]
5084#[must_use]
5085pub const fn const_ring_eval_unary_w96(op: PrimitiveOp, a: u128) -> u128 {
5086    const MASK: u128 = u128::MAX >> (128 - 96);
5087    match op {
5088        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5089        PrimitiveOp::Bnot => (!a) & MASK,
5090        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5091        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5092        _ => 0,
5093    }
5094}
5095
5096#[inline]
5097#[must_use]
5098#[allow(clippy::manual_checked_ops)]
5099pub const fn const_ring_eval_w104(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5100    const MASK: u128 = u128::MAX >> (128 - 104);
5101    match op {
5102        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5103        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5104        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5105        PrimitiveOp::Xor => (a ^ b) & MASK,
5106        PrimitiveOp::And => (a & b) & MASK,
5107        PrimitiveOp::Or => (a | b) & MASK,
5108        PrimitiveOp::Le => (a <= b) as u128,
5109        PrimitiveOp::Lt => (a < b) as u128,
5110        PrimitiveOp::Ge => (a >= b) as u128,
5111        PrimitiveOp::Gt => (a > b) as u128,
5112        PrimitiveOp::Concat => 0,
5113        PrimitiveOp::Div => {
5114            if b == 0 {
5115                0
5116            } else {
5117                (a / b) & MASK
5118            }
5119        }
5120        PrimitiveOp::Mod => {
5121            if b == 0 {
5122                0
5123            } else {
5124                (a % b) & MASK
5125            }
5126        }
5127        PrimitiveOp::Pow => (const_pow_w104(a, b)) & MASK,
5128        _ => 0,
5129    }
5130}
5131
5132#[inline]
5133#[must_use]
5134pub const fn const_pow_w104(base: u128, exp: u128) -> u128 {
5135    const MASK: u128 = u128::MAX >> (128 - 104);
5136    let mut result: u128 = 1;
5137    let mut b: u128 = (base) & MASK;
5138    let mut e: u128 = exp;
5139    while e > 0 {
5140        if (e & 1) == 1 {
5141            result = (result.wrapping_mul(b)) & MASK;
5142        }
5143        b = (b.wrapping_mul(b)) & MASK;
5144        e >>= 1;
5145    }
5146    result
5147}
5148
5149#[inline]
5150#[must_use]
5151pub const fn const_ring_eval_unary_w104(op: PrimitiveOp, a: u128) -> u128 {
5152    const MASK: u128 = u128::MAX >> (128 - 104);
5153    match op {
5154        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5155        PrimitiveOp::Bnot => (!a) & MASK,
5156        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5157        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5158        _ => 0,
5159    }
5160}
5161
5162#[inline]
5163#[must_use]
5164#[allow(clippy::manual_checked_ops)]
5165pub const fn const_ring_eval_w112(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5166    const MASK: u128 = u128::MAX >> (128 - 112);
5167    match op {
5168        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5169        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5170        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5171        PrimitiveOp::Xor => (a ^ b) & MASK,
5172        PrimitiveOp::And => (a & b) & MASK,
5173        PrimitiveOp::Or => (a | b) & MASK,
5174        PrimitiveOp::Le => (a <= b) as u128,
5175        PrimitiveOp::Lt => (a < b) as u128,
5176        PrimitiveOp::Ge => (a >= b) as u128,
5177        PrimitiveOp::Gt => (a > b) as u128,
5178        PrimitiveOp::Concat => 0,
5179        PrimitiveOp::Div => {
5180            if b == 0 {
5181                0
5182            } else {
5183                (a / b) & MASK
5184            }
5185        }
5186        PrimitiveOp::Mod => {
5187            if b == 0 {
5188                0
5189            } else {
5190                (a % b) & MASK
5191            }
5192        }
5193        PrimitiveOp::Pow => (const_pow_w112(a, b)) & MASK,
5194        _ => 0,
5195    }
5196}
5197
5198#[inline]
5199#[must_use]
5200pub const fn const_pow_w112(base: u128, exp: u128) -> u128 {
5201    const MASK: u128 = u128::MAX >> (128 - 112);
5202    let mut result: u128 = 1;
5203    let mut b: u128 = (base) & MASK;
5204    let mut e: u128 = exp;
5205    while e > 0 {
5206        if (e & 1) == 1 {
5207            result = (result.wrapping_mul(b)) & MASK;
5208        }
5209        b = (b.wrapping_mul(b)) & MASK;
5210        e >>= 1;
5211    }
5212    result
5213}
5214
5215#[inline]
5216#[must_use]
5217pub const fn const_ring_eval_unary_w112(op: PrimitiveOp, a: u128) -> u128 {
5218    const MASK: u128 = u128::MAX >> (128 - 112);
5219    match op {
5220        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5221        PrimitiveOp::Bnot => (!a) & MASK,
5222        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5223        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5224        _ => 0,
5225    }
5226}
5227
5228#[inline]
5229#[must_use]
5230#[allow(clippy::manual_checked_ops)]
5231pub const fn const_ring_eval_w120(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5232    const MASK: u128 = u128::MAX >> (128 - 120);
5233    match op {
5234        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5235        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5236        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5237        PrimitiveOp::Xor => (a ^ b) & MASK,
5238        PrimitiveOp::And => (a & b) & MASK,
5239        PrimitiveOp::Or => (a | b) & MASK,
5240        PrimitiveOp::Le => (a <= b) as u128,
5241        PrimitiveOp::Lt => (a < b) as u128,
5242        PrimitiveOp::Ge => (a >= b) as u128,
5243        PrimitiveOp::Gt => (a > b) as u128,
5244        PrimitiveOp::Concat => 0,
5245        PrimitiveOp::Div => {
5246            if b == 0 {
5247                0
5248            } else {
5249                (a / b) & MASK
5250            }
5251        }
5252        PrimitiveOp::Mod => {
5253            if b == 0 {
5254                0
5255            } else {
5256                (a % b) & MASK
5257            }
5258        }
5259        PrimitiveOp::Pow => (const_pow_w120(a, b)) & MASK,
5260        _ => 0,
5261    }
5262}
5263
5264#[inline]
5265#[must_use]
5266pub const fn const_pow_w120(base: u128, exp: u128) -> u128 {
5267    const MASK: u128 = u128::MAX >> (128 - 120);
5268    let mut result: u128 = 1;
5269    let mut b: u128 = (base) & MASK;
5270    let mut e: u128 = exp;
5271    while e > 0 {
5272        if (e & 1) == 1 {
5273            result = (result.wrapping_mul(b)) & MASK;
5274        }
5275        b = (b.wrapping_mul(b)) & MASK;
5276        e >>= 1;
5277    }
5278    result
5279}
5280
5281#[inline]
5282#[must_use]
5283pub const fn const_ring_eval_unary_w120(op: PrimitiveOp, a: u128) -> u128 {
5284    const MASK: u128 = u128::MAX >> (128 - 120);
5285    match op {
5286        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5287        PrimitiveOp::Bnot => (!a) & MASK,
5288        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5289        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5290        _ => 0,
5291    }
5292}
5293
5294#[inline]
5295#[must_use]
5296#[allow(clippy::manual_checked_ops)]
5297pub const fn const_ring_eval_w128(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5298    match op {
5299        PrimitiveOp::Add => a.wrapping_add(b),
5300        PrimitiveOp::Sub => a.wrapping_sub(b),
5301        PrimitiveOp::Mul => a.wrapping_mul(b),
5302        PrimitiveOp::Xor => a ^ b,
5303        PrimitiveOp::And => a & b,
5304        PrimitiveOp::Or => a | b,
5305        PrimitiveOp::Le => (a <= b) as u128,
5306        PrimitiveOp::Lt => (a < b) as u128,
5307        PrimitiveOp::Ge => (a >= b) as u128,
5308        PrimitiveOp::Gt => (a > b) as u128,
5309        PrimitiveOp::Concat => 0,
5310        PrimitiveOp::Div => {
5311            if b == 0 {
5312                0
5313            } else {
5314                a / b
5315            }
5316        }
5317        PrimitiveOp::Mod => {
5318            if b == 0 {
5319                0
5320            } else {
5321                a % b
5322            }
5323        }
5324        PrimitiveOp::Pow => const_pow_w128(a, b),
5325        _ => 0,
5326    }
5327}
5328
5329#[inline]
5330#[must_use]
5331pub const fn const_pow_w128(base: u128, exp: u128) -> u128 {
5332    let mut result: u128 = 1;
5333    let mut b: u128 = base;
5334    let mut e: u128 = exp;
5335    while e > 0 {
5336        if (e & 1) == 1 {
5337            result = result.wrapping_mul(b);
5338        }
5339        b = b.wrapping_mul(b);
5340        e >>= 1;
5341    }
5342    result
5343}
5344
5345#[inline]
5346#[must_use]
5347pub const fn const_ring_eval_unary_w128(op: PrimitiveOp, a: u128) -> u128 {
5348    match op {
5349        PrimitiveOp::Neg => 0u128.wrapping_sub(a),
5350        PrimitiveOp::Bnot => !a,
5351        PrimitiveOp::Succ => a.wrapping_add(1),
5352        PrimitiveOp::Pred => a.wrapping_sub(1),
5353        _ => 0,
5354    }
5355}
5356
5357/// v0.2.2 Phase C.3: foundation-internal generic backing for Witt
5358/// levels above W128. Holds an inline `[u64; N]` array with no heap
5359/// allocation, no global state, and `const fn` arithmetic throughout.
5360/// Constructors are `pub(crate)`; downstream cannot fabricate a `Limbs<N>`.
5361/// Multiplication is schoolbook-only at v0.2.2 Phase C.3; the Toom-Cook
5362/// framework with parametric splitting factor `R` ships in Phase C.4 via
5363/// the `resolver::multiplication::certify` resolver, which decides `R`
5364/// per call from a Landauer cost function constrained by stack budget.
5365#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5366pub struct Limbs<const N: usize> {
5367    /// Little-endian limbs: `words[0]` is the low 64 bits.
5368    words: [u64; N],
5369    /// Prevents external construction.
5370    _sealed: (),
5371}
5372
5373impl<const N: usize> Limbs<N> {
5374    /// Crate-internal constructor from a fixed-size limb array.
5375    #[inline]
5376    #[must_use]
5377    #[allow(dead_code)]
5378    pub(crate) const fn from_words(words: [u64; N]) -> Self {
5379        Self { words, _sealed: () }
5380    }
5381
5382    /// All-zeros constructor.
5383    #[inline]
5384    #[must_use]
5385    #[allow(dead_code)]
5386    pub(crate) const fn zero() -> Self {
5387        Self {
5388            words: [0u64; N],
5389            _sealed: (),
5390        }
5391    }
5392
5393    /// Returns a reference to the underlying limb array.
5394    #[inline]
5395    #[must_use]
5396    pub const fn words(&self) -> &[u64; N] {
5397        &self.words
5398    }
5399
5400    /// Wrapping addition mod 2^(64*N). Const-fn schoolbook with carry.
5401    #[inline]
5402    #[must_use]
5403    #[allow(dead_code)]
5404    pub(crate) const fn wrapping_add(self, other: Self) -> Self {
5405        let mut out = [0u64; N];
5406        let mut carry: u64 = 0;
5407        let mut i = 0;
5408        while i < N {
5409            let (s1, c1) = self.words[i].overflowing_add(other.words[i]);
5410            let (s2, c2) = s1.overflowing_add(carry);
5411            out[i] = s2;
5412            carry = (c1 as u64) | (c2 as u64);
5413            i += 1;
5414        }
5415        Self {
5416            words: out,
5417            _sealed: (),
5418        }
5419    }
5420
5421    /// Wrapping subtraction mod 2^(64*N). Const-fn schoolbook with borrow.
5422    #[inline]
5423    #[must_use]
5424    #[allow(dead_code)]
5425    pub(crate) const fn wrapping_sub(self, other: Self) -> Self {
5426        let mut out = [0u64; N];
5427        let mut borrow: u64 = 0;
5428        let mut i = 0;
5429        while i < N {
5430            let (d1, b1) = self.words[i].overflowing_sub(other.words[i]);
5431            let (d2, b2) = d1.overflowing_sub(borrow);
5432            out[i] = d2;
5433            borrow = (b1 as u64) | (b2 as u64);
5434            i += 1;
5435        }
5436        Self {
5437            words: out,
5438            _sealed: (),
5439        }
5440    }
5441
5442    /// Wrapping schoolbook multiplication mod 2^(64*N). The high N limbs of
5443    /// the 2N-limb full product are discarded (mod 2^bits truncation).
5444    /// v0.2.2 Phase C.3: schoolbook only. Phase C.4 adds the Toom-Cook
5445    /// framework with parametric R via `resolver::multiplication::certify`.
5446    #[inline]
5447    #[must_use]
5448    #[allow(dead_code)]
5449    pub(crate) const fn wrapping_mul(self, other: Self) -> Self {
5450        let mut out = [0u64; N];
5451        let mut i = 0;
5452        while i < N {
5453            let mut carry: u128 = 0;
5454            let mut j = 0;
5455            while j < N - i {
5456                let prod = (self.words[i] as u128) * (other.words[j] as u128)
5457                    + (out[i + j] as u128)
5458                    + carry;
5459                out[i + j] = prod as u64;
5460                carry = prod >> 64;
5461                j += 1;
5462            }
5463            i += 1;
5464        }
5465        Self {
5466            words: out,
5467            _sealed: (),
5468        }
5469    }
5470
5471    /// Bitwise XOR.
5472    #[inline]
5473    #[must_use]
5474    #[allow(dead_code)]
5475    pub(crate) const fn xor(self, other: Self) -> Self {
5476        let mut out = [0u64; N];
5477        let mut i = 0;
5478        while i < N {
5479            out[i] = self.words[i] ^ other.words[i];
5480            i += 1;
5481        }
5482        Self {
5483            words: out,
5484            _sealed: (),
5485        }
5486    }
5487
5488    /// Bitwise AND.
5489    #[inline]
5490    #[must_use]
5491    #[allow(dead_code)]
5492    pub(crate) const fn and(self, other: Self) -> Self {
5493        let mut out = [0u64; N];
5494        let mut i = 0;
5495        while i < N {
5496            out[i] = self.words[i] & other.words[i];
5497            i += 1;
5498        }
5499        Self {
5500            words: out,
5501            _sealed: (),
5502        }
5503    }
5504
5505    /// Bitwise OR.
5506    #[inline]
5507    #[must_use]
5508    #[allow(dead_code)]
5509    pub(crate) const fn or(self, other: Self) -> Self {
5510        let mut out = [0u64; N];
5511        let mut i = 0;
5512        while i < N {
5513            out[i] = self.words[i] | other.words[i];
5514            i += 1;
5515        }
5516        Self {
5517            words: out,
5518            _sealed: (),
5519        }
5520    }
5521
5522    /// Bitwise NOT.
5523    #[inline]
5524    #[must_use]
5525    #[allow(dead_code)]
5526    pub(crate) const fn not(self) -> Self {
5527        let mut out = [0u64; N];
5528        let mut i = 0;
5529        while i < N {
5530            out[i] = !self.words[i];
5531            i += 1;
5532        }
5533        Self {
5534            words: out,
5535            _sealed: (),
5536        }
5537    }
5538
5539    /// Mask the high bits of the value to keep only the low `bits` bits.
5540    /// Used at the arithmetic boundary for non-exact-fit Witt widths (e.g.,
5541    /// W160 over `Limbs<3>`: 64+64+32 bits = mask the upper 32 bits of words[2]).
5542    #[inline]
5543    #[must_use]
5544    #[allow(dead_code)]
5545    pub(crate) const fn mask_high_bits(self, bits: u32) -> Self {
5546        let mut out = self.words;
5547        let high_word_idx = (bits / 64) as usize;
5548        let low_bits_in_high_word = bits % 64;
5549        if low_bits_in_high_word != 0 && high_word_idx < N {
5550            let mask = (1u64 << low_bits_in_high_word) - 1;
5551            out[high_word_idx] &= mask;
5552            // Zero everything above the high word.
5553            let mut i = high_word_idx + 1;
5554            while i < N {
5555                out[i] = 0;
5556                i += 1;
5557            }
5558        } else if low_bits_in_high_word == 0 && high_word_idx < N {
5559            // bits is exactly a multiple of 64; zero everything from high_word_idx.
5560            let mut i = high_word_idx;
5561            while i < N {
5562                out[i] = 0;
5563                i += 1;
5564            }
5565        }
5566        Self {
5567            words: out,
5568            _sealed: (),
5569        }
5570    }
5571}
5572
5573/// Sealed marker trait identifying types produced by the foundation crate's
5574/// conformance/reduction pipeline. v0.2.1 bounds `Validated<T>` on this trait
5575/// so downstream crates cannot fabricate `Validated<UserType>` — user types
5576/// cannot impl `OntologyTarget` because the supertrait is private.
5577pub trait OntologyTarget: ontology_target_sealed::Sealed {}
5578
5579/// Sealed shim for `cert:GroundingCertificate`. Produced by GroundingAwareResolver.
5580#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5581pub struct GroundingCertificate {
5582    witt_bits: u16,
5583    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5584    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5585    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5586    /// are never equal even when leading bytes coincide.
5587    content_fingerprint: ContentFingerprint,
5588}
5589
5590impl GroundingCertificate {
5591    /// Returns the Witt level the certificate was issued for. Sourced
5592    /// from the pipeline's substrate hash output at minting time.
5593    #[inline]
5594    #[must_use]
5595    pub const fn witt_bits(&self) -> u16 {
5596        self.witt_bits
5597    }
5598
5599    /// v0.2.2 T5: returns the parametric content fingerprint of the
5600    /// source state, computed at mint time by the consumer-supplied
5601    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5602    /// certificates from different hashers are never equal because
5603    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5604    #[inline]
5605    #[must_use]
5606    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5607        self.content_fingerprint
5608    }
5609
5610    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5611    /// witt-bits value AND the parametric content fingerprint. Used by
5612    /// `pipeline::run` and `certify_*_const` to mint a certificate
5613    /// carrying the substrate-computed fingerprint of the source state.
5614    #[inline]
5615    #[must_use]
5616    #[allow(dead_code)]
5617    pub(crate) const fn with_level_and_fingerprint_const(
5618        witt_bits: u16,
5619        content_fingerprint: ContentFingerprint,
5620    ) -> Self {
5621        Self {
5622            witt_bits,
5623            content_fingerprint,
5624        }
5625    }
5626}
5627
5628/// Sealed shim for `cert:LiftChainCertificate`. Carries the v0.2.1 `target_level()` accessor populated from the pipeline's StageOutcome.
5629#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5630pub struct LiftChainCertificate {
5631    witt_bits: u16,
5632    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5633    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5634    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5635    /// are never equal even when leading bytes coincide.
5636    content_fingerprint: ContentFingerprint,
5637}
5638
5639impl LiftChainCertificate {
5640    /// Returns the Witt level the certificate was issued for. Sourced
5641    /// from the pipeline's substrate hash output at minting time.
5642    #[inline]
5643    #[must_use]
5644    pub const fn witt_bits(&self) -> u16 {
5645        self.witt_bits
5646    }
5647
5648    /// v0.2.2 T5: returns the parametric content fingerprint of the
5649    /// source state, computed at mint time by the consumer-supplied
5650    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5651    /// certificates from different hashers are never equal because
5652    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5653    #[inline]
5654    #[must_use]
5655    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5656        self.content_fingerprint
5657    }
5658
5659    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5660    /// witt-bits value AND the parametric content fingerprint. Used by
5661    /// `pipeline::run` and `certify_*_const` to mint a certificate
5662    /// carrying the substrate-computed fingerprint of the source state.
5663    #[inline]
5664    #[must_use]
5665    #[allow(dead_code)]
5666    pub(crate) const fn with_level_and_fingerprint_const(
5667        witt_bits: u16,
5668        content_fingerprint: ContentFingerprint,
5669    ) -> Self {
5670        Self {
5671            witt_bits,
5672            content_fingerprint,
5673        }
5674    }
5675}
5676
5677/// Sealed shim for `cert:InhabitanceCertificate` (v0.2.1).
5678#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5679pub struct InhabitanceCertificate {
5680    witt_bits: u16,
5681    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5682    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5683    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5684    /// are never equal even when leading bytes coincide.
5685    content_fingerprint: ContentFingerprint,
5686}
5687
5688impl InhabitanceCertificate {
5689    /// Returns the Witt level the certificate was issued for. Sourced
5690    /// from the pipeline's substrate hash output at minting time.
5691    #[inline]
5692    #[must_use]
5693    pub const fn witt_bits(&self) -> u16 {
5694        self.witt_bits
5695    }
5696
5697    /// v0.2.2 T5: returns the parametric content fingerprint of the
5698    /// source state, computed at mint time by the consumer-supplied
5699    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5700    /// certificates from different hashers are never equal because
5701    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5702    #[inline]
5703    #[must_use]
5704    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5705        self.content_fingerprint
5706    }
5707
5708    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5709    /// witt-bits value AND the parametric content fingerprint. Used by
5710    /// `pipeline::run` and `certify_*_const` to mint a certificate
5711    /// carrying the substrate-computed fingerprint of the source state.
5712    #[inline]
5713    #[must_use]
5714    #[allow(dead_code)]
5715    pub(crate) const fn with_level_and_fingerprint_const(
5716        witt_bits: u16,
5717        content_fingerprint: ContentFingerprint,
5718    ) -> Self {
5719        Self {
5720            witt_bits,
5721            content_fingerprint,
5722        }
5723    }
5724}
5725
5726/// Sealed shim for `cert:CompletenessCertificate`.
5727#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5728pub struct CompletenessCertificate {
5729    witt_bits: u16,
5730    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5731    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5732    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5733    /// are never equal even when leading bytes coincide.
5734    content_fingerprint: ContentFingerprint,
5735}
5736
5737impl CompletenessCertificate {
5738    /// Returns the Witt level the certificate was issued for. Sourced
5739    /// from the pipeline's substrate hash output at minting time.
5740    #[inline]
5741    #[must_use]
5742    pub const fn witt_bits(&self) -> u16 {
5743        self.witt_bits
5744    }
5745
5746    /// v0.2.2 T5: returns the parametric content fingerprint of the
5747    /// source state, computed at mint time by the consumer-supplied
5748    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5749    /// certificates from different hashers are never equal because
5750    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5751    #[inline]
5752    #[must_use]
5753    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5754        self.content_fingerprint
5755    }
5756
5757    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5758    /// witt-bits value AND the parametric content fingerprint. Used by
5759    /// `pipeline::run` and `certify_*_const` to mint a certificate
5760    /// carrying the substrate-computed fingerprint of the source state.
5761    #[inline]
5762    #[must_use]
5763    #[allow(dead_code)]
5764    pub(crate) const fn with_level_and_fingerprint_const(
5765        witt_bits: u16,
5766        content_fingerprint: ContentFingerprint,
5767    ) -> Self {
5768        Self {
5769            witt_bits,
5770            content_fingerprint,
5771        }
5772    }
5773}
5774
5775/// Sealed shim for `cert:MultiplicationCertificate` (v0.2.2 Phase C.4). Carries the cost-optimal Toom-Cook splitting factor R, the recursive sub-multiplication count, and the accumulated Landauer cost in nats.
5776#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5777pub struct MultiplicationCertificate {
5778    witt_bits: u16,
5779    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5780    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5781    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5782    /// are never equal even when leading bytes coincide.
5783    content_fingerprint: ContentFingerprint,
5784}
5785
5786impl MultiplicationCertificate {
5787    /// Returns the Witt level the certificate was issued for. Sourced
5788    /// from the pipeline's substrate hash output at minting time.
5789    #[inline]
5790    #[must_use]
5791    pub const fn witt_bits(&self) -> u16 {
5792        self.witt_bits
5793    }
5794
5795    /// v0.2.2 T5: returns the parametric content fingerprint of the
5796    /// source state, computed at mint time by the consumer-supplied
5797    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5798    /// certificates from different hashers are never equal because
5799    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5800    #[inline]
5801    #[must_use]
5802    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5803        self.content_fingerprint
5804    }
5805
5806    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5807    /// witt-bits value AND the parametric content fingerprint. Used by
5808    /// `pipeline::run` and `certify_*_const` to mint a certificate
5809    /// carrying the substrate-computed fingerprint of the source state.
5810    #[inline]
5811    #[must_use]
5812    #[allow(dead_code)]
5813    pub(crate) const fn with_level_and_fingerprint_const(
5814        witt_bits: u16,
5815        content_fingerprint: ContentFingerprint,
5816    ) -> Self {
5817        Self {
5818            witt_bits,
5819            content_fingerprint,
5820        }
5821    }
5822}
5823
5824/// Sealed shim for `cert:PartitionCertificate` (v0.2.2 Phase E). Attests the partition component classification of a Datum.
5825#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5826pub struct PartitionCertificate {
5827    witt_bits: u16,
5828    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5829    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5830    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5831    /// are never equal even when leading bytes coincide.
5832    content_fingerprint: ContentFingerprint,
5833}
5834
5835impl PartitionCertificate {
5836    /// Returns the Witt level the certificate was issued for. Sourced
5837    /// from the pipeline's substrate hash output at minting time.
5838    #[inline]
5839    #[must_use]
5840    pub const fn witt_bits(&self) -> u16 {
5841        self.witt_bits
5842    }
5843
5844    /// v0.2.2 T5: returns the parametric content fingerprint of the
5845    /// source state, computed at mint time by the consumer-supplied
5846    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5847    /// certificates from different hashers are never equal because
5848    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5849    #[inline]
5850    #[must_use]
5851    pub const fn content_fingerprint(&self) -> ContentFingerprint {
5852        self.content_fingerprint
5853    }
5854
5855    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5856    /// witt-bits value AND the parametric content fingerprint. Used by
5857    /// `pipeline::run` and `certify_*_const` to mint a certificate
5858    /// carrying the substrate-computed fingerprint of the source state.
5859    #[inline]
5860    #[must_use]
5861    #[allow(dead_code)]
5862    pub(crate) const fn with_level_and_fingerprint_const(
5863        witt_bits: u16,
5864        content_fingerprint: ContentFingerprint,
5865    ) -> Self {
5866        Self {
5867            witt_bits,
5868            content_fingerprint,
5869        }
5870    }
5871}
5872
5873/// Sealed shim for `proof:ImpossibilityWitness`. Returned by completeness and grounding resolvers on failure.
5874#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5875pub struct GenericImpossibilityWitness {
5876    /// Optional theorem / invariant IRI identifying the failed identity.
5877    /// `None` for legacy call sites minting via `Default::default()`;
5878    /// `Some(iri)` when the witness is constructed via `for_identity`
5879    /// (Product/Coproduct Completion Amendment §2.3a).
5880    identity: Option<&'static str>,
5881}
5882
5883impl Default for GenericImpossibilityWitness {
5884    #[inline]
5885    fn default() -> Self {
5886        Self { identity: None }
5887    }
5888}
5889
5890impl GenericImpossibilityWitness {
5891    /// Construct a witness citing a specific theorem / invariant IRI.
5892    /// Introduced by the Product/Coproduct Completion Amendment §2.3a
5893    /// so mint primitives can emit typed failures against `op/*` theorems
5894    /// and `foundation/*` layout invariants.
5895    #[inline]
5896    #[must_use]
5897    pub const fn for_identity(identity: &'static str) -> Self {
5898        Self {
5899            identity: Some(identity),
5900        }
5901    }
5902
5903    /// Returns the theorem / invariant IRI this witness cites, if any.
5904    #[inline]
5905    #[must_use]
5906    pub const fn identity(&self) -> Option<&'static str> {
5907        self.identity
5908    }
5909}
5910
5911/// Sealed shim for `proof:InhabitanceImpossibilityWitness` (v0.2.1).
5912#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5913pub struct InhabitanceImpossibilityWitness {
5914    _private: (),
5915}
5916
5917/// Input shim for `type:ConstrainedType`. Used as `Certify::Input` for InhabitanceResolver, TowerCompletenessResolver, and IncrementalCompletenessResolver.
5918#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5919pub struct ConstrainedTypeInput {
5920    _private: (),
5921}
5922
5923impl core::fmt::Display for GenericImpossibilityWitness {
5924    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5925        match self.identity {
5926            Some(iri) => write!(f, "GenericImpossibilityWitness({iri})"),
5927            None => f.write_str("GenericImpossibilityWitness"),
5928        }
5929    }
5930}
5931impl core::error::Error for GenericImpossibilityWitness {}
5932
5933impl core::fmt::Display for InhabitanceImpossibilityWitness {
5934    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5935        f.write_str("InhabitanceImpossibilityWitness")
5936    }
5937}
5938impl core::error::Error for InhabitanceImpossibilityWitness {}
5939
5940impl LiftChainCertificate {
5941    /// Returns the Witt level the certificate was issued for.
5942    #[inline]
5943    #[must_use]
5944    pub const fn target_level(&self) -> WittLevel {
5945        WittLevel::new(self.witt_bits as u32)
5946    }
5947}
5948
5949impl InhabitanceCertificate {
5950    /// Returns the witness value tuple bytes when `verified` is true.
5951    /// The sealed shim returns `None`; real witnesses flow through the
5952    /// macro back-door path.
5953    #[inline]
5954    #[must_use]
5955    pub const fn witness(&self) -> Option<&'static [u8]> {
5956        None
5957    }
5958}
5959
5960pub(crate) mod ontology_target_sealed {
5961    /// Private supertrait. Not implementable outside this crate.
5962    pub trait Sealed {}
5963    impl Sealed for super::GroundingCertificate {}
5964    impl Sealed for super::LiftChainCertificate {}
5965    impl Sealed for super::InhabitanceCertificate {}
5966    impl Sealed for super::CompletenessCertificate {}
5967    impl Sealed for super::MultiplicationCertificate {}
5968    impl Sealed for super::PartitionCertificate {}
5969    impl Sealed for super::GenericImpossibilityWitness {}
5970    impl Sealed for super::InhabitanceImpossibilityWitness {}
5971    impl Sealed for super::ConstrainedTypeInput {}
5972    impl Sealed for super::PartitionProductWitness {}
5973    impl Sealed for super::PartitionCoproductWitness {}
5974    impl Sealed for super::CartesianProductWitness {}
5975    impl Sealed for super::CompileUnit<'_> {}
5976}
5977
5978impl OntologyTarget for GroundingCertificate {}
5979impl OntologyTarget for LiftChainCertificate {}
5980impl OntologyTarget for InhabitanceCertificate {}
5981impl OntologyTarget for CompletenessCertificate {}
5982impl OntologyTarget for MultiplicationCertificate {}
5983impl OntologyTarget for PartitionCertificate {}
5984impl OntologyTarget for GenericImpossibilityWitness {}
5985impl OntologyTarget for InhabitanceImpossibilityWitness {}
5986impl OntologyTarget for ConstrainedTypeInput {}
5987impl OntologyTarget for PartitionProductWitness {}
5988impl OntologyTarget for PartitionCoproductWitness {}
5989impl OntologyTarget for CartesianProductWitness {}
5990impl OntologyTarget for CompileUnit<'_> {}
5991
5992/// v0.2.2 W11: supporting evidence type for `CompletenessCertificate`.
5993/// Linked from the certificate via the `Certificate::Evidence` associated type.
5994#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5995pub struct CompletenessAuditTrail {
5996    _private: (),
5997}
5998
5999/// v0.2.2 W11: supporting evidence type for `LiftChainCertificate`.
6000#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6001pub struct ChainAuditTrail {
6002    _private: (),
6003}
6004
6005/// v0.2.2 W11: supporting evidence type for `GeodesicCertificate`.
6006#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6007pub struct GeodesicEvidenceBundle {
6008    _private: (),
6009}
6010
6011/// v0.2.2 W11: sealed carrier for `cert:TransformCertificate`.
6012/// Phase X.1: minted with a Witt level and content fingerprint so the
6013/// resolver whose `resolver:CertifyMapping` produces this class can fold
6014/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6015/// constructor matches every other `cert:Certificate` subclass.
6016#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6017pub struct TransformCertificate {
6018    witt_bits: u16,
6019    content_fingerprint: ContentFingerprint,
6020    _private: (),
6021}
6022
6023impl TransformCertificate {
6024    /// Phase X.1: content-addressed constructor. Mints a certificate
6025    /// carrying the Witt level and substrate-hasher fingerprint of the
6026    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6027    #[inline]
6028    #[must_use]
6029    #[allow(dead_code)]
6030    pub(crate) const fn with_level_and_fingerprint_const(
6031        witt_bits: u16,
6032        content_fingerprint: ContentFingerprint,
6033    ) -> Self {
6034        Self {
6035            witt_bits,
6036            content_fingerprint,
6037            _private: (),
6038        }
6039    }
6040
6041    /// Phase X.1: legacy zero-fingerprint constructor retained for
6042    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6043    #[inline]
6044    #[must_use]
6045    #[allow(dead_code)]
6046    pub(crate) const fn empty_const() -> Self {
6047        Self {
6048            witt_bits: 0,
6049            content_fingerprint: ContentFingerprint::zero(),
6050            _private: (),
6051        }
6052    }
6053
6054    /// Phase X.1: the Witt level at which this certificate was minted.
6055    #[inline]
6056    #[must_use]
6057    pub const fn witt_bits(&self) -> u16 {
6058        self.witt_bits
6059    }
6060
6061    /// Phase X.1: the content fingerprint of the resolver decision.
6062    #[inline]
6063    #[must_use]
6064    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6065        self.content_fingerprint
6066    }
6067}
6068
6069/// v0.2.2 W11: sealed carrier for `cert:IsometryCertificate`.
6070/// Phase X.1: minted with a Witt level and content fingerprint so the
6071/// resolver whose `resolver:CertifyMapping` produces this class can fold
6072/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6073/// constructor matches every other `cert:Certificate` subclass.
6074#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6075pub struct IsometryCertificate {
6076    witt_bits: u16,
6077    content_fingerprint: ContentFingerprint,
6078    _private: (),
6079}
6080
6081impl IsometryCertificate {
6082    /// Phase X.1: content-addressed constructor. Mints a certificate
6083    /// carrying the Witt level and substrate-hasher fingerprint of the
6084    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6085    #[inline]
6086    #[must_use]
6087    #[allow(dead_code)]
6088    pub(crate) const fn with_level_and_fingerprint_const(
6089        witt_bits: u16,
6090        content_fingerprint: ContentFingerprint,
6091    ) -> Self {
6092        Self {
6093            witt_bits,
6094            content_fingerprint,
6095            _private: (),
6096        }
6097    }
6098
6099    /// Phase X.1: legacy zero-fingerprint constructor retained for
6100    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6101    #[inline]
6102    #[must_use]
6103    #[allow(dead_code)]
6104    pub(crate) const fn empty_const() -> Self {
6105        Self {
6106            witt_bits: 0,
6107            content_fingerprint: ContentFingerprint::zero(),
6108            _private: (),
6109        }
6110    }
6111
6112    /// Phase X.1: the Witt level at which this certificate was minted.
6113    #[inline]
6114    #[must_use]
6115    pub const fn witt_bits(&self) -> u16 {
6116        self.witt_bits
6117    }
6118
6119    /// Phase X.1: the content fingerprint of the resolver decision.
6120    #[inline]
6121    #[must_use]
6122    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6123        self.content_fingerprint
6124    }
6125}
6126
6127/// v0.2.2 W11: sealed carrier for `cert:InvolutionCertificate`.
6128/// Phase X.1: minted with a Witt level and content fingerprint so the
6129/// resolver whose `resolver:CertifyMapping` produces this class can fold
6130/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6131/// constructor matches every other `cert:Certificate` subclass.
6132#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6133pub struct InvolutionCertificate {
6134    witt_bits: u16,
6135    content_fingerprint: ContentFingerprint,
6136    _private: (),
6137}
6138
6139impl InvolutionCertificate {
6140    /// Phase X.1: content-addressed constructor. Mints a certificate
6141    /// carrying the Witt level and substrate-hasher fingerprint of the
6142    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6143    #[inline]
6144    #[must_use]
6145    #[allow(dead_code)]
6146    pub(crate) const fn with_level_and_fingerprint_const(
6147        witt_bits: u16,
6148        content_fingerprint: ContentFingerprint,
6149    ) -> Self {
6150        Self {
6151            witt_bits,
6152            content_fingerprint,
6153            _private: (),
6154        }
6155    }
6156
6157    /// Phase X.1: legacy zero-fingerprint constructor retained for
6158    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6159    #[inline]
6160    #[must_use]
6161    #[allow(dead_code)]
6162    pub(crate) const fn empty_const() -> Self {
6163        Self {
6164            witt_bits: 0,
6165            content_fingerprint: ContentFingerprint::zero(),
6166            _private: (),
6167        }
6168    }
6169
6170    /// Phase X.1: the Witt level at which this certificate was minted.
6171    #[inline]
6172    #[must_use]
6173    pub const fn witt_bits(&self) -> u16 {
6174        self.witt_bits
6175    }
6176
6177    /// Phase X.1: the content fingerprint of the resolver decision.
6178    #[inline]
6179    #[must_use]
6180    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6181        self.content_fingerprint
6182    }
6183}
6184
6185/// v0.2.2 W11: sealed carrier for `cert:GeodesicCertificate`.
6186/// Phase X.1: minted with a Witt level and content fingerprint so the
6187/// resolver whose `resolver:CertifyMapping` produces this class can fold
6188/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6189/// constructor matches every other `cert:Certificate` subclass.
6190#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6191pub struct GeodesicCertificate {
6192    witt_bits: u16,
6193    content_fingerprint: ContentFingerprint,
6194    _private: (),
6195}
6196
6197impl GeodesicCertificate {
6198    /// Phase X.1: content-addressed constructor. Mints a certificate
6199    /// carrying the Witt level and substrate-hasher fingerprint of the
6200    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6201    #[inline]
6202    #[must_use]
6203    #[allow(dead_code)]
6204    pub(crate) const fn with_level_and_fingerprint_const(
6205        witt_bits: u16,
6206        content_fingerprint: ContentFingerprint,
6207    ) -> Self {
6208        Self {
6209            witt_bits,
6210            content_fingerprint,
6211            _private: (),
6212        }
6213    }
6214
6215    /// Phase X.1: legacy zero-fingerprint constructor retained for
6216    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6217    #[inline]
6218    #[must_use]
6219    #[allow(dead_code)]
6220    pub(crate) const fn empty_const() -> Self {
6221        Self {
6222            witt_bits: 0,
6223            content_fingerprint: ContentFingerprint::zero(),
6224            _private: (),
6225        }
6226    }
6227
6228    /// Phase X.1: the Witt level at which this certificate was minted.
6229    #[inline]
6230    #[must_use]
6231    pub const fn witt_bits(&self) -> u16 {
6232        self.witt_bits
6233    }
6234
6235    /// Phase X.1: the content fingerprint of the resolver decision.
6236    #[inline]
6237    #[must_use]
6238    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6239        self.content_fingerprint
6240    }
6241}
6242
6243/// v0.2.2 W11: sealed carrier for `cert:MeasurementCertificate`.
6244/// Phase X.1: minted with a Witt level and content fingerprint so the
6245/// resolver whose `resolver:CertifyMapping` produces this class can fold
6246/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6247/// constructor matches every other `cert:Certificate` subclass.
6248#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6249pub struct MeasurementCertificate {
6250    witt_bits: u16,
6251    content_fingerprint: ContentFingerprint,
6252    _private: (),
6253}
6254
6255impl MeasurementCertificate {
6256    /// Phase X.1: content-addressed constructor. Mints a certificate
6257    /// carrying the Witt level and substrate-hasher fingerprint of the
6258    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6259    #[inline]
6260    #[must_use]
6261    #[allow(dead_code)]
6262    pub(crate) const fn with_level_and_fingerprint_const(
6263        witt_bits: u16,
6264        content_fingerprint: ContentFingerprint,
6265    ) -> Self {
6266        Self {
6267            witt_bits,
6268            content_fingerprint,
6269            _private: (),
6270        }
6271    }
6272
6273    /// Phase X.1: legacy zero-fingerprint constructor retained for
6274    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6275    #[inline]
6276    #[must_use]
6277    #[allow(dead_code)]
6278    pub(crate) const fn empty_const() -> Self {
6279        Self {
6280            witt_bits: 0,
6281            content_fingerprint: ContentFingerprint::zero(),
6282            _private: (),
6283        }
6284    }
6285
6286    /// Phase X.1: the Witt level at which this certificate was minted.
6287    #[inline]
6288    #[must_use]
6289    pub const fn witt_bits(&self) -> u16 {
6290        self.witt_bits
6291    }
6292
6293    /// Phase X.1: the content fingerprint of the resolver decision.
6294    #[inline]
6295    #[must_use]
6296    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6297        self.content_fingerprint
6298    }
6299}
6300
6301/// v0.2.2 W11: sealed carrier for `cert:BornRuleVerification`.
6302/// Phase X.1: minted with a Witt level and content fingerprint so the
6303/// resolver whose `resolver:CertifyMapping` produces this class can fold
6304/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6305/// constructor matches every other `cert:Certificate` subclass.
6306#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6307pub struct BornRuleVerification {
6308    witt_bits: u16,
6309    content_fingerprint: ContentFingerprint,
6310    _private: (),
6311}
6312
6313impl BornRuleVerification {
6314    /// Phase X.1: content-addressed constructor. Mints a certificate
6315    /// carrying the Witt level and substrate-hasher fingerprint of the
6316    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6317    #[inline]
6318    #[must_use]
6319    #[allow(dead_code)]
6320    pub(crate) const fn with_level_and_fingerprint_const(
6321        witt_bits: u16,
6322        content_fingerprint: ContentFingerprint,
6323    ) -> Self {
6324        Self {
6325            witt_bits,
6326            content_fingerprint,
6327            _private: (),
6328        }
6329    }
6330
6331    /// Phase X.1: legacy zero-fingerprint constructor retained for
6332    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6333    #[inline]
6334    #[must_use]
6335    #[allow(dead_code)]
6336    pub(crate) const fn empty_const() -> Self {
6337        Self {
6338            witt_bits: 0,
6339            content_fingerprint: ContentFingerprint::zero(),
6340            _private: (),
6341        }
6342    }
6343
6344    /// Phase X.1: the Witt level at which this certificate was minted.
6345    #[inline]
6346    #[must_use]
6347    pub const fn witt_bits(&self) -> u16 {
6348        self.witt_bits
6349    }
6350
6351    /// Phase X.1: the content fingerprint of the resolver decision.
6352    #[inline]
6353    #[must_use]
6354    pub const fn content_fingerprint(&self) -> ContentFingerprint {
6355        self.content_fingerprint
6356    }
6357}
6358
6359/// v0.2.2 W11: sealed marker trait for foundation-supplied certificate kinds.
6360/// Implemented by every `cert:Certificate` subclass via codegen; not
6361/// implementable outside this crate.
6362pub trait Certificate: certificate_sealed::Sealed {
6363    /// The ontology IRI of this certificate class.
6364    const IRI: &'static str;
6365    /// The structured evidence carried by this certificate (or `()` if none).
6366    type Evidence;
6367}
6368
6369pub(crate) mod certificate_sealed {
6370    /// Private supertrait. Not implementable outside this crate.
6371    pub trait Sealed {}
6372    impl Sealed for super::GroundingCertificate {}
6373    impl Sealed for super::LiftChainCertificate {}
6374    impl Sealed for super::InhabitanceCertificate {}
6375    impl Sealed for super::CompletenessCertificate {}
6376    impl Sealed for super::TransformCertificate {}
6377    impl Sealed for super::IsometryCertificate {}
6378    impl Sealed for super::InvolutionCertificate {}
6379    impl Sealed for super::GeodesicCertificate {}
6380    impl Sealed for super::MeasurementCertificate {}
6381    impl Sealed for super::BornRuleVerification {}
6382    impl Sealed for super::MultiplicationCertificate {}
6383    impl Sealed for super::PartitionCertificate {}
6384    impl Sealed for super::GenericImpossibilityWitness {}
6385    impl Sealed for super::InhabitanceImpossibilityWitness {}
6386    impl Sealed for super::PartitionProductWitness {}
6387    impl Sealed for super::PartitionCoproductWitness {}
6388    impl Sealed for super::CartesianProductWitness {}
6389}
6390
6391impl Certificate for GroundingCertificate {
6392    const IRI: &'static str = "https://uor.foundation/cert/GroundingCertificate";
6393    type Evidence = ();
6394}
6395
6396impl Certificate for LiftChainCertificate {
6397    const IRI: &'static str = "https://uor.foundation/cert/LiftChainCertificate";
6398    type Evidence = ChainAuditTrail;
6399}
6400
6401impl Certificate for InhabitanceCertificate {
6402    const IRI: &'static str = "https://uor.foundation/cert/InhabitanceCertificate";
6403    type Evidence = ();
6404}
6405
6406impl Certificate for CompletenessCertificate {
6407    const IRI: &'static str = "https://uor.foundation/cert/CompletenessCertificate";
6408    type Evidence = CompletenessAuditTrail;
6409}
6410
6411impl Certificate for TransformCertificate {
6412    const IRI: &'static str = "https://uor.foundation/cert/TransformCertificate";
6413    type Evidence = ();
6414}
6415
6416impl Certificate for IsometryCertificate {
6417    const IRI: &'static str = "https://uor.foundation/cert/IsometryCertificate";
6418    type Evidence = ();
6419}
6420
6421impl Certificate for InvolutionCertificate {
6422    const IRI: &'static str = "https://uor.foundation/cert/InvolutionCertificate";
6423    type Evidence = ();
6424}
6425
6426impl Certificate for GeodesicCertificate {
6427    const IRI: &'static str = "https://uor.foundation/cert/GeodesicCertificate";
6428    type Evidence = GeodesicEvidenceBundle;
6429}
6430
6431impl Certificate for MeasurementCertificate {
6432    const IRI: &'static str = "https://uor.foundation/cert/MeasurementCertificate";
6433    type Evidence = ();
6434}
6435
6436impl Certificate for BornRuleVerification {
6437    const IRI: &'static str = "https://uor.foundation/cert/BornRuleVerification";
6438    type Evidence = ();
6439}
6440
6441impl Certificate for MultiplicationCertificate {
6442    const IRI: &'static str = "https://uor.foundation/cert/MultiplicationCertificate";
6443    type Evidence = MultiplicationEvidence;
6444}
6445
6446impl Certificate for PartitionCertificate {
6447    const IRI: &'static str = "https://uor.foundation/cert/PartitionCertificate";
6448    type Evidence = ();
6449}
6450
6451impl Certificate for GenericImpossibilityWitness {
6452    const IRI: &'static str = "https://uor.foundation/cert/GenericImpossibilityCertificate";
6453    type Evidence = ();
6454}
6455
6456impl Certificate for InhabitanceImpossibilityWitness {
6457    const IRI: &'static str = "https://uor.foundation/cert/InhabitanceImpossibilityCertificate";
6458    type Evidence = ();
6459}
6460
6461/// Phase X.1: uniform mint interface over cert subclasses. Each
6462/// `Certificate` implementer that accepts `(witt_bits, ContentFingerprint)`
6463/// at construction time implements this trait. Lives inside a
6464/// `certify_const_mint` module so the symbol doesn't leak into top-level
6465/// documentation alongside `Certificate`.
6466pub(crate) mod certify_const_mint {
6467    use super::{Certificate, ContentFingerprint};
6468    pub trait MintWithLevelFingerprint: Certificate {
6469        fn mint_with_level_fingerprint(
6470            witt_bits: u16,
6471            content_fingerprint: ContentFingerprint,
6472        ) -> Self;
6473    }
6474    impl MintWithLevelFingerprint for super::GroundingCertificate {
6475        #[inline]
6476        fn mint_with_level_fingerprint(
6477            witt_bits: u16,
6478            content_fingerprint: ContentFingerprint,
6479        ) -> Self {
6480            super::GroundingCertificate::with_level_and_fingerprint_const(
6481                witt_bits,
6482                content_fingerprint,
6483            )
6484        }
6485    }
6486    impl MintWithLevelFingerprint for super::LiftChainCertificate {
6487        #[inline]
6488        fn mint_with_level_fingerprint(
6489            witt_bits: u16,
6490            content_fingerprint: ContentFingerprint,
6491        ) -> Self {
6492            super::LiftChainCertificate::with_level_and_fingerprint_const(
6493                witt_bits,
6494                content_fingerprint,
6495            )
6496        }
6497    }
6498    impl MintWithLevelFingerprint for super::InhabitanceCertificate {
6499        #[inline]
6500        fn mint_with_level_fingerprint(
6501            witt_bits: u16,
6502            content_fingerprint: ContentFingerprint,
6503        ) -> Self {
6504            super::InhabitanceCertificate::with_level_and_fingerprint_const(
6505                witt_bits,
6506                content_fingerprint,
6507            )
6508        }
6509    }
6510    impl MintWithLevelFingerprint for super::CompletenessCertificate {
6511        #[inline]
6512        fn mint_with_level_fingerprint(
6513            witt_bits: u16,
6514            content_fingerprint: ContentFingerprint,
6515        ) -> Self {
6516            super::CompletenessCertificate::with_level_and_fingerprint_const(
6517                witt_bits,
6518                content_fingerprint,
6519            )
6520        }
6521    }
6522    impl MintWithLevelFingerprint for super::MultiplicationCertificate {
6523        #[inline]
6524        fn mint_with_level_fingerprint(
6525            witt_bits: u16,
6526            content_fingerprint: ContentFingerprint,
6527        ) -> Self {
6528            super::MultiplicationCertificate::with_level_and_fingerprint_const(
6529                witt_bits,
6530                content_fingerprint,
6531            )
6532        }
6533    }
6534    impl MintWithLevelFingerprint for super::PartitionCertificate {
6535        #[inline]
6536        fn mint_with_level_fingerprint(
6537            witt_bits: u16,
6538            content_fingerprint: ContentFingerprint,
6539        ) -> Self {
6540            super::PartitionCertificate::with_level_and_fingerprint_const(
6541                witt_bits,
6542                content_fingerprint,
6543            )
6544        }
6545    }
6546    impl MintWithLevelFingerprint for super::TransformCertificate {
6547        #[inline]
6548        fn mint_with_level_fingerprint(
6549            witt_bits: u16,
6550            content_fingerprint: ContentFingerprint,
6551        ) -> Self {
6552            super::TransformCertificate::with_level_and_fingerprint_const(
6553                witt_bits,
6554                content_fingerprint,
6555            )
6556        }
6557    }
6558    impl MintWithLevelFingerprint for super::IsometryCertificate {
6559        #[inline]
6560        fn mint_with_level_fingerprint(
6561            witt_bits: u16,
6562            content_fingerprint: ContentFingerprint,
6563        ) -> Self {
6564            super::IsometryCertificate::with_level_and_fingerprint_const(
6565                witt_bits,
6566                content_fingerprint,
6567            )
6568        }
6569    }
6570    impl MintWithLevelFingerprint for super::InvolutionCertificate {
6571        #[inline]
6572        fn mint_with_level_fingerprint(
6573            witt_bits: u16,
6574            content_fingerprint: ContentFingerprint,
6575        ) -> Self {
6576            super::InvolutionCertificate::with_level_and_fingerprint_const(
6577                witt_bits,
6578                content_fingerprint,
6579            )
6580        }
6581    }
6582    impl MintWithLevelFingerprint for super::GeodesicCertificate {
6583        #[inline]
6584        fn mint_with_level_fingerprint(
6585            witt_bits: u16,
6586            content_fingerprint: ContentFingerprint,
6587        ) -> Self {
6588            super::GeodesicCertificate::with_level_and_fingerprint_const(
6589                witt_bits,
6590                content_fingerprint,
6591            )
6592        }
6593    }
6594    impl MintWithLevelFingerprint for super::MeasurementCertificate {
6595        #[inline]
6596        fn mint_with_level_fingerprint(
6597            witt_bits: u16,
6598            content_fingerprint: ContentFingerprint,
6599        ) -> Self {
6600            super::MeasurementCertificate::with_level_and_fingerprint_const(
6601                witt_bits,
6602                content_fingerprint,
6603            )
6604        }
6605    }
6606    impl MintWithLevelFingerprint for super::BornRuleVerification {
6607        #[inline]
6608        fn mint_with_level_fingerprint(
6609            witt_bits: u16,
6610            content_fingerprint: ContentFingerprint,
6611        ) -> Self {
6612            super::BornRuleVerification::with_level_and_fingerprint_const(
6613                witt_bits,
6614                content_fingerprint,
6615            )
6616        }
6617    }
6618}
6619
6620/// v0.2.2 W11: parametric carrier for any foundation-supplied certificate.
6621/// Replaces the v0.2.1 per-class shim duplication. The `Certificate` trait
6622/// is sealed and the `_private` field prevents external construction; only
6623/// the foundation's pipeline / resolver paths produce `Certified<C>` values.
6624#[derive(Debug, Clone)]
6625pub struct Certified<C: Certificate> {
6626    /// The certificate kind value carried by this wrapper.
6627    inner: C,
6628    /// Phase A.1: the foundation-internal two-clock value read at witness issuance.
6629    uor_time: UorTime,
6630    /// Prevents external construction.
6631    _private: (),
6632}
6633
6634impl<C: Certificate> Certified<C> {
6635    /// Returns a reference to the carried certificate kind value.
6636    #[inline]
6637    #[must_use]
6638    pub const fn certificate(&self) -> &C {
6639        &self.inner
6640    }
6641
6642    /// Returns the ontology IRI of this certificate's kind.
6643    #[inline]
6644    #[must_use]
6645    pub const fn iri(&self) -> &'static str {
6646        C::IRI
6647    }
6648
6649    /// Phase A.1: the foundation-internal two-clock value read at witness issuance.
6650    /// Maps `rewrite_steps` to `derivation:stepCount` and `landauer_nats` to
6651    /// `observable:LandauerCost`. Content-deterministic: same computation →
6652    /// same `UorTime`. Composable against wall-clock bounds via
6653    /// [`UorTime::min_wall_clock`] and a downstream-supplied `Calibration`.
6654    #[inline]
6655    #[must_use]
6656    pub const fn uor_time(&self) -> UorTime {
6657        self.uor_time
6658    }
6659
6660    /// Crate-internal constructor. Reachable only from the pipeline / resolver paths.
6661    /// The `uor_time` is computed deterministically from the certificate kind's `IRI`
6662    /// length: the rewrite-step count is the IRI byte length, and the Landauer cost
6663    /// is `rewrite_steps × ln 2` (the Landauer-temperature cost of traversing that
6664    /// many orthogonal states). Two `Certified<C>` values with the same `C` share the
6665    /// same `UorTime`, preserving content-determinism across pipeline invocations.
6666    #[inline]
6667    #[allow(dead_code)]
6668    pub(crate) const fn new(inner: C) -> Self {
6669        // IRI length is the deterministic proxy for the cert class's structural
6670        // complexity. Phase D threads real resolver-counted steps through.
6671        let steps = C::IRI.len() as u64;
6672        let landauer = LandauerBudget::new((steps as f64) * core::f64::consts::LN_2);
6673        let uor_time = UorTime::new(landauer, steps);
6674        Self {
6675            inner,
6676            uor_time,
6677            _private: (),
6678        }
6679    }
6680}
6681
6682/// v0.2.2 Phase C.4: call-site context consumed by the multiplication
6683/// resolver. Carries the stack budget (`linear:stackBudgetBytes`), the
6684/// const-eval regime, and the limb count of the operand's `Limbs<N>`
6685/// backing. The resolver picks the cost-optimal Toom-Cook splitting
6686/// factor R based on this context.
6687#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6688pub struct MulContext {
6689    /// Stack budget available at the call site, in bytes. Zero is
6690    /// inadmissible; the resolver returns an impossibility witness.
6691    pub stack_budget_bytes: u64,
6692    /// True if this call is in const-eval context. In const-eval, only
6693    /// R = 1 (schoolbook) is admissible because deeper recursion blows
6694    /// the const-eval depth limit.
6695    pub const_eval: bool,
6696    /// Number of 64-bit limbs in the operand's `Limbs<N>` backing.
6697    /// Schoolbook cost is proportional to `N^2`; Karatsuba cost is
6698    /// proportional to `3 · (N/2)^2`. For native-backed levels
6699    /// (W8..W128), pass the equivalent limb count.
6700    pub limb_count: usize,
6701}
6702
6703impl MulContext {
6704    /// Construct a new `MulContext` for the call site.
6705    #[inline]
6706    #[must_use]
6707    pub const fn new(stack_budget_bytes: u64, const_eval: bool, limb_count: usize) -> Self {
6708        Self {
6709            stack_budget_bytes,
6710            const_eval,
6711            limb_count,
6712        }
6713    }
6714}
6715
6716/// v0.2.2 Phase C.4: evidence returned alongside a `MultiplicationCertificate`.
6717/// The certificate is a sealed handle; its evidence (chosen splitting factor,
6718/// sub-multiplication count, accumulated Landauer cost in nats) lives here.
6719#[derive(Debug, Clone, Copy, PartialEq)]
6720pub struct MultiplicationEvidence {
6721    splitting_factor: u32,
6722    sub_multiplication_count: u32,
6723    landauer_cost_nats_bits: u64,
6724}
6725
6726impl MultiplicationEvidence {
6727    /// The Toom-Cook splitting factor R chosen by the resolver.
6728    #[inline]
6729    #[must_use]
6730    pub const fn splitting_factor(&self) -> u32 {
6731        self.splitting_factor
6732    }
6733
6734    /// The recursive sub-multiplication count for one multiplication.
6735    #[inline]
6736    #[must_use]
6737    pub const fn sub_multiplication_count(&self) -> u32 {
6738        self.sub_multiplication_count
6739    }
6740
6741    /// Accumulated Landauer cost in nats, priced per `op:OA_5`. Returned as the IEEE-754 bit pattern; project to `H::Decimal` at use sites via `<H::Decimal as DecimalTranscendental>::from_bits(_)`.
6742    #[inline]
6743    #[must_use]
6744    pub const fn landauer_cost_nats_bits(&self) -> u64 {
6745        self.landauer_cost_nats_bits
6746    }
6747}
6748
6749impl MultiplicationCertificate {
6750    /// v0.2.2 T6.7: construct a `MultiplicationCertificate` with substrate-
6751    /// computed evidence. Crate-internal only; downstream obtains certificates
6752    /// via `resolver::multiplication::certify::<H>`.
6753    #[inline]
6754    #[must_use]
6755    pub(crate) fn with_evidence(
6756        splitting_factor: u32,
6757        sub_multiplication_count: u32,
6758        landauer_cost_nats_bits: u64,
6759        content_fingerprint: ContentFingerprint,
6760    ) -> Self {
6761        let _ = MultiplicationEvidence {
6762            splitting_factor,
6763            sub_multiplication_count,
6764            landauer_cost_nats_bits,
6765        };
6766        Self::with_level_and_fingerprint_const(32, content_fingerprint)
6767    }
6768}
6769
6770/// v0.2.2 Phase E: maximum simplicial dimension tracked by the
6771/// constraint-nerve Betti-numbers vector. The bound is 8 for the
6772/// currently-supported WittLevel set per the existing partition:FreeRank
6773/// capacity properties; the constant is `pub` (part of the public-API
6774/// snapshot) so future expansions require explicit review.
6775/// Wiki ADR-037: alias of [`crate::HostBounds::BETTI_DIMENSION_MAX`] via
6776/// [`crate::DefaultHostBounds`].
6777pub const MAX_BETTI_DIMENSION: usize =
6778    <crate::DefaultHostBounds as crate::HostBounds>::BETTI_DIMENSION_MAX;
6779
6780/// Sealed newtype for the grounding completion ratio σ ∈
6781/// [0.0, 1.0]. σ = 1 indicates the ground state; σ = 0 the
6782/// unbound state. Backs observable:GroundingSigma. Phase 9: parametric over
6783/// the host's `H::Decimal` precision.
6784#[derive(Debug)]
6785pub struct SigmaValue<H: HostTypes = crate::DefaultHostTypes> {
6786    value: H::Decimal,
6787    _phantom: core::marker::PhantomData<H>,
6788    _sealed: (),
6789}
6790
6791impl<H: HostTypes> Copy for SigmaValue<H> {}
6792impl<H: HostTypes> Clone for SigmaValue<H> {
6793    #[inline]
6794    fn clone(&self) -> Self {
6795        *self
6796    }
6797}
6798impl<H: HostTypes> PartialEq for SigmaValue<H> {
6799    #[inline]
6800    fn eq(&self, other: &Self) -> bool {
6801        self.value == other.value
6802    }
6803}
6804
6805impl<H: HostTypes> SigmaValue<H> {
6806    /// Returns the stored σ value in the range [0.0, 1.0].
6807    #[inline]
6808    #[must_use]
6809    pub const fn value(&self) -> H::Decimal {
6810        self.value
6811    }
6812
6813    /// Crate-internal constructor. Caller guarantees `value` is in
6814    /// the closed range [0.0, 1.0] and is not NaN.
6815    #[inline]
6816    #[must_use]
6817    #[allow(dead_code)]
6818    pub(crate) const fn new_unchecked(value: H::Decimal) -> Self {
6819        Self {
6820            value,
6821            _phantom: core::marker::PhantomData,
6822            _sealed: (),
6823        }
6824    }
6825}
6826
6827/// Phase A.3: sealed stratum coordinate (the v₂ valuation of a `Datum` at level `L`).
6828/// Backs `schema:stratum`. The value is non-negative and bounded by `L`'s `bit_width`
6829/// per the ontology's `nonNegativeInteger` range. Constructed only by foundation code
6830/// at grounding time; no public constructor — the `Stratum<W8>` / `Stratum<W16>` / ...
6831/// type family is closed under the WittLevel individual set.
6832#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6833pub struct Stratum<L> {
6834    value: u32,
6835    _level: PhantomData<L>,
6836    _sealed: (),
6837}
6838
6839impl<L> Stratum<L> {
6840    /// Returns the raw v₂ valuation as a `u32`. The value is bounded by `L`'s bit_width.
6841    #[inline]
6842    #[must_use]
6843    pub const fn as_u32(&self) -> u32 {
6844        self.value
6845    }
6846
6847    /// Crate-internal constructor. Reachable only from grounding-time minting.
6848    #[inline]
6849    #[must_use]
6850    #[allow(dead_code)]
6851    pub(crate) const fn new(value: u32) -> Self {
6852        Self {
6853            value,
6854            _level: PhantomData,
6855            _sealed: (),
6856        }
6857    }
6858}
6859
6860/// Phase A.4: sealed carrier for `observable:d_delta_metric` (metric incompatibility).
6861#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6862pub struct DDeltaMetric {
6863    value: i64,
6864    _sealed: (),
6865}
6866
6867impl DDeltaMetric {
6868    /// Returns the signed incompatibility magnitude (ring distance minus Hamming distance).
6869    #[inline]
6870    #[must_use]
6871    pub const fn as_i64(&self) -> i64 {
6872        self.value
6873    }
6874
6875    /// Crate-internal constructor.
6876    #[inline]
6877    #[must_use]
6878    #[allow(dead_code)]
6879    pub(crate) const fn new(value: i64) -> Self {
6880        Self { value, _sealed: () }
6881    }
6882}
6883
6884/// Phase A.4: sealed carrier for `observable:euler_metric` (Euler characteristic).
6885#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6886pub struct EulerMetric {
6887    value: i64,
6888    _sealed: (),
6889}
6890
6891impl EulerMetric {
6892    /// Returns the Euler characteristic χ of the constraint nerve.
6893    #[inline]
6894    #[must_use]
6895    pub const fn as_i64(&self) -> i64 {
6896        self.value
6897    }
6898
6899    /// Crate-internal constructor.
6900    #[inline]
6901    #[must_use]
6902    #[allow(dead_code)]
6903    pub(crate) const fn new(value: i64) -> Self {
6904        Self { value, _sealed: () }
6905    }
6906}
6907
6908/// Phase A.4: sealed carrier for `observable:residual_metric` (free-site count r).
6909#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6910pub struct ResidualMetric {
6911    value: u32,
6912    _sealed: (),
6913}
6914
6915impl ResidualMetric {
6916    /// Returns the free-site count r at grounding time.
6917    #[inline]
6918    #[must_use]
6919    pub const fn as_u32(&self) -> u32 {
6920        self.value
6921    }
6922
6923    /// Crate-internal constructor.
6924    #[inline]
6925    #[must_use]
6926    #[allow(dead_code)]
6927    pub(crate) const fn new(value: u32) -> Self {
6928        Self { value, _sealed: () }
6929    }
6930}
6931
6932/// Phase A.4: sealed carrier for `observable:betti_metric` (Betti-number vector).
6933/// Fixed-capacity `[u32; MAX_BETTI_DIMENSION]` backing; no heap.
6934#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6935pub struct BettiMetric {
6936    values: [u32; MAX_BETTI_DIMENSION],
6937    _sealed: (),
6938}
6939
6940impl BettiMetric {
6941    /// Returns the Betti-number vector as a fixed-size array reference.
6942    #[inline]
6943    #[must_use]
6944    pub const fn as_array(&self) -> &[u32; MAX_BETTI_DIMENSION] {
6945        &self.values
6946    }
6947
6948    /// Returns the individual Betti number βₖ for dimension k.
6949    /// Returns 0 when k >= MAX_BETTI_DIMENSION.
6950    #[inline]
6951    #[must_use]
6952    pub const fn beta(&self, k: usize) -> u32 {
6953        if k < MAX_BETTI_DIMENSION {
6954            self.values[k]
6955        } else {
6956            0
6957        }
6958    }
6959
6960    /// Crate-internal constructor.
6961    #[inline]
6962    #[must_use]
6963    #[allow(dead_code)]
6964    pub(crate) const fn new(values: [u32; MAX_BETTI_DIMENSION]) -> Self {
6965        Self {
6966            values,
6967            _sealed: (),
6968        }
6969    }
6970}
6971
6972/// Maximum site count of the Jacobian row per Datum at any supported
6973/// WittLevel. Sourced from the partition:FreeRank capacity bound.
6974/// v0.2.2 T2.6 (cleanup): reduced from 64 to 8 to keep `Grounded` under
6975/// the 256-byte size budget enforced by `phantom_tag::grounded_sealed_field_count_unchanged`.
6976/// 8 matches `MAX_BETTI_DIMENSION` and is sufficient for the v0.2.2 partition rank set.
6977/// Wiki ADR-037: alias of [`crate::HostBounds::JACOBIAN_SITES_MAX`] via
6978/// [`crate::DefaultHostBounds`].
6979pub const JACOBIAN_MAX_SITES: usize =
6980    <crate::DefaultHostBounds as crate::HostBounds>::JACOBIAN_SITES_MAX;
6981
6982/// v0.2.2 Phase E: sealed Jacobian row carrier, parametric over the
6983/// WittLevel marker. Fixed-size `[i64; JACOBIAN_MAX_SITES]` backing; no
6984/// heap. The row records the per-site partial derivative of the ring
6985/// operation that produced the Datum. Backs observable:JacobianObservable.
6986#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6987pub struct JacobianMetric<L> {
6988    entries: [i64; JACOBIAN_MAX_SITES],
6989    len: u16,
6990    _level: PhantomData<L>,
6991    _sealed: (),
6992}
6993
6994impl<L> JacobianMetric<L> {
6995    /// Construct a zeroed Jacobian row with the given active length.
6996    #[inline]
6997    #[must_use]
6998    #[allow(dead_code)]
6999    pub(crate) const fn zero(len: u16) -> Self {
7000        Self {
7001            entries: [0i64; JACOBIAN_MAX_SITES],
7002            len,
7003            _level: PhantomData,
7004            _sealed: (),
7005        }
7006    }
7007
7008    /// v0.2.2 T2.6 (cleanup): crate-internal constructor used by the
7009    /// BaseMetric accessor on `Grounded` to return a `JacobianMetric`
7010    /// backed by stored field values.
7011    #[inline]
7012    #[must_use]
7013    #[allow(dead_code)]
7014    pub(crate) const fn from_entries(entries: [i64; JACOBIAN_MAX_SITES], len: u16) -> Self {
7015        Self {
7016            entries,
7017            len,
7018            _level: PhantomData,
7019            _sealed: (),
7020        }
7021    }
7022
7023    /// Access the Jacobian row entries.
7024    #[inline]
7025    #[must_use]
7026    pub const fn entries(&self) -> &[i64; JACOBIAN_MAX_SITES] {
7027        &self.entries
7028    }
7029
7030    /// Number of active sites (the row's logical length).
7031    #[inline]
7032    #[must_use]
7033    pub const fn len(&self) -> u16 {
7034        self.len
7035    }
7036
7037    /// Whether the Jacobian row is empty.
7038    #[inline]
7039    #[must_use]
7040    pub const fn is_empty(&self) -> bool {
7041        self.len == 0
7042    }
7043}
7044
7045/// v0.2.2 Phase E: sealed Partition component classification.
7046/// Closed enumeration mirroring the partition:PartitionComponent
7047/// ontology class.
7048#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7049#[non_exhaustive]
7050pub enum PartitionComponent {
7051    /// The irreducible component.
7052    Irreducible,
7053    /// The reducible component.
7054    Reducible,
7055    /// The unit component.
7056    Units,
7057    /// The exterior component.
7058    Exterior,
7059}
7060
7061/// Sealed marker trait identifying type:ConstrainedType subclasses that may
7062/// appear as the parameter of `Grounded<T>`.
7063/// Per wiki ADR-027, the seal is the same `__sdk_seal::Sealed` supertrait
7064/// foundation uses for `FoundationClosed`, `PrismModel`, and
7065/// `IntoBindingValue`: only foundation and the SDK shape macros emit
7066/// impls. The foundation-sanctioned identity output `ConstrainedTypeInput`
7067/// retains its direct impl; application authors declaring custom Output
7068/// shapes invoke the `output_shape!` SDK macro, which emits
7069/// `__sdk_seal::Sealed`, `GroundedShape`, `IntoBindingValue`, and
7070/// `ConstrainedTypeShape` together.
7071pub trait GroundedShape: crate::pipeline::__sdk_seal::Sealed {}
7072impl GroundedShape for ConstrainedTypeInput {}
7073
7074/// v0.2.2 T4.2: sealed content-addressed handle.
7075/// Wraps a 128-bit identity used for `BindingsTable` lookups and as a
7076/// compact identity handle for `Grounded` values. The underlying `u128`
7077/// is visible via `as_u128()` for interop. Distinct from
7078/// `ContentFingerprint` (the parametric-width fingerprint computed by
7079/// the substrate `Hasher` — see T5.C3.d below): `ContentAddress` is a
7080/// fixed 16-byte sortable handle, while `ContentFingerprint` is the full
7081/// substrate-computed identity that round-trips through `verify_trace`.
7082#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7083pub struct ContentAddress {
7084    raw: u128,
7085    _sealed: (),
7086}
7087
7088impl ContentAddress {
7089    /// The zero content address. Used as the "unset" placeholder in
7090    /// `BindingsTable` lookups, the default state of an uninitialised
7091    /// `Grounded::unit_address`, and the initial seed of replay folds.
7092    #[inline]
7093    #[must_use]
7094    pub const fn zero() -> Self {
7095        Self {
7096            raw: 0,
7097            _sealed: (),
7098        }
7099    }
7100
7101    /// Returns the underlying 128-bit content hash.
7102    #[inline]
7103    #[must_use]
7104    pub const fn as_u128(&self) -> u128 {
7105        self.raw
7106    }
7107
7108    /// Whether this content address is the zero handle.
7109    #[inline]
7110    #[must_use]
7111    pub const fn is_zero(&self) -> bool {
7112        self.raw == 0
7113    }
7114
7115    /// v0.2.2 T5.C1: public ctor. Promoted from `pub(crate)` in T5 so
7116    /// downstream tests can construct deterministic `ContentAddress` values
7117    /// for fixture data without going through the foundation pipeline.
7118    #[inline]
7119    #[must_use]
7120    pub const fn from_u128(raw: u128) -> Self {
7121        Self { raw, _sealed: () }
7122    }
7123
7124    /// v0.2.2 Phase P.3: construct a `ContentAddress` from a `u64` FNV-1a fingerprint
7125    /// by right-padding the value into the 128-bit address space. Used by
7126    /// `Binding::to_binding_entry` to bridge the `Binding.content_address: u64`
7127    /// carrier to the `BindingEntry.address: ContentAddress` (`u128`-backed) shape.
7128    /// The lift is `raw = (fingerprint as u128) << 64` — upper 64 bits carry the
7129    /// FNV-1a value; lower 64 bits are zero. Content-deterministic; round-trips via
7130    /// `ContentAddress::as_u128() >> 64` back to the original `u64`.
7131    #[inline]
7132    #[must_use]
7133    pub const fn from_u64_fingerprint(fingerprint: u64) -> Self {
7134        Self {
7135            raw: (fingerprint as u128) << 64,
7136            _sealed: (),
7137        }
7138    }
7139}
7140
7141impl Default for ContentAddress {
7142    #[inline]
7143    fn default() -> Self {
7144        Self::zero()
7145    }
7146}
7147
7148/// Trace wire-format identifier. Per the wiki's ADR-018, wire-format
7149/// identifiers are explicitly carved out of the `HostBounds` rule because
7150/// cross-implementation interop requires a single shared format identifier.
7151/// Increment when the layout changes (event ordering, trailing fields,
7152/// primitive-op discriminant table, certificate-kind discriminant table).
7153/// Pinned by the `rust/trace_byte_layout_pinned` conformance validator.
7154pub const TRACE_REPLAY_FORMAT_VERSION: u16 = 10;
7155
7156/// v0.2.2 T5: pluggable content hasher with parametric output width.
7157/// The foundation does not ship an implementation. Downstream substrate
7158/// consumers (PRISM, application crates) supply their own `Hasher` impl
7159/// — BLAKE3, SHA-256, SHA-512, BLAKE2b, SipHash 2-4, FNV-1a, or any
7160/// other byte-stream hash whose output width satisfies the foundation's
7161/// derived collision-bound minimum.
7162/// # Foundation recommendation
7163/// The foundation **recommends BLAKE3** as the default substrate hash for
7164/// production deployments. BLAKE3 is fast, well-audited, has no known
7165/// cryptographic weaknesses, supports parallel and SIMD-accelerated
7166/// implementations, and has a flexible output length. PRISM ships a BLAKE3
7167/// `Hasher` impl as its production substrate; application crates should
7168/// use it unless they have a specific reason to deviate.
7169/// The recommendation is non-binding: any conforming `Hasher` impl works
7170/// with the foundation's pipeline and verify path. The foundation never
7171/// invokes a hash function itself, so the choice is fully a downstream
7172/// decision.
7173/// # Architecture
7174/// The architectural shape mirrors `Calibration`: the foundation defines
7175/// the abstract quantity (`ContentFingerprint`) and the substitution point
7176/// (`Hasher`); downstream provides the concrete substrate AND chooses the
7177/// output width within the foundation's correctness budget.
7178/// # Required laws
7179/// 1. **Width-in-budget**: `OUTPUT_BYTES` must be in
7180///    `[<B as HostBounds>::FINGERPRINT_MIN_BYTES, FP_MAX]` where `FP_MAX`
7181///    is the const-generic carrying `<B as HostBounds>::FINGERPRINT_MAX_BYTES`.
7182///    Enforced at codegen time via a `const _: () = assert!(...)` block
7183///    emitted inside every `pipeline::run::<T, _, H>` body.
7184/// 2. **Determinism**: identical byte sequences produce bit-identical outputs
7185///    across program runs, builds, target architectures, and rustc versions.
7186/// 3. **Sensitivity**: hashing two byte sequences that differ in any byte
7187///    produces two distinct outputs with probability bounded by the hasher's
7188///    documented collision rate.
7189/// 4. **No interior mutability**: `fold_byte` consumes `self` and returns a
7190///    new state. Impls that depend on hidden mutable state violate the contract.
7191/// # Example
7192/// ```
7193/// use uor_foundation::enforcement::Hasher;
7194/// /// Minimal 128-bit (16-byte) FNV-1a substrate — two 64-bit lanes.
7195/// #[derive(Clone, Copy)]
7196/// pub struct Fnv1a16 { a: u64, b: u64 }
7197/// impl Hasher for Fnv1a16 {
7198///     const OUTPUT_BYTES: usize = 16;
7199///     fn initial() -> Self {
7200///         Self { a: 0xcbf29ce484222325, b: 0x84222325cbf29ce4 }
7201///     }
7202///     fn fold_byte(mut self, x: u8) -> Self {
7203///         self.a ^= x as u64;
7204///         self.a = self.a.wrapping_mul(0x100000001b3);
7205///         self.b ^= (x as u64).rotate_left(8);
7206///         self.b = self.b.wrapping_mul(0x100000001b3);
7207///         self
7208///     }
7209///     fn finalize(self) -> [u8; 32] {
7210///         let mut buf = [0u8; 32];
7211///         buf[..8].copy_from_slice(&self.a.to_be_bytes());
7212///         buf[8..16].copy_from_slice(&self.b.to_be_bytes());
7213///         buf
7214///     }
7215/// }
7216/// ```
7217/// Above, `Hasher` is reached through its default const-generic
7218/// `<FP_MAX = 32>`, which is the `DefaultHostBounds::FINGERPRINT_MAX_BYTES`
7219/// value. Applications that select a different `HostBounds` impl write
7220/// `impl Hasher<{<MyBounds as HostBounds>::FINGERPRINT_MAX_BYTES}> for MyHasher`.
7221pub trait Hasher<const FP_MAX: usize = 32> {
7222    /// Active output width in bytes. Must lie within the bounds
7223    /// the application's selected `HostBounds` declares —
7224    /// `[<B as HostBounds>::FINGERPRINT_MIN_BYTES, FP_MAX]`.
7225    const OUTPUT_BYTES: usize;
7226
7227    /// Initial hasher state.
7228    fn initial() -> Self;
7229
7230    /// Fold a single byte into the running state.
7231    #[must_use]
7232    fn fold_byte(self, b: u8) -> Self;
7233
7234    /// Fold a slice of bytes (default impl: byte-by-byte).
7235    #[inline]
7236    #[must_use]
7237    fn fold_bytes(mut self, bytes: &[u8]) -> Self
7238    where
7239        Self: Sized,
7240    {
7241        let mut i = 0;
7242        while i < bytes.len() {
7243            self = self.fold_byte(bytes[i]);
7244            i += 1;
7245        }
7246        self
7247    }
7248
7249    /// Finalize into the canonical max-width buffer of `FP_MAX` bytes.
7250    /// Bytes `0..OUTPUT_BYTES` carry the hash result; bytes
7251    /// `OUTPUT_BYTES..FP_MAX` MUST be zero.
7252    fn finalize(self) -> [u8; FP_MAX];
7253}
7254
7255/// ADR-030 adapter: wrap any [`Hasher`] impl as an
7256/// [`crate::pipeline::AxisExtension`]. The lone supported kernel id
7257/// is [`HashAxis::KERNEL_HASH`] = 0, which folds the input bytes
7258/// through the wrapped Hasher and writes the first `OUTPUT_BYTES`
7259/// digest bytes to the caller-provided buffer.
7260#[derive(Debug, Clone, Copy)]
7261pub struct HashAxis<H: Hasher>(core::marker::PhantomData<H>);
7262
7263impl<H: Hasher> HashAxis<H> {
7264    /// Canonical kernel id for the hash operation. The closure-body
7265    /// grammar G19 form `hash(input)` lowers to
7266    /// `Term::AxisInvocation { axis_index: 0, kernel_id: HashAxis::KERNEL_HASH, input_index }`.
7267    pub const KERNEL_HASH: u32 = 0;
7268}
7269
7270impl<H: Hasher> crate::pipeline::__sdk_seal::Sealed for HashAxis<H> {}
7271impl<H: Hasher> crate::pipeline::SubstrateTermBody for HashAxis<H> {
7272    fn body_arena() -> &'static [Term] {
7273        &[]
7274    }
7275}
7276impl<H: Hasher> crate::pipeline::AxisExtension for HashAxis<H> {
7277    const AXIS_ADDRESS: &'static str = "https://uor.foundation/axis/HashAxis";
7278    const MAX_OUTPUT_BYTES: usize = <H as Hasher>::OUTPUT_BYTES;
7279    fn dispatch_kernel(
7280        kernel_id: u32,
7281        input: &[u8],
7282        out: &mut [u8],
7283    ) -> Result<usize, ShapeViolation> {
7284        if kernel_id != Self::KERNEL_HASH {
7285            return Err(ShapeViolation {
7286                shape_iri: "https://uor.foundation/axis/HashAxis",
7287                constraint_iri: "https://uor.foundation/axis/HashAxis/kernelId",
7288                property_iri: "https://uor.foundation/axis/kernelId",
7289                expected_range: "https://uor.foundation/axis/HashAxis/KERNEL_HASH",
7290                min_count: 0,
7291                max_count: 1,
7292                kind: crate::ViolationKind::ValueCheck,
7293            });
7294        }
7295        let mut hasher = <H as Hasher>::initial();
7296        hasher = hasher.fold_bytes(input);
7297        let digest = hasher.finalize();
7298        let n = <H as Hasher>::OUTPUT_BYTES.min(out.len()).min(digest.len());
7299        let mut i = 0;
7300        while i < n {
7301            out[i] = digest[i];
7302            i += 1;
7303        }
7304        Ok(n)
7305    }
7306}
7307
7308/// Sealed parametric content fingerprint.
7309/// Wraps a fixed-capacity byte buffer of `FP_MAX` bytes plus the
7310/// active width in bytes. `FP_MAX` is the const-generic that carries
7311/// the application's selected `HostBounds::FINGERPRINT_MAX_BYTES`
7312/// (default = 32, matching `DefaultHostBounds`). The active width
7313/// is set by the producing `Hasher::OUTPUT_BYTES` and recorded so
7314/// downstream can distinguish "this is a 128-bit fingerprint" from
7315/// "this is a 256-bit fingerprint" without inspecting trailing zeros.
7316/// Equality is bit-equality on the full buffer + width tag, so two
7317/// fingerprints from different hashers (different widths) are never
7318/// equal even if their leading bytes happen to coincide. This prevents
7319/// silent collisions when downstream consumers mix substrate hashers.
7320#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7321pub struct ContentFingerprint<const FP_MAX: usize = 32> {
7322    bytes: [u8; FP_MAX],
7323    width_bytes: u8,
7324    _sealed: (),
7325}
7326
7327impl<const FP_MAX: usize> ContentFingerprint<FP_MAX> {
7328    /// Crate-internal zero placeholder. Used internally as the
7329    /// `Trace::empty()` field initializer and the `Default` impl. Not
7330    /// publicly constructible; downstream that needs a `ContentFingerprint`
7331    /// constructs one via `Hasher::finalize()` followed by `from_buffer()`.
7332    #[inline]
7333    #[must_use]
7334    #[allow(dead_code)]
7335    pub(crate) const fn zero() -> Self {
7336        Self {
7337            bytes: [0u8; FP_MAX],
7338            width_bytes: 0,
7339            _sealed: (),
7340        }
7341    }
7342
7343    /// Whether this fingerprint is the all-zero placeholder.
7344    #[inline]
7345    #[must_use]
7346    pub const fn is_zero(&self) -> bool {
7347        self.width_bytes == 0
7348    }
7349
7350    /// Active width in bytes (set by the producing hasher).
7351    #[inline]
7352    #[must_use]
7353    pub const fn width_bytes(&self) -> u8 {
7354        self.width_bytes
7355    }
7356
7357    /// Active width in bits (`width_bytes * 8`).
7358    #[inline]
7359    #[must_use]
7360    pub const fn width_bits(&self) -> u16 {
7361        (self.width_bytes as u16) * 8
7362    }
7363
7364    /// The full buffer. Bytes `0..width_bytes` are the hash; bytes
7365    /// `width_bytes..FP_MAX` are zero.
7366    #[inline]
7367    #[must_use]
7368    pub const fn as_bytes(&self) -> &[u8; FP_MAX] {
7369        &self.bytes
7370    }
7371
7372    /// Construct a fingerprint from a hasher's finalize buffer + width tag.
7373    /// Production paths reach this via `pipeline::run::<T, _, H>`; test
7374    /// paths via the `__test_helpers` back-door.
7375    #[inline]
7376    #[must_use]
7377    pub const fn from_buffer(bytes: [u8; FP_MAX], width_bytes: u8) -> Self {
7378        Self {
7379            bytes,
7380            width_bytes,
7381            _sealed: (),
7382        }
7383    }
7384}
7385
7386impl<const FP_MAX: usize> Default for ContentFingerprint<FP_MAX> {
7387    #[inline]
7388    fn default() -> Self {
7389        Self::zero()
7390    }
7391}
7392
7393/// v0.2.2 T5: stable u8 discriminant for `PrimitiveOp`. Locked to the
7394/// codegen output order; do not reorder `PrimitiveOp` variants without
7395/// bumping `TRACE_REPLAY_FORMAT_VERSION`. Folded into the canonical byte
7396/// layout of every `TraceEvent` so substrate hashers produce stable
7397/// fingerprints across builds.
7398#[inline]
7399#[must_use]
7400pub const fn primitive_op_discriminant(op: crate::PrimitiveOp) -> u8 {
7401    match op {
7402        crate::PrimitiveOp::Neg => 0,
7403        crate::PrimitiveOp::Bnot => 1,
7404        crate::PrimitiveOp::Succ => 2,
7405        crate::PrimitiveOp::Pred => 3,
7406        crate::PrimitiveOp::Add => 4,
7407        crate::PrimitiveOp::Sub => 5,
7408        crate::PrimitiveOp::Mul => 6,
7409        crate::PrimitiveOp::Xor => 7,
7410        crate::PrimitiveOp::And => 8,
7411        crate::PrimitiveOp::Or => 9,
7412        // ADR-013/TR-08 substrate amendment: byte-level ops 10..15.
7413        crate::PrimitiveOp::Le => 10,
7414        crate::PrimitiveOp::Lt => 11,
7415        crate::PrimitiveOp::Ge => 12,
7416        crate::PrimitiveOp::Gt => 13,
7417        crate::PrimitiveOp::Concat => 14,
7418        // ADR-053 substrate amendment: ring-axis arithmetic completion.
7419        crate::PrimitiveOp::Div => 15,
7420        crate::PrimitiveOp::Mod => 16,
7421        crate::PrimitiveOp::Pow => 17,
7422    }
7423}
7424
7425/// v0.2.2 T5: stable u8 discriminant tag distinguishing the certificate
7426/// kinds the foundation pipeline mints. Folded into the trailing byte of
7427/// every canonical digest so two certificates over the same source unit
7428/// but of different kinds produce distinct fingerprints. Locked at v0.2.2;
7429/// reordering or inserting variants requires bumping
7430/// `TRACE_REPLAY_FORMAT_VERSION`.
7431#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7432#[non_exhaustive]
7433pub enum CertificateKind {
7434    /// Cert minted by `pipeline::run` and `run_const` (retained for
7435    /// `run_grounding_aware`).
7436    Grounding,
7437    /// Cert minted by `certify_tower_completeness_const`.
7438    TowerCompleteness,
7439    /// Cert minted by `certify_incremental_completeness_const`.
7440    IncrementalCompleteness,
7441    /// Cert minted by `certify_inhabitance_const` / `run_inhabitance`.
7442    Inhabitance,
7443    /// Cert minted by `certify_multiplication_const`.
7444    Multiplication,
7445    /// Cert minted by `resolver::two_sat_decider::certify`.
7446    TwoSat,
7447    /// Cert minted by `resolver::horn_sat_decider::certify`.
7448    HornSat,
7449    /// Cert minted by `resolver::residual_verdict::certify`.
7450    ResidualVerdict,
7451    /// Cert minted by `resolver::canonical_form::certify`.
7452    CanonicalForm,
7453    /// Cert minted by `resolver::type_synthesis::certify`.
7454    TypeSynthesis,
7455    /// Cert minted by `resolver::homotopy::certify`.
7456    Homotopy,
7457    /// Cert minted by `resolver::monodromy::certify`.
7458    Monodromy,
7459    /// Cert minted by `resolver::moduli::certify`.
7460    Moduli,
7461    /// Cert minted by `resolver::jacobian_guided::certify`.
7462    JacobianGuided,
7463    /// Cert minted by `resolver::evaluation::certify`.
7464    Evaluation,
7465    /// Cert minted by `resolver::session::certify`.
7466    Session,
7467    /// Cert minted by `resolver::superposition::certify`.
7468    Superposition,
7469    /// Cert minted by `resolver::measurement::certify`.
7470    Measurement,
7471    /// Cert minted by `resolver::witt_level_resolver::certify`.
7472    WittLevel,
7473    /// Cert minted by `resolver::dihedral_factorization::certify`.
7474    DihedralFactorization,
7475    /// Cert minted by `resolver::completeness::certify`.
7476    Completeness,
7477    /// Cert minted by `resolver::geodesic_validator::certify`.
7478    GeodesicValidator,
7479}
7480
7481/// v0.2.2 T5: stable u8 discriminant for `CertificateKind`. Folded into
7482/// the trailing byte of canonical digests via the `*Digest` types so two
7483/// distinct certificate kinds over the same source unit produce distinct
7484/// fingerprints. Locked at v0.2.2.
7485#[inline]
7486#[must_use]
7487pub const fn certificate_kind_discriminant(kind: CertificateKind) -> u8 {
7488    match kind {
7489        CertificateKind::Grounding => 1,
7490        CertificateKind::TowerCompleteness => 2,
7491        CertificateKind::IncrementalCompleteness => 3,
7492        CertificateKind::Inhabitance => 4,
7493        CertificateKind::Multiplication => 5,
7494        CertificateKind::TwoSat => 6,
7495        CertificateKind::HornSat => 7,
7496        CertificateKind::ResidualVerdict => 8,
7497        CertificateKind::CanonicalForm => 9,
7498        CertificateKind::TypeSynthesis => 10,
7499        CertificateKind::Homotopy => 11,
7500        CertificateKind::Monodromy => 12,
7501        CertificateKind::Moduli => 13,
7502        CertificateKind::JacobianGuided => 14,
7503        CertificateKind::Evaluation => 15,
7504        CertificateKind::Session => 16,
7505        CertificateKind::Superposition => 17,
7506        CertificateKind::Measurement => 18,
7507        CertificateKind::WittLevel => 19,
7508        CertificateKind::DihedralFactorization => 20,
7509        CertificateKind::Completeness => 21,
7510        CertificateKind::GeodesicValidator => 22,
7511    }
7512}
7513
7514/// v0.2.2 T5: fold a `ConstraintRef` into a `Hasher` via the canonical
7515/// byte layout. Each variant emits a discriminant byte (1..=9) followed by
7516/// its payload bytes in big-endian order. Locked at v0.2.2; reordering
7517/// variants requires bumping `TRACE_REPLAY_FORMAT_VERSION`.
7518/// Used by `pipeline::run`, `run_const`, and the four `certify_*` entry
7519/// points to fold a unit's constraint set into the substrate fingerprint.
7520pub fn fold_constraint_ref<H: Hasher>(mut hasher: H, c: &crate::pipeline::ConstraintRef) -> H {
7521    use crate::pipeline::ConstraintRef as C;
7522    match c {
7523        C::Residue { modulus, residue } => {
7524            hasher = hasher.fold_byte(1);
7525            hasher = hasher.fold_bytes(&modulus.to_be_bytes());
7526            hasher = hasher.fold_bytes(&residue.to_be_bytes());
7527        }
7528        C::Hamming { bound } => {
7529            hasher = hasher.fold_byte(2);
7530            hasher = hasher.fold_bytes(&bound.to_be_bytes());
7531        }
7532        C::Depth { min, max } => {
7533            hasher = hasher.fold_byte(3);
7534            hasher = hasher.fold_bytes(&min.to_be_bytes());
7535            hasher = hasher.fold_bytes(&max.to_be_bytes());
7536        }
7537        C::Carry { site } => {
7538            hasher = hasher.fold_byte(4);
7539            hasher = hasher.fold_bytes(&site.to_be_bytes());
7540        }
7541        C::Site { position } => {
7542            hasher = hasher.fold_byte(5);
7543            hasher = hasher.fold_bytes(&position.to_be_bytes());
7544        }
7545        C::Affine {
7546            coefficients,
7547            coefficient_count,
7548            bias,
7549        } => {
7550            hasher = hasher.fold_byte(6);
7551            hasher = hasher.fold_bytes(&coefficient_count.to_be_bytes());
7552            let count = *coefficient_count as usize;
7553            let mut i = 0;
7554            while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS {
7555                hasher = hasher.fold_bytes(&coefficients[i].to_be_bytes());
7556                i += 1;
7557            }
7558            hasher = hasher.fold_bytes(&bias.to_be_bytes());
7559        }
7560        C::SatClauses { clauses, num_vars } => {
7561            hasher = hasher.fold_byte(7);
7562            hasher = hasher.fold_bytes(&num_vars.to_be_bytes());
7563            hasher = hasher.fold_bytes(&(clauses.len() as u32).to_be_bytes());
7564            let mut i = 0;
7565            while i < clauses.len() {
7566                let clause = clauses[i];
7567                hasher = hasher.fold_bytes(&(clause.len() as u32).to_be_bytes());
7568                let mut j = 0;
7569                while j < clause.len() {
7570                    let (var, neg) = clause[j];
7571                    hasher = hasher.fold_bytes(&var.to_be_bytes());
7572                    hasher = hasher.fold_byte(if neg { 1 } else { 0 });
7573                    j += 1;
7574                }
7575                i += 1;
7576            }
7577        }
7578        C::Bound {
7579            observable_iri,
7580            bound_shape_iri,
7581            args_repr,
7582        } => {
7583            hasher = hasher.fold_byte(8);
7584            hasher = hasher.fold_bytes(observable_iri.as_bytes());
7585            hasher = hasher.fold_byte(0);
7586            hasher = hasher.fold_bytes(bound_shape_iri.as_bytes());
7587            hasher = hasher.fold_byte(0);
7588            hasher = hasher.fold_bytes(args_repr.as_bytes());
7589            hasher = hasher.fold_byte(0);
7590        }
7591        C::Conjunction {
7592            conjuncts,
7593            conjunct_count,
7594        } => {
7595            hasher = hasher.fold_byte(9);
7596            hasher = hasher.fold_bytes(&conjunct_count.to_be_bytes());
7597            let count = *conjunct_count as usize;
7598            let mut i = 0;
7599            while i < count && i < crate::pipeline::CONJUNCTION_MAX_TERMS {
7600                let lifted = conjuncts[i].into_constraint();
7601                hasher = fold_constraint_ref(hasher, &lifted);
7602                i += 1;
7603            }
7604        }
7605        // ADR-057 wire-format: discriminant byte 10 + content-addressed
7606        // shape_iri + descent_bound. The discriminant table extension
7607        // requires TRACE_REPLAY_FORMAT_VERSION bump per ADR-013/TR-08.
7608        C::Recurse {
7609            shape_iri,
7610            descent_bound,
7611        } => {
7612            hasher = hasher.fold_byte(10);
7613            hasher = hasher.fold_bytes(shape_iri.as_bytes());
7614            hasher = hasher.fold_byte(0);
7615            hasher = hasher.fold_bytes(&descent_bound.to_be_bytes());
7616        }
7617    }
7618    hasher
7619}
7620
7621/// v0.2.2 T5: fold the canonical CompileUnit byte layout into a `Hasher`.
7622/// Layout: `level_bits (2 BE) || budget (8 BE) || iri bytes || 0x00 ||
7623/// site_count (8 BE) || for each constraint: fold_constraint_ref ||
7624/// certificate_kind_discriminant (1 byte trailing)`.
7625/// Locked at v0.2.2 by the `rust/trace_byte_layout_pinned` conformance
7626/// validator. Used by `pipeline::run`, `run_const`, and the four
7627/// `certify_*` entry points.
7628pub fn fold_unit_digest<H: Hasher>(
7629    mut hasher: H,
7630    level_bits: u16,
7631    budget: u64,
7632    iri: &str,
7633    site_count: usize,
7634    constraints: &[crate::pipeline::ConstraintRef],
7635    kind: CertificateKind,
7636) -> H {
7637    hasher = hasher.fold_bytes(&level_bits.to_be_bytes());
7638    hasher = hasher.fold_bytes(&budget.to_be_bytes());
7639    hasher = hasher.fold_bytes(iri.as_bytes());
7640    hasher = hasher.fold_byte(0);
7641    hasher = hasher.fold_bytes(&(site_count as u64).to_be_bytes());
7642    let mut i = 0;
7643    while i < constraints.len() {
7644        hasher = fold_constraint_ref(hasher, &constraints[i]);
7645        i += 1;
7646    }
7647    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7648    hasher
7649}
7650
7651/// v0.2.2 T5: fold the canonical ParallelDeclaration byte layout into a `Hasher`.
7652/// Layout: `site_count (8 BE) || iri bytes || 0x00 || decl_site_count (8 BE) ||
7653/// for each constraint: fold_constraint_ref || certificate_kind_discriminant`.
7654pub fn fold_parallel_digest<H: Hasher>(
7655    mut hasher: H,
7656    decl_site_count: u64,
7657    iri: &str,
7658    type_site_count: usize,
7659    constraints: &[crate::pipeline::ConstraintRef],
7660    kind: CertificateKind,
7661) -> H {
7662    hasher = hasher.fold_bytes(&decl_site_count.to_be_bytes());
7663    hasher = hasher.fold_bytes(iri.as_bytes());
7664    hasher = hasher.fold_byte(0);
7665    hasher = hasher.fold_bytes(&(type_site_count as u64).to_be_bytes());
7666    let mut i = 0;
7667    while i < constraints.len() {
7668        hasher = fold_constraint_ref(hasher, &constraints[i]);
7669        i += 1;
7670    }
7671    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7672    hasher
7673}
7674
7675/// v0.2.2 T5: fold the canonical StreamDeclaration byte layout into a `Hasher`.
7676pub fn fold_stream_digest<H: Hasher>(
7677    mut hasher: H,
7678    productivity_bound: u64,
7679    iri: &str,
7680    constraints: &[crate::pipeline::ConstraintRef],
7681    kind: CertificateKind,
7682) -> H {
7683    hasher = hasher.fold_bytes(&productivity_bound.to_be_bytes());
7684    hasher = hasher.fold_bytes(iri.as_bytes());
7685    hasher = hasher.fold_byte(0);
7686    let mut i = 0;
7687    while i < constraints.len() {
7688        hasher = fold_constraint_ref(hasher, &constraints[i]);
7689        i += 1;
7690    }
7691    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7692    hasher
7693}
7694
7695/// v0.2.2 T5: fold the canonical InteractionDeclaration byte layout into a `Hasher`.
7696pub fn fold_interaction_digest<H: Hasher>(
7697    mut hasher: H,
7698    convergence_seed: u64,
7699    iri: &str,
7700    constraints: &[crate::pipeline::ConstraintRef],
7701    kind: CertificateKind,
7702) -> H {
7703    hasher = hasher.fold_bytes(&convergence_seed.to_be_bytes());
7704    hasher = hasher.fold_bytes(iri.as_bytes());
7705    hasher = hasher.fold_byte(0);
7706    let mut i = 0;
7707    while i < constraints.len() {
7708        hasher = fold_constraint_ref(hasher, &constraints[i]);
7709        i += 1;
7710    }
7711    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7712    hasher
7713}
7714
7715/// v0.2.2 Phase J primitive: `reduction:ReductionStep` / `recursion:BoundedRecursion`.
7716/// Content-deterministic reduction signature: `(witt_bits, constraint_count, satisfiable_bit)`.
7717pub(crate) fn primitive_terminal_reduction<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
7718    witt_bits: u16,
7719) -> Result<(u16, u32, u8), PipelineFailure> {
7720    let outcome = crate::pipeline::run_reduction_stages::<T>(witt_bits)?;
7721    let satisfiable_bit: u8 = if outcome.satisfiable { 1 } else { 0 };
7722    Ok((
7723        outcome.witt_bits,
7724        T::CONSTRAINTS.len() as u32,
7725        satisfiable_bit,
7726    ))
7727}
7728
7729/// v0.2.2 Phase J: fold the TerminalReduction triple into the hasher.
7730pub(crate) fn fold_terminal_reduction<H: Hasher>(
7731    mut hasher: H,
7732    witt_bits: u16,
7733    constraint_count: u32,
7734    satisfiable_bit: u8,
7735) -> H {
7736    hasher = hasher.fold_bytes(&witt_bits.to_be_bytes());
7737    hasher = hasher.fold_bytes(&constraint_count.to_be_bytes());
7738    hasher = hasher.fold_byte(satisfiable_bit);
7739    hasher
7740}
7741
7742/// Phase X.4: `resolver:CechNerve` / `homology:ChainComplex`.
7743/// Computes the content-deterministic Betti tuple `[b_0, b_1, b_2, 0, .., 0]`
7744/// from the 2-complex constraint-nerve over `T::CONSTRAINTS`:
7745/// vertices = constraints, 1-simplices = pairs of constraints with intersecting
7746/// site support, 2-simplices = triples of constraints with a common site.
7747/// `b_k = dim ker(∂_k) - dim im(∂_{k+1})` for k ∈ {0,1,2}; `b_3..b_7 = 0`.
7748/// Ranks of the boundary operators ∂_1, ∂_2 are computed over ℤ/p (p prime,
7749/// `NERVE_RANK_MOD_P = 1_000_000_007`) by `integer_matrix_rank`. Nerve boundary
7750/// matrices have ±1/0 entries and are totally unimodular, so rank over ℤ/p
7751/// equals rank over ℚ equals rank over ℤ for any prime p not dividing a minor.
7752/// Phase 1a (orphan-closure): inputs larger than `NERVE_CONSTRAINTS_CAP = 8`
7753/// constraints or `NERVE_SITES_CAP = 8` sites return
7754/// `Err(GenericImpossibilityWitness::for_identity("NERVE_CAPACITY_EXCEEDED"))`
7755/// rather than silently truncating — truncation produced Betti numbers for a
7756/// differently-shaped complex than the caller asked about. Callers propagate
7757/// the witness via `?` (pattern mirrored on `primitive_terminal_reduction`).
7758/// ADR-057: `T::CONSTRAINTS` may contain `ConstraintRef::Recurse` entries
7759/// referencing shapes by IRI. This primitive expands Recurse references
7760/// through the **foundation built-in shape-IRI registry** (`lookup_shape`),
7761/// decrementing the descent budget on each Recurse encountered and
7762/// terminating when the budget reaches zero. Applications that register
7763/// their own shapes (via the SDK `register_shape!` macro) use
7764/// [`primitive_simplicial_nerve_betti_in`] which is generic over the
7765/// application's `ShapeRegistryProvider`. The structural reading at ψ_1
7766/// reflects the expanded constraint geometry — Recurse entries are not
7767/// opaque anonymous Sites but their structurally-substituted body per the
7768/// registered shape's `CONSTRAINTS` array.
7769/// # Errors
7770/// Returns `NERVE_CAPACITY_EXCEEDED` when either cap is exceeded after
7771/// expansion. Returns `RECURSE_SHAPE_UNREGISTERED` when a `Recurse`
7772/// entry references an IRI not present in the consulted registry
7773/// (non-zero descent budget).
7774pub fn primitive_simplicial_nerve_betti<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
7775) -> Result<[u32; MAX_BETTI_DIMENSION], GenericImpossibilityWitness> {
7776    // ADR-057: foundation-default registry path. EmptyShapeRegistry's
7777    // REGISTRY is the empty slice, so lookup_shape_in falls through to
7778    // foundation's built-in FOUNDATION_REGISTRY (the canonical stdlib path).
7779    primitive_simplicial_nerve_betti_in::<T, crate::pipeline::shape_iri_registry::EmptyShapeRegistry>(
7780    )
7781}
7782
7783/// ADR-057: registry-parameterized variant of
7784/// [`primitive_simplicial_nerve_betti`]. Walks `T::CONSTRAINTS` and expands
7785/// every `ConstraintRef::Recurse { shape_iri, descent_bound }` entry by
7786/// looking up `shape_iri` through `R`'s registry plus foundation's
7787/// built-in registry, decrementing the descent budget on each recursive
7788/// walk, and terminating when the budget reaches zero. The expanded
7789/// constraint sequence is the input to the nerve computation — the
7790/// structural reading at ψ_1 reflects the recursive grammar.
7791/// This is the entry point ψ_1 `NerveResolver` impls call from the
7792/// application's resolver-tuple — `R` is the ResolverTuple's
7793/// `ShapeRegistry` associated type per ADR-036+ADR-057.
7794/// # Errors
7795/// Returns `NERVE_CAPACITY_EXCEEDED` when the expanded constraint set
7796/// exceeds `NERVE_CONSTRAINTS_CAP` or `NERVE_SITES_CAP`. Returns
7797/// `RECURSE_SHAPE_UNREGISTERED` when a `Recurse` entry references an
7798/// IRI not present in either `R::REGISTRY` or foundation's built-in.
7799pub fn primitive_simplicial_nerve_betti_in<
7800    T: crate::pipeline::ConstrainedTypeShape + ?Sized,
7801    R: crate::pipeline::shape_iri_registry::ShapeRegistryProvider,
7802>() -> Result<[u32; MAX_BETTI_DIMENSION], GenericImpossibilityWitness> {
7803    // ADR-057 step 3: expand T::CONSTRAINTS, walking ConstraintRef::Recurse
7804    // through R's registry with bounded descent.
7805    let mut expanded: [crate::pipeline::ConstraintRef; NERVE_CONSTRAINTS_CAP] =
7806        [crate::pipeline::ConstraintRef::Site { position: 0 }; NERVE_CONSTRAINTS_CAP];
7807    let mut n_expanded: usize = 0;
7808    expand_constraints_in::<R>(T::CONSTRAINTS, u32::MAX, &mut expanded, &mut n_expanded)?;
7809    let n_constraints = n_expanded;
7810    if n_constraints > NERVE_CONSTRAINTS_CAP {
7811        return Err(GenericImpossibilityWitness::for_identity(
7812            "NERVE_CAPACITY_EXCEEDED",
7813        ));
7814    }
7815    let s_all = T::SITE_COUNT;
7816    if s_all > NERVE_SITES_CAP {
7817        return Err(GenericImpossibilityWitness::for_identity(
7818            "NERVE_CAPACITY_EXCEEDED",
7819        ));
7820    }
7821    let n_sites = s_all;
7822    let mut out = [0u32; MAX_BETTI_DIMENSION];
7823    if n_constraints == 0 {
7824        out[0] = 1;
7825        return Ok(out);
7826    }
7827    // Compute site-support bitmask per constraint (bit `s` set iff constraint touches site `s`).
7828    let mut support = [0u16; NERVE_CONSTRAINTS_CAP];
7829    let mut c = 0;
7830    while c < n_constraints {
7831        support[c] = constraint_site_support_mask_of(&expanded[c], n_sites);
7832        c += 1;
7833    }
7834    // Enumerate 1-simplices: pairs (i,j) with i<j and support[i] & support[j] != 0.
7835    // Index in c1_pairs_lo/hi corresponds to the column in ∂_1 / row in ∂_2.
7836    let mut c1_pairs_lo = [0u8; NERVE_C1_MAX];
7837    let mut c1_pairs_hi = [0u8; NERVE_C1_MAX];
7838    let mut n_c1: usize = 0;
7839    let mut i = 0;
7840    while i < n_constraints {
7841        let mut j = i + 1;
7842        while j < n_constraints {
7843            if (support[i] & support[j]) != 0 && n_c1 < NERVE_C1_MAX {
7844                c1_pairs_lo[n_c1] = i as u8;
7845                c1_pairs_hi[n_c1] = j as u8;
7846                n_c1 += 1;
7847            }
7848            j += 1;
7849        }
7850        i += 1;
7851    }
7852    // Enumerate 2-simplices: triples (i,j,k) with i<j<k and support[i] & support[j] & support[k] != 0.
7853    let mut c2_i = [0u8; NERVE_C2_MAX];
7854    let mut c2_j = [0u8; NERVE_C2_MAX];
7855    let mut c2_k = [0u8; NERVE_C2_MAX];
7856    let mut n_c2: usize = 0;
7857    let mut i2 = 0;
7858    while i2 < n_constraints {
7859        let mut j2 = i2 + 1;
7860        while j2 < n_constraints {
7861            let mut k2 = j2 + 1;
7862            while k2 < n_constraints {
7863                if (support[i2] & support[j2] & support[k2]) != 0 && n_c2 < NERVE_C2_MAX {
7864                    c2_i[n_c2] = i2 as u8;
7865                    c2_j[n_c2] = j2 as u8;
7866                    c2_k[n_c2] = k2 as u8;
7867                    n_c2 += 1;
7868                }
7869                k2 += 1;
7870            }
7871            j2 += 1;
7872        }
7873        i2 += 1;
7874    }
7875    // Build ∂_1: rows = n_constraints (vertices of the nerve), cols = n_c1.
7876    // Convention: ∂(c_i, c_j) = c_j - c_i for i < j.
7877    let mut partial_1 = [[0i64; NERVE_C1_MAX]; NERVE_CONSTRAINTS_CAP];
7878    let mut e = 0;
7879    while e < n_c1 {
7880        let lo = c1_pairs_lo[e] as usize;
7881        let hi = c1_pairs_hi[e] as usize;
7882        partial_1[lo][e] = NERVE_RANK_MOD_P - 1; // -1 mod p
7883        partial_1[hi][e] = 1;
7884        e += 1;
7885    }
7886    let rank_1 = integer_matrix_rank::<NERVE_CONSTRAINTS_CAP, NERVE_C1_MAX>(
7887        &mut partial_1,
7888        n_constraints,
7889        n_c1,
7890    );
7891    // Build ∂_2: rows = n_c1, cols = n_c2.
7892    // Convention: ∂(c_i, c_j, c_k) = (c_j, c_k) - (c_i, c_k) + (c_i, c_j).
7893    let mut partial_2 = [[0i64; NERVE_C2_MAX]; NERVE_C1_MAX];
7894    let mut t = 0;
7895    while t < n_c2 {
7896        let ti = c2_i[t];
7897        let tj = c2_j[t];
7898        let tk = c2_k[t];
7899        let idx_jk = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, tj, tk);
7900        let idx_ik = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, ti, tk);
7901        let idx_ij = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, ti, tj);
7902        if idx_jk < NERVE_C1_MAX {
7903            partial_2[idx_jk][t] = 1;
7904        }
7905        if idx_ik < NERVE_C1_MAX {
7906            partial_2[idx_ik][t] = NERVE_RANK_MOD_P - 1;
7907        }
7908        if idx_ij < NERVE_C1_MAX {
7909            partial_2[idx_ij][t] = 1;
7910        }
7911        t += 1;
7912    }
7913    let rank_2 = integer_matrix_rank::<NERVE_C1_MAX, NERVE_C2_MAX>(&mut partial_2, n_c1, n_c2);
7914    // b_0 = |C_0| - rank(∂_1). Always ≥ 1 because partial_1 has at least one all-zero row.
7915    let b0 = (n_constraints - rank_1) as u32;
7916    // b_1 = (|C_1| - rank(∂_1)) - rank(∂_2).
7917    let cycles_1 = n_c1.saturating_sub(rank_1);
7918    let b1 = cycles_1.saturating_sub(rank_2) as u32;
7919    // b_2 = |C_2| - rank(∂_2) (the complex is 2-dimensional; no ∂_3).
7920    let b2 = n_c2.saturating_sub(rank_2) as u32;
7921    out[0] = if b0 == 0 { 1 } else { b0 };
7922    if MAX_BETTI_DIMENSION > 1 {
7923        out[1] = b1;
7924    }
7925    if MAX_BETTI_DIMENSION > 2 {
7926        out[2] = b2;
7927    }
7928    Ok(out)
7929}
7930
7931/// ADR-057 step 3: walk `in_constraints`, copying non-Recurse entries into
7932/// `out_arr` and expanding every `ConstraintRef::Recurse { shape_iri,
7933/// descent_bound }` by looking up `shape_iri` through `R`'s registry plus
7934/// foundation's built-in registry and recursing into the referenced shape's
7935/// `CONSTRAINTS`. The effective descent budget at each Recurse is the min
7936/// of the caller's `descent_remaining` and the constraint's own
7937/// `descent_bound`; on Recurse the budget decrements by 1 before recursion.
7938/// A budget of 0 terminates the descent (the Recurse contributes no
7939/// further constraints — the recursion bottoms out).
7940/// # Errors
7941/// Returns `NERVE_CAPACITY_EXCEEDED` when the expansion would exceed
7942/// `NERVE_CONSTRAINTS_CAP`. Returns `RECURSE_SHAPE_UNREGISTERED` when a
7943/// `Recurse` entry with non-zero effective budget references an IRI not
7944/// present in either `R::REGISTRY` or foundation's built-in registry.
7945pub fn expand_constraints_in<R: crate::pipeline::shape_iri_registry::ShapeRegistryProvider>(
7946    in_constraints: &[crate::pipeline::ConstraintRef],
7947    descent_remaining: u32,
7948    out_arr: &mut [crate::pipeline::ConstraintRef; NERVE_CONSTRAINTS_CAP],
7949    out_n: &mut usize,
7950) -> Result<(), GenericImpossibilityWitness> {
7951    let mut i = 0;
7952    while i < in_constraints.len() {
7953        match in_constraints[i] {
7954            crate::pipeline::ConstraintRef::Recurse {
7955                shape_iri,
7956                descent_bound,
7957            } => {
7958                // Effective budget = min(caller's remaining, this Recurse's bound).
7959                let budget = if descent_remaining < descent_bound {
7960                    descent_remaining
7961                } else {
7962                    descent_bound
7963                };
7964                if budget == 0 {
7965                    // Bottom out — contribute no further constraints.
7966                } else {
7967                    match crate::pipeline::shape_iri_registry::lookup_shape_in::<R>(shape_iri) {
7968                        Some(registered) => {
7969                            expand_constraints_in::<R>(
7970                                registered.constraints,
7971                                budget - 1,
7972                                out_arr,
7973                                out_n,
7974                            )?;
7975                        }
7976                        None => {
7977                            return Err(GenericImpossibilityWitness::for_identity(
7978                                "RECURSE_SHAPE_UNREGISTERED",
7979                            ));
7980                        }
7981                    }
7982                }
7983            }
7984            other => {
7985                if *out_n >= NERVE_CONSTRAINTS_CAP {
7986                    return Err(GenericImpossibilityWitness::for_identity(
7987                        "NERVE_CAPACITY_EXCEEDED",
7988                    ));
7989                }
7990                out_arr[*out_n] = other;
7991                *out_n += 1;
7992            }
7993        }
7994        i += 1;
7995    }
7996    Ok(())
7997}
7998
7999/// Phase X.4: cap on the number of constraints considered by the nerve
8000/// primitive. Phase 1a (orphan-closure): inputs exceeding this cap are
8001/// rejected via `NERVE_CAPACITY_EXCEEDED` (was previously silent truncation).
8002/// Wiki ADR-037: alias of [`crate::HostBounds::NERVE_CONSTRAINTS_MAX`] via
8003/// [`crate::DefaultHostBounds`].
8004pub const NERVE_CONSTRAINTS_CAP: usize =
8005    <crate::DefaultHostBounds as crate::HostBounds>::NERVE_CONSTRAINTS_MAX;
8006
8007/// Phase X.4: cap on site-support bitmask width (matches `u16` storage).
8008/// Phase 1a (orphan-closure): inputs exceeding this cap are rejected via
8009/// `NERVE_CAPACITY_EXCEEDED` (was previously silent truncation).
8010/// Wiki ADR-037: alias of [`crate::HostBounds::NERVE_SITES_MAX`] via
8011/// [`crate::DefaultHostBounds`].
8012pub const NERVE_SITES_CAP: usize = <crate::DefaultHostBounds as crate::HostBounds>::NERVE_SITES_MAX;
8013
8014/// Phase X.4: maximum number of 1-simplices = C(NERVE_CONSTRAINTS_CAP, 2) = 28.
8015pub const NERVE_C1_MAX: usize = 28;
8016
8017/// Phase X.4: maximum number of 2-simplices = C(NERVE_CONSTRAINTS_CAP, 3) = 56.
8018pub const NERVE_C2_MAX: usize = 56;
8019
8020/// Phase X.4: prime modulus for nerve boundary-matrix rank computation.
8021/// Chosen so `(i64 * i64) mod p` never overflows (`p² < 2⁶³`). Nerve boundary
8022/// matrices have entries in {-1, 0, 1}; rank over ℤ/p equals rank over ℚ.
8023pub(crate) const NERVE_RANK_MOD_P: i64 = 1_000_000_007;
8024
8025/// Phase X.4: per-constraint site-support bitmask. Returns bit `s` set iff
8026/// constraint `c` touches site index `s` (`s < n_sites`).
8027/// `Affine { coefficients, .. }` returns the bitmask of sites whose
8028/// coefficient is non-zero — the natural "site support" of the affine
8029/// relation. Remaining non-site-local variants (Residue, Hamming, Depth,
8030/// Bound, Conjunction, SatClauses) return an all-ones mask over `n_sites`.
8031/// ADR-057: slice-based — operates directly on a `&ConstraintRef` rather
8032/// than indexing a `ConstrainedTypeShape::CONSTRAINTS` slot. ψ_1 calls this
8033/// from [`primitive_simplicial_nerve_betti_in`] after `T::CONSTRAINTS` has
8034/// been expanded into a fixed-size array via [`expand_constraints_in`].
8035pub(crate) const fn constraint_site_support_mask_of(
8036    c: &crate::pipeline::ConstraintRef,
8037    n_sites: usize,
8038) -> u16 {
8039    let all_mask: u16 = if n_sites == 0 {
8040        0
8041    } else {
8042        (1u16 << n_sites) - 1
8043    };
8044    match c {
8045        crate::pipeline::ConstraintRef::Site { position } => {
8046            if n_sites == 0 {
8047                0
8048            } else {
8049                1u16 << (*position as usize % n_sites)
8050            }
8051        }
8052        crate::pipeline::ConstraintRef::Carry { site } => {
8053            if n_sites == 0 {
8054                0
8055            } else {
8056                1u16 << (*site as usize % n_sites)
8057            }
8058        }
8059        crate::pipeline::ConstraintRef::Affine {
8060            coefficients,
8061            coefficient_count,
8062            ..
8063        } => {
8064            if n_sites == 0 {
8065                0
8066            } else {
8067                let mut mask: u16 = 0;
8068                let count = *coefficient_count as usize;
8069                let mut i = 0;
8070                while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS && i < n_sites {
8071                    if coefficients[i] != 0 {
8072                        mask |= 1u16 << i;
8073                    }
8074                    i += 1;
8075                }
8076                if mask == 0 {
8077                    all_mask
8078                } else {
8079                    mask
8080                }
8081            }
8082        }
8083        // ADR-057: any Recurse entry left in the array means
8084        // expand_constraints_in already bottomed out (descent_bound = 0).
8085        // Treat it as a structural placeholder with no specific site support.
8086        _ => all_mask,
8087    }
8088}
8089
8090/// Phase X.4: find the column index of the 1-simplex (lo, hi) in the enumerated
8091/// pair list. Returns `NERVE_C1_MAX` (sentinel = not found) when absent.
8092pub(crate) const fn find_pair_index(
8093    lo_arr: &[u8; NERVE_C1_MAX],
8094    hi_arr: &[u8; NERVE_C1_MAX],
8095    n_c1: usize,
8096    lo: u8,
8097    hi: u8,
8098) -> usize {
8099    let mut i = 0;
8100    while i < n_c1 {
8101        if lo_arr[i] == lo && hi_arr[i] == hi {
8102            return i;
8103        }
8104        i += 1;
8105    }
8106    NERVE_C1_MAX
8107}
8108
8109/// Phase X.4: rank of an integer matrix over ℤ/`NERVE_RANK_MOD_P` via modular
8110/// Gaussian elimination. Entries are reduced mod p and elimination uses
8111/// Fermat-inverse pivot normalization. For ±1/0 boundary matrices this
8112/// coincides with rank over ℤ.
8113pub(crate) const fn integer_matrix_rank<const R: usize, const C: usize>(
8114    matrix: &mut [[i64; C]; R],
8115    rows: usize,
8116    cols: usize,
8117) -> usize {
8118    let p = NERVE_RANK_MOD_P;
8119    // Reduce all entries into [0, p).
8120    let mut r = 0;
8121    while r < rows {
8122        let mut c = 0;
8123        while c < cols {
8124            let v = matrix[r][c] % p;
8125            matrix[r][c] = if v < 0 { v + p } else { v };
8126            c += 1;
8127        }
8128        r += 1;
8129    }
8130    let mut rank: usize = 0;
8131    let mut col: usize = 0;
8132    while col < cols && rank < rows {
8133        // Find a pivot row in column `col`, starting at `rank`.
8134        let mut pivot_row = rank;
8135        while pivot_row < rows && matrix[pivot_row][col] == 0 {
8136            pivot_row += 1;
8137        }
8138        if pivot_row == rows {
8139            col += 1;
8140            continue;
8141        }
8142        // Swap into position.
8143        if pivot_row != rank {
8144            let mut k = 0;
8145            while k < cols {
8146                let tmp = matrix[rank][k];
8147                matrix[rank][k] = matrix[pivot_row][k];
8148                matrix[pivot_row][k] = tmp;
8149                k += 1;
8150            }
8151        }
8152        // Normalize pivot row to have leading 1.
8153        let pivot = matrix[rank][col];
8154        let pivot_inv = mod_pow(pivot, p - 2, p);
8155        let mut k = 0;
8156        while k < cols {
8157            matrix[rank][k] = (matrix[rank][k] * pivot_inv) % p;
8158            k += 1;
8159        }
8160        // Eliminate the column entry from every other row.
8161        let mut r2 = 0;
8162        while r2 < rows {
8163            if r2 != rank {
8164                let factor = matrix[r2][col];
8165                if factor != 0 {
8166                    let mut kk = 0;
8167                    while kk < cols {
8168                        let sub = (matrix[rank][kk] * factor) % p;
8169                        let mut v = matrix[r2][kk] - sub;
8170                        v %= p;
8171                        if v < 0 {
8172                            v += p;
8173                        }
8174                        matrix[r2][kk] = v;
8175                        kk += 1;
8176                    }
8177                }
8178            }
8179            r2 += 1;
8180        }
8181        rank += 1;
8182        col += 1;
8183    }
8184    rank
8185}
8186
8187/// Phase X.4: modular exponentiation `base^exp mod p`, const-fn. Used by
8188/// `integer_matrix_rank` via Fermat's little theorem for modular inverses.
8189pub(crate) const fn mod_pow(base: i64, exp: i64, p: i64) -> i64 {
8190    let mut result: i64 = 1;
8191    let mut b = ((base % p) + p) % p;
8192    let mut e = exp;
8193    while e > 0 {
8194        if e & 1 == 1 {
8195            result = (result * b) % p;
8196        }
8197        b = (b * b) % p;
8198        e >>= 1;
8199    }
8200    result
8201}
8202
8203/// v0.2.2 Phase J: fold the Betti tuple into the hasher.
8204pub(crate) fn fold_betti_tuple<H: Hasher>(mut hasher: H, betti: &[u32; MAX_BETTI_DIMENSION]) -> H {
8205    let mut i = 0;
8206    while i < MAX_BETTI_DIMENSION {
8207        hasher = hasher.fold_bytes(&betti[i].to_be_bytes());
8208        i += 1;
8209    }
8210    hasher
8211}
8212
8213/// v0.2.2 Phase J: Euler characteristic `χ = Σ(-1)^k b_k` from the Betti tuple.
8214#[must_use]
8215pub(crate) fn primitive_euler_characteristic(betti: &[u32; MAX_BETTI_DIMENSION]) -> i64 {
8216    let mut chi: i64 = 0;
8217    let mut k = 0;
8218    while k < MAX_BETTI_DIMENSION {
8219        let term = betti[k] as i64;
8220        if k % 2 == 0 {
8221            chi += term;
8222        } else {
8223            chi -= term;
8224        }
8225        k += 1;
8226    }
8227    chi
8228}
8229
8230/// v0.2.2 Phase J primitive: `op:DihedralGroup` / `op:D_7`.
8231/// Returns `(orbit_size, representative)` under D_{2^n} acting on `T::SITE_COUNT`.
8232/// `orbit_size = 2n` when n ≥ 2, 2 when n == 1, 1 when n == 0 (group identity only).
8233/// `representative` is the lexicographically-minimal element of the orbit of
8234/// site 0 under D_{2n}: rotations `r^k → k mod n` and reflections `s·r^k → (n - k) mod n`.
8235/// For the orbit of site 0, both maps produce 0 as a group element, so the
8236/// representative is always 0; for a non-canonical starting index `i`, the
8237/// representative would be `min(i, (n - i) mod n)`. This helper uses site 0 as the
8238/// canonical starting point (the foundation's convention), so the representative
8239/// reflects the orbit's algebraic content, not a sentinel.
8240pub(crate) fn primitive_dihedral_signature<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8241) -> (u32, u32) {
8242    let n = T::SITE_COUNT as u32;
8243    let orbit_size = if n < 2 {
8244        if n == 0 {
8245            1
8246        } else {
8247            2
8248        }
8249    } else {
8250        2 * n
8251    };
8252    // v0.2.2 Phase S.2: compute the lexicographically-minimal orbit element.
8253    // Orbit of site 0 under D_{2n} contains: rotation images {0, 1, ..., n-1}
8254    // (since r^k maps 0 → k mod n) and reflection images {0, n-1, n-2, ..., 1}
8255    // (since s·r^k maps 0 → (n - k) mod n). The union is {0, 1, ..., n-1}.
8256    // The lex-min is 0 by construction; formalize it by min-walking the orbit.
8257    let mut rep: u32 = 0;
8258    let mut k = 1u32;
8259    while k < n {
8260        let rot = k % n;
8261        let refl = (n - k) % n;
8262        if rot < rep {
8263            rep = rot;
8264        }
8265        if refl < rep {
8266            rep = refl;
8267        }
8268        k += 1;
8269    }
8270    (orbit_size, rep)
8271}
8272
8273/// v0.2.2 Phase J: fold the dihedral `(orbit_size, representative)` pair.
8274pub(crate) fn fold_dihedral_signature<H: Hasher>(
8275    mut hasher: H,
8276    orbit_size: u32,
8277    representative: u32,
8278) -> H {
8279    hasher = hasher.fold_bytes(&orbit_size.to_be_bytes());
8280    hasher = hasher.fold_bytes(&representative.to_be_bytes());
8281    hasher
8282}
8283
8284/// v0.2.2 Phase J primitive: `observable:Jacobian` / `op:DC_10`.
8285/// Content-deterministic per-site Jacobian profile: for each site `i`, the number
8286/// of constraints that mention site index `i` (derived from the constraint encoding).
8287/// Truncated / zero-padded to `JACOBIAN_MAX_SITES` entries to keep the fold fixed-size.
8288pub(crate) fn primitive_curvature_jacobian<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8289) -> [i32; JACOBIAN_MAX_SITES] {
8290    let mut out = [0i32; JACOBIAN_MAX_SITES];
8291    let mut ci = 0;
8292    while ci < T::CONSTRAINTS.len() {
8293        if let crate::pipeline::ConstraintRef::Site { position } = T::CONSTRAINTS[ci] {
8294            let idx = (position as usize) % JACOBIAN_MAX_SITES;
8295            out[idx] = out[idx].saturating_add(1);
8296        }
8297        ci += 1;
8298    }
8299    // Also account for residue and hamming constraints as contributing uniformly
8300    // across all sites (they are not site-local). Represented as +1 to site 0.
8301    let total = T::CONSTRAINTS.len() as i32;
8302    out[0] = out[0].saturating_add(total);
8303    out
8304}
8305
8306/// v0.2.2 Phase J: DC_10 selects the site with the maximum absolute Jacobian value.
8307#[must_use]
8308pub(crate) fn primitive_dc10_select(jac: &[i32; JACOBIAN_MAX_SITES]) -> usize {
8309    let mut best_idx: usize = 0;
8310    let mut best_abs: i32 = jac[0].unsigned_abs() as i32;
8311    let mut i = 1;
8312    while i < JACOBIAN_MAX_SITES {
8313        let a = jac[i].unsigned_abs() as i32;
8314        if a > best_abs {
8315            best_abs = a;
8316            best_idx = i;
8317        }
8318        i += 1;
8319    }
8320    best_idx
8321}
8322
8323/// v0.2.2 Phase J: fold the Jacobian profile into the hasher.
8324pub(crate) fn fold_jacobian_profile<H: Hasher>(
8325    mut hasher: H,
8326    jac: &[i32; JACOBIAN_MAX_SITES],
8327) -> H {
8328    let mut i = 0;
8329    while i < JACOBIAN_MAX_SITES {
8330        hasher = hasher.fold_bytes(&jac[i].to_be_bytes());
8331        i += 1;
8332    }
8333    hasher
8334}
8335
8336/// v0.2.2 Phase J primitive: `state:BindingAccumulator` / `state:ContextLease`.
8337/// Returns `(binding_count, fold_address)` — a content-deterministic session signature.
8338/// v0.2.2 Phase S.4: uses an FNV-1a-style order-preserving incremental hash
8339/// (rotate-and-multiply) over each binding's `(name_index, type_index,
8340/// content_address)` tuple, rather than XOR-accumulation (which is commutative
8341/// and collides on reordered-but-otherwise-identical binding sets). Order-dependence
8342/// is intentional: `state:BindingAccumulator` semantics treat the insertion
8343/// sequence as part of the session signature.
8344pub(crate) fn primitive_session_binding_signature(bindings: &[Binding]) -> (u32, u64) {
8345    // FNV-1a-style incremental mix: start from the FNV offset basis,
8346    // multiply-then-XOR each limb. Order-dependent by construction.
8347    let mut fold: u64 = 0xcbf2_9ce4_8422_2325;
8348    const FNV_PRIME: u64 = 0x0000_0100_0000_01b3;
8349    let mut i = 0;
8350    while i < bindings.len() {
8351        let b = &bindings[i];
8352        // Mix in (name_index, type_index, content_address) per binding.
8353        fold = fold.wrapping_mul(FNV_PRIME);
8354        fold ^= b.name_index as u64;
8355        fold = fold.wrapping_mul(FNV_PRIME);
8356        fold ^= b.type_index as u64;
8357        fold = fold.wrapping_mul(FNV_PRIME);
8358        fold ^= b.content_address;
8359        i += 1;
8360    }
8361    (bindings.len() as u32, fold)
8362}
8363
8364/// v0.2.2 Phase J: fold the session-binding signature into the hasher.
8365pub(crate) fn fold_session_signature<H: Hasher>(
8366    mut hasher: H,
8367    binding_count: u32,
8368    fold_address: u64,
8369) -> H {
8370    hasher = hasher.fold_bytes(&binding_count.to_be_bytes());
8371    hasher = hasher.fold_bytes(&fold_address.to_be_bytes());
8372    hasher
8373}
8374
8375/// v0.2.2 Phase J primitive: `op:QM_1` / `op:QM_5` / `resolver:collapseAmplitude`.
8376/// Seeds a two-state amplitude vector from the CompileUnit's thermodynamic budget,
8377/// computes Born-rule probabilities `P(0) = |α_0|²` and `P(1) = |α_1|²`,
8378/// verifies QM_5 normalization `Σ P = 1`, and returns `(outcome_index, probability)`
8379/// where `outcome_index` is the index of the larger amplitude and `probability` is its value.
8380/// QM_1 Landauer equality: `pre_entropy == post_cost` at β* = ln 2; since both
8381/// sides derive from the same budget the equality holds by construction.
8382/// v0.2.2 Phase S.3: amplitudes are sourced from two decorrelated projections
8383/// of the thermodynamic budget — the high 32 bits become the alpha-0
8384/// magnitude and the low 32 bits become the alpha-1 magnitude. This replaces
8385/// the earlier XOR-with-fixed-constants sourcing, preserving determinism while
8386/// ensuring both amplitudes derive from independent halves of the budget's
8387/// thermodynamic-entropy state. Born normalization and QM_1 Landauer equality
8388/// remain invariant under this sourcing change.
8389pub(crate) fn primitive_measurement_projection(budget: u64) -> (u64, u64) {
8390    // Decorrelated amplitude sourcing: high-32-bits drives alpha_0,
8391    // low-32-bits drives alpha_1. Distinct bit halves yield independent
8392    // magnitudes under any non-degenerate budget.
8393    let alpha0_bits: u32 = (budget >> 32) as u32;
8394    let alpha1_bits: u32 = (budget & 0xFFFF_FFFF) as u32;
8395    type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
8396    let a0 = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(alpha0_bits)
8397        / <DefaultDecimal as crate::DecimalTranscendental>::from_u32(u32::MAX);
8398    let a1 = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(alpha1_bits)
8399        / <DefaultDecimal as crate::DecimalTranscendental>::from_u32(u32::MAX);
8400    let norm = a0 * a0 + a1 * a1;
8401    let zero = <DefaultDecimal as Default>::default();
8402    let half =
8403        <DefaultDecimal as crate::DecimalTranscendental>::from_bits(0x3FE0_0000_0000_0000_u64);
8404    // QM_5 normalization: P(k) = |alpha_k|^2 / norm. Degenerate budget = 0
8405    // yields norm = 0; fall through to the uniform distribution (P(0) = 0.5,
8406    // P(1) = 0.5), which is the maximum-entropy projection under QM_1.
8407    let p0 = if norm > zero { (a0 * a0) / norm } else { half };
8408    let p1 = if norm > zero { (a1 * a1) / norm } else { half };
8409    if p0 >= p1 {
8410        (
8411            0,
8412            <DefaultDecimal as crate::DecimalTranscendental>::to_bits(p0),
8413        )
8414    } else {
8415        (
8416            1,
8417            <DefaultDecimal as crate::DecimalTranscendental>::to_bits(p1),
8418        )
8419    }
8420}
8421
8422/// v0.2.2 Phase J / Phase 9: fold the Born-rule outcome into the hasher.
8423/// `probability_bits` is the IEEE-754 bit pattern (call sites convert via
8424/// `<H::Decimal as DecimalTranscendental>::to_bits` if working in `H::Decimal`).
8425pub(crate) fn fold_born_outcome<H: Hasher>(
8426    mut hasher: H,
8427    outcome_index: u64,
8428    probability_bits: u64,
8429) -> H {
8430    hasher = hasher.fold_bytes(&outcome_index.to_be_bytes());
8431    hasher = hasher.fold_bytes(&probability_bits.to_be_bytes());
8432    hasher
8433}
8434
8435/// v0.2.2 Phase J primitive: `recursion:DescentMeasure` / `observable:ResidualEntropy`.
8436/// Computes `(residual_count, entropy_bits)` from `T::SITE_COUNT` and the Euler char.
8437/// `residual_count = max(0, site_count - euler_char)` — free sites after constraint contraction.
8438/// `entropy = (residual_count) × ln 2` — Landauer-temperature entropy in nats.
8439/// Phase 9: returns `(residual_count, entropy_bits)` where `entropy_bits` is the
8440/// IEEE-754 bit pattern of `residual × ln 2`. Consumers project to `H::Decimal`
8441/// via `<H::Decimal as DecimalTranscendental>::from_bits`.
8442pub(crate) fn primitive_descent_metrics<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8443    betti: &[u32; MAX_BETTI_DIMENSION],
8444) -> (u32, u64) {
8445    let chi = primitive_euler_characteristic(betti);
8446    let n = T::SITE_COUNT as i64;
8447    let residual = if n > chi { (n - chi) as u32 } else { 0u32 };
8448    type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
8449    let residual_d = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(residual);
8450    let ln_2 = <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
8451    let entropy = residual_d * ln_2;
8452    (
8453        residual,
8454        <DefaultDecimal as crate::DecimalTranscendental>::to_bits(entropy),
8455    )
8456}
8457
8458/// v0.2.2 Phase J / Phase 9: fold the descent metrics into the hasher.
8459/// `entropy_bits` is the IEEE-754 bit pattern of the descent entropy.
8460pub(crate) fn fold_descent_metrics<H: Hasher>(
8461    mut hasher: H,
8462    residual_count: u32,
8463    entropy_bits: u64,
8464) -> H {
8465    hasher = hasher.fold_bytes(&residual_count.to_be_bytes());
8466    hasher = hasher.fold_bytes(&entropy_bits.to_be_bytes());
8467    hasher
8468}
8469
8470/// Phase X.2: upper bound on cohomology class dimension. Cup products
8471/// whose summed dimension exceeds this cap are rejected as
8472/// `CohomologyError::DimensionOverflow`.
8473pub const MAX_COHOMOLOGY_DIMENSION: u32 = 32;
8474
8475/// Phase X.2: a cohomology class `H^n(·)` at dimension `n` with a content
8476/// fingerprint of the underlying cochain representative. Parametric over
8477/// dimension via a runtime field because generic-const-expression arithmetic
8478/// over `N + M` is unstable at the crate's MSRV (Rust 1.81).
8479#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8480pub struct CohomologyClass {
8481    dimension: u32,
8482    fingerprint: ContentFingerprint,
8483    _sealed: (),
8484}
8485
8486impl CohomologyClass {
8487    /// Phase X.2: crate-sealed constructor. Public callers go through
8488    /// `mint_cohomology_class` so that construction always routes through a
8489    /// validating hash of the cochain representative.
8490    #[inline]
8491    pub(crate) const fn with_dimension_and_fingerprint(
8492        dimension: u32,
8493        fingerprint: ContentFingerprint,
8494    ) -> Self {
8495        Self {
8496            dimension,
8497            fingerprint,
8498            _sealed: (),
8499        }
8500    }
8501
8502    /// The dimension `n` of this cohomology class `H^n(·)`.
8503    #[inline]
8504    #[must_use]
8505    pub const fn dimension(&self) -> u32 {
8506        self.dimension
8507    }
8508
8509    /// The content fingerprint of the underlying cochain representative.
8510    #[inline]
8511    #[must_use]
8512    pub const fn fingerprint(&self) -> ContentFingerprint {
8513        self.fingerprint
8514    }
8515
8516    /// Phase X.2: cup product `H^n × H^m → H^{n+m}`. The resulting class
8517    /// carries dimension `n + m` and a fingerprint folded from both
8518    /// operand dimensions and fingerprints via `fold_cup_product`. The
8519    /// fold is ordered (lhs-then-rhs) — graded-commutativity of the cup
8520    /// product at the algebraic level is not a fingerprint-level property.
8521    /// # Errors
8522    /// Returns `CohomologyError::DimensionOverflow` when `n + m >
8523    /// MAX_COHOMOLOGY_DIMENSION`.
8524    pub fn cup<H: Hasher>(
8525        self,
8526        other: CohomologyClass,
8527    ) -> Result<CohomologyClass, CohomologyError> {
8528        let sum = self.dimension.saturating_add(other.dimension);
8529        if sum > MAX_COHOMOLOGY_DIMENSION {
8530            return Err(CohomologyError::DimensionOverflow {
8531                lhs: self.dimension,
8532                rhs: other.dimension,
8533            });
8534        }
8535        let hasher = H::initial();
8536        let hasher = fold_cup_product(
8537            hasher,
8538            self.dimension,
8539            &self.fingerprint,
8540            other.dimension,
8541            &other.fingerprint,
8542        );
8543        let buf = hasher.finalize();
8544        let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8545        Ok(Self::with_dimension_and_fingerprint(sum, fp))
8546    }
8547}
8548
8549/// Phase X.2: error returned by `CohomologyClass::cup` when the summed
8550/// dimension exceeds `MAX_COHOMOLOGY_DIMENSION`.
8551#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8552pub enum CohomologyError {
8553    /// Cup product would exceed `MAX_COHOMOLOGY_DIMENSION`.
8554    DimensionOverflow { lhs: u32, rhs: u32 },
8555}
8556
8557impl core::fmt::Display for CohomologyError {
8558    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8559        match self {
8560            Self::DimensionOverflow { lhs, rhs } => write!(
8561                f,
8562                "cup product dimension overflow: {lhs} + {rhs} > MAX_COHOMOLOGY_DIMENSION ({})",
8563                MAX_COHOMOLOGY_DIMENSION
8564            ),
8565        }
8566    }
8567}
8568impl core::error::Error for CohomologyError {}
8569
8570/// Phase X.2: homology class dual to `CohomologyClass`. A homology class
8571/// `H_n(·)` at dimension `n` with a content fingerprint of its chain
8572/// representative. Shares the dimension-as-runtime-field discipline.
8573#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8574pub struct HomologyClass {
8575    dimension: u32,
8576    fingerprint: ContentFingerprint,
8577    _sealed: (),
8578}
8579
8580impl HomologyClass {
8581    /// Phase X.2: crate-sealed constructor. Public callers go through
8582    /// `mint_homology_class`.
8583    #[inline]
8584    pub(crate) const fn with_dimension_and_fingerprint(
8585        dimension: u32,
8586        fingerprint: ContentFingerprint,
8587    ) -> Self {
8588        Self {
8589            dimension,
8590            fingerprint,
8591            _sealed: (),
8592        }
8593    }
8594
8595    /// The dimension `n` of this homology class `H_n(·)`.
8596    #[inline]
8597    #[must_use]
8598    pub const fn dimension(&self) -> u32 {
8599        self.dimension
8600    }
8601
8602    /// The content fingerprint of the underlying chain representative.
8603    #[inline]
8604    #[must_use]
8605    pub const fn fingerprint(&self) -> ContentFingerprint {
8606        self.fingerprint
8607    }
8608}
8609
8610/// Phase X.2: fold the cup-product operand pair into the hasher. Ordered
8611/// (lhs dimension + fingerprint, then rhs dimension + fingerprint).
8612pub fn fold_cup_product<H: Hasher>(
8613    mut hasher: H,
8614    lhs_dim: u32,
8615    lhs_fp: &ContentFingerprint,
8616    rhs_dim: u32,
8617    rhs_fp: &ContentFingerprint,
8618) -> H {
8619    hasher = hasher.fold_bytes(&lhs_dim.to_be_bytes());
8620    hasher = hasher.fold_bytes(lhs_fp.as_bytes());
8621    hasher = hasher.fold_bytes(&rhs_dim.to_be_bytes());
8622    hasher = hasher.fold_bytes(rhs_fp.as_bytes());
8623    hasher
8624}
8625
8626/// Phase X.2: mint a `CohomologyClass` from a cochain representative `seed`.
8627/// Hashes `seed` through `H` to produce the class fingerprint. The caller's
8628/// choice of `H` determines the fingerprint width.
8629/// # Errors
8630/// Returns `CohomologyError::DimensionOverflow` when `dimension >
8631/// MAX_COHOMOLOGY_DIMENSION`.
8632pub fn mint_cohomology_class<H: Hasher>(
8633    dimension: u32,
8634    seed: &[u8],
8635) -> Result<CohomologyClass, CohomologyError> {
8636    if dimension > MAX_COHOMOLOGY_DIMENSION {
8637        return Err(CohomologyError::DimensionOverflow {
8638            lhs: dimension,
8639            rhs: 0,
8640        });
8641    }
8642    let mut hasher = H::initial();
8643    hasher = hasher.fold_bytes(&dimension.to_be_bytes());
8644    hasher = hasher.fold_bytes(seed);
8645    let buf = hasher.finalize();
8646    let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8647    Ok(CohomologyClass::with_dimension_and_fingerprint(
8648        dimension, fp,
8649    ))
8650}
8651
8652/// Phase X.2: mint a `HomologyClass` from a chain representative `seed`.
8653/// Hashes `seed` through `H` to produce the class fingerprint.
8654/// # Errors
8655/// Returns `CohomologyError::DimensionOverflow` when `dimension >
8656/// MAX_COHOMOLOGY_DIMENSION`.
8657pub fn mint_homology_class<H: Hasher>(
8658    dimension: u32,
8659    seed: &[u8],
8660) -> Result<HomologyClass, CohomologyError> {
8661    if dimension > MAX_COHOMOLOGY_DIMENSION {
8662        return Err(CohomologyError::DimensionOverflow {
8663            lhs: dimension,
8664            rhs: 0,
8665        });
8666    }
8667    let mut hasher = H::initial();
8668    hasher = hasher.fold_bytes(&dimension.to_be_bytes());
8669    hasher = hasher.fold_bytes(seed);
8670    let buf = hasher.finalize();
8671    let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8672    Ok(HomologyClass::with_dimension_and_fingerprint(dimension, fp))
8673}
8674
8675/// v0.2.2 T6.1: per-step canonical byte layout for `StreamDriver::next()`.
8676/// Layout: `productivity_remaining (8 BE) || rewrite_steps (8 BE) || seed (8 BE) ||
8677/// iri bytes || 0x00 || certificate_kind_discriminant (1 byte trailing)`.
8678pub fn fold_stream_step_digest<H: Hasher>(
8679    mut hasher: H,
8680    productivity_remaining: u64,
8681    rewrite_steps: u64,
8682    seed: u64,
8683    iri: &str,
8684    kind: CertificateKind,
8685) -> H {
8686    hasher = hasher.fold_bytes(&productivity_remaining.to_be_bytes());
8687    hasher = hasher.fold_bytes(&rewrite_steps.to_be_bytes());
8688    hasher = hasher.fold_bytes(&seed.to_be_bytes());
8689    hasher = hasher.fold_bytes(iri.as_bytes());
8690    hasher = hasher.fold_byte(0);
8691    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
8692    hasher
8693}
8694
8695/// v0.2.2 T6.1: per-step canonical byte layout for `InteractionDriver::step()`
8696/// and `InteractionDriver::finalize()`.
8697/// Layout: `commutator_acc[0..4] (4 × 8 BE bytes) || peer_step_count (8 BE) ||
8698/// seed (8 BE) || iri bytes || 0x00 || certificate_kind_discriminant (1 byte trailing)`.
8699pub fn fold_interaction_step_digest<H: Hasher>(
8700    mut hasher: H,
8701    commutator_acc: &[u64; 4],
8702    peer_step_count: u64,
8703    seed: u64,
8704    iri: &str,
8705    kind: CertificateKind,
8706) -> H {
8707    let mut i = 0;
8708    while i < 4 {
8709        hasher = hasher.fold_bytes(&commutator_acc[i].to_be_bytes());
8710        i += 1;
8711    }
8712    hasher = hasher.fold_bytes(&peer_step_count.to_be_bytes());
8713    hasher = hasher.fold_bytes(&seed.to_be_bytes());
8714    hasher = hasher.fold_bytes(iri.as_bytes());
8715    hasher = hasher.fold_byte(0);
8716    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
8717    hasher
8718}
8719
8720/// Utility — extract the leading 16 bytes of a `Hasher::finalize` buffer
8721/// as a `ContentAddress`. Used by pipeline entry points to derive the
8722/// 16-byte unit_address handle from a freshly-computed substrate
8723/// fingerprint, so two units with distinct fingerprints have distinct
8724/// unit_address handles too.
8725/// Per the wiki's ADR-018 the `FP_MAX` const-generic carries the
8726/// application's selected `<B as HostBounds>::FINGERPRINT_MAX_BYTES`.
8727/// `FP_MAX` MUST be at least 16; smaller buffers cannot supply the
8728/// 16-byte address prefix.
8729#[inline]
8730#[must_use]
8731pub const fn unit_address_from_buffer<const FP_MAX: usize>(
8732    buffer: &[u8; FP_MAX],
8733) -> ContentAddress {
8734    let mut bytes = [0u8; 16];
8735    let mut i = 0;
8736    while i < 16 {
8737        bytes[i] = buffer[i];
8738        i += 1;
8739    }
8740    ContentAddress::from_u128(u128::from_be_bytes(bytes))
8741}
8742
8743/// v0.2.2 T6.11: const-fn equality on `&str` slices. `str::eq` is not
8744/// stable in const eval under MSRV 1.81; this helper provides a
8745/// byte-by-byte equality check for use in `pipeline::run`'s ShapeMismatch
8746/// detection without runtime allocation.
8747#[inline]
8748#[must_use]
8749pub const fn str_eq(a: &str, b: &str) -> bool {
8750    let a = a.as_bytes();
8751    let b = b.as_bytes();
8752    if a.len() != b.len() {
8753        return false;
8754    }
8755    let mut i = 0;
8756    while i < a.len() {
8757        if a[i] != b[i] {
8758            return false;
8759        }
8760        i += 1;
8761    }
8762    true
8763}
8764
8765/// A binding entry in a `BindingsTable`. Pairs a `ContentAddress`
8766/// (hash of the query coordinate) with the bound bytes.
8767#[derive(Debug, Clone, Copy)]
8768pub struct BindingEntry {
8769    /// Content-hashed query address.
8770    pub address: ContentAddress,
8771    /// Bound payload bytes (length determined by the WittLevel of the table).
8772    pub bytes: &'static [u8],
8773}
8774
8775/// A static, sorted-by-address binding table laid out for `op:GS_5` zero-step
8776/// access. Looked up via binary search; the foundation guarantees the table
8777/// is materialized at compile time from the attested `state:GroundedContext`.
8778#[derive(Debug, Clone, Copy)]
8779pub struct BindingsTable {
8780    /// Entries, sorted ascending by `address`.
8781    pub entries: &'static [BindingEntry],
8782}
8783
8784impl BindingsTable {
8785    /// v0.2.2 T5 C4: validating constructor. Checks that `entries` are
8786    /// strictly ascending by `address`, which is the invariant
8787    /// `Grounded::get_binding` relies on for its binary-search lookup.
8788    /// # Errors
8789    /// Returns `BindingsTableError::Unsorted { at }` where `at` is the first
8790    /// index where the order is violated (i.e., `entries[at].address <=
8791    /// entries[at - 1].address`).
8792    pub const fn try_new(entries: &'static [BindingEntry]) -> Result<Self, BindingsTableError> {
8793        let mut i = 1;
8794        while i < entries.len() {
8795            if entries[i].address.as_u128() <= entries[i - 1].address.as_u128() {
8796                return Err(BindingsTableError::Unsorted { at: i });
8797            }
8798            i += 1;
8799        }
8800        Ok(Self { entries })
8801    }
8802}
8803
8804/// v0.2.2 T5 C4: errors returned by `BindingsTable::try_new`.
8805#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8806#[non_exhaustive]
8807pub enum BindingsTableError {
8808    /// Entries at index `at` and `at - 1` are out of order (the slice is
8809    /// not strictly ascending by `address`).
8810    Unsorted {
8811        /// The first index where the order is violated.
8812        at: usize,
8813    },
8814}
8815
8816impl core::fmt::Display for BindingsTableError {
8817    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8818        match self {
8819            Self::Unsorted { at } => write!(
8820                f,
8821                "BindingsTable entries not sorted: address at index {at} <= address at index {}",
8822                at - 1,
8823            ),
8824        }
8825    }
8826}
8827
8828impl core::error::Error for BindingsTableError {}
8829
8830/// The compile-time witness that `op:GS_4` holds for the value it carries:
8831/// σ = 1, freeRank = 0, S = 0, T_ctx = 0. `Grounded<T, Tag>` is constructed
8832/// only by the reduction pipeline and provides `op:GS_5` zero-step binding access.
8833/// v0.2.2 Phase B (Q3): the `Tag` phantom parameter (default `Tag = T`)
8834/// lets downstream code attach a domain marker to a grounded witness without
8835/// any new sealing — e.g., `Grounded<ConstrainedTypeInput, BlockHashTag>` is
8836/// a distinct Rust type from `Grounded<ConstrainedTypeInput, PixelTag>`. The
8837/// inner witness is unchanged; the tag is pure decoration. The foundation
8838/// guarantees ring soundness on the inner witness; the tag is the developer's
8839/// domain claim. Coerce via `Grounded::tag::<NewTag>()` (zero-cost).
8840///
8841/// # Wiki ADR-039 — Inhabitance verdict realization mapping
8842///
8843/// For typed feature hierarchies whose admission relations are
8844/// inhabitance questions, a successful `Grounded<Output>` IS a
8845/// `cert:InhabitanceCertificate` envelope:
8846///
8847/// - The κ-label (homotopy-classification structural witness at ψ_9
8848///   per ADR-035) is the `Term::KInvariants` emission's bytes, exposed
8849///   via [`Grounded::output_bytes`].
8850/// - The concrete `cert:witness` ValueTuple is derivable from
8851///   `Term::Nerve`'s 0-simplices at ψ_1 (the per-value bytes the model's
8852///   NerveResolver consumed).
8853/// - The `cert:searchTrace` is realized as
8854///   [`Grounded::derivation`]`().replay()`.
8855///
8856/// The κ-label and `cert:witness` are different witness granularities
8857/// (homotopy classification vs. concrete ValueTuple); the canonical
8858/// k-invariants branch ψ_1 → ψ_7 → ψ_8 → ψ_9 produces both, at the
8859/// ψ_9 and ψ_1 stages respectively. Ontology references:
8860/// `<https://uor.foundation/cert/InhabitanceCertificate>`,
8861/// `<https://uor.foundation/cert/witness>`,
8862/// `<https://uor.foundation/cert/searchTrace>`.
8863#[derive(Debug, Clone)]
8864pub struct Grounded<T: GroundedShape, Tag = T> {
8865    /// The validated grounding certificate this wrapper carries.
8866    validated: Validated<GroundingCertificate>,
8867    /// The compile-time-materialized bindings table.
8868    bindings: BindingsTable,
8869    /// The Witt level the grounded value was minted at.
8870    witt_level_bits: u16,
8871    /// Content-address of the originating CompileUnit.
8872    unit_address: ContentAddress,
8873    /// Phase A.1: the foundation-internal two-clock value read at witness mint time.
8874    /// Computed deterministically from (witt_level_bits, unit_address, bindings).
8875    uor_time: UorTime,
8876    /// v0.2.2 T2.6 (cleanup): BaseMetric storage — populated by the
8877    /// pipeline at mint time as a deterministic function of witt level,
8878    /// unit address, and bindings. All six fields are read-only from
8879    /// the accessors; downstream cannot mutate them.
8880    /// Grounding completion ratio σ × 10⁶ (parts per million).
8881    sigma_ppm: u32,
8882    /// Metric incompatibility d_Δ.
8883    d_delta: i64,
8884    /// Euler characteristic of the constraint nerve.
8885    euler_characteristic: i64,
8886    /// Free-site count at grounding time.
8887    residual_count: u32,
8888    /// Per-site Jacobian row (fixed capacity, zero-padded).
8889    jacobian_entries: [i64; JACOBIAN_MAX_SITES],
8890    /// Active length of jacobian_entries.
8891    jacobian_len: u16,
8892    /// Betti numbers β_0..β_{MAX_BETTI_DIMENSION-1}.
8893    betti_numbers: [u32; MAX_BETTI_DIMENSION],
8894    /// v0.2.2 T5: parametric content fingerprint of the source unit's
8895    /// full state, computed at grounding time by the consumer-supplied
8896    /// `Hasher`. Width is `ContentFingerprint::width_bytes()`, set by
8897    /// `H::OUTPUT_BYTES` at the call site. Read by `Grounded::derivation()`
8898    /// so the verify path can re-derive the source certificate.
8899    content_fingerprint: ContentFingerprint,
8900    /// Wiki ADR-028: output-value payload — the catamorphism's evaluation
8901    /// result populated by `pipeline::run_route` per ADR-029's per-variant
8902    /// fold rules. Fixed-capacity stack buffer; the active prefix runs to
8903    /// `output_len` bytes. Read via [`Grounded::output_bytes`].
8904    output_payload: [u8; crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES],
8905    /// Active length of `output_payload` (the route's evaluation output length).
8906    output_len: u16,
8907    /// Phantom type tying this `Grounded` to a specific `ConstrainedType`.
8908    _phantom: PhantomData<T>,
8909    /// Phantom domain tag (Q3). Defaults to `T` for backwards-compatible
8910    /// call sites; downstream attaches a custom tag via `tag::<NewTag>()`.
8911    _tag: PhantomData<Tag>,
8912}
8913
8914impl<T: GroundedShape, Tag> Grounded<T, Tag> {
8915    /// Returns the binding for the given query address, or `None` if not in
8916    /// the table. Resolves in O(log n) via binary search; for true `op:GS_5`
8917    /// zero-step access, downstream code uses statically-known indices.
8918    #[inline]
8919    #[must_use]
8920    pub fn get_binding(&self, address: ContentAddress) -> Option<&'static [u8]> {
8921        self.bindings
8922            .entries
8923            .binary_search_by_key(&address.as_u128(), |e| e.address.as_u128())
8924            .ok()
8925            .map(|i| self.bindings.entries[i].bytes)
8926    }
8927
8928    /// Iterate over all bindings in this grounded context.
8929    #[inline]
8930    pub fn iter_bindings(&self) -> impl Iterator<Item = &BindingEntry> + '_ {
8931        self.bindings.entries.iter()
8932    }
8933
8934    /// Returns the Witt level the grounded value was minted at.
8935    #[inline]
8936    #[must_use]
8937    pub const fn witt_level_bits(&self) -> u16 {
8938        self.witt_level_bits
8939    }
8940
8941    /// Returns the content-address of the originating CompileUnit.
8942    #[inline]
8943    #[must_use]
8944    pub const fn unit_address(&self) -> ContentAddress {
8945        self.unit_address
8946    }
8947
8948    /// Returns the validated grounding certificate this wrapper carries.
8949    #[inline]
8950    #[must_use]
8951    pub const fn certificate(&self) -> &Validated<GroundingCertificate> {
8952        &self.validated
8953    }
8954
8955    /// Phase A.4: `observable:d_delta_metric` — sealed metric incompatibility between
8956    /// ring distance and Hamming distance for this datum's neighborhood.
8957    #[inline]
8958    #[must_use]
8959    pub const fn d_delta(&self) -> DDeltaMetric {
8960        DDeltaMetric::new(self.d_delta)
8961    }
8962
8963    /// Phase A.4: `observable:sigma_metric` — sealed grounding completion ratio.
8964    #[inline]
8965    #[must_use]
8966    pub fn sigma(&self) -> SigmaValue<crate::DefaultHostTypes> {
8967        // Default-host (f64) projection; polymorphic consumers
8968        // can re-encode via DecimalTranscendental::from_u32 + Div.
8969        let value = <f64 as crate::DecimalTranscendental>::from_u32(self.sigma_ppm)
8970            / <f64 as crate::DecimalTranscendental>::from_u32(1_000_000);
8971        SigmaValue::<crate::DefaultHostTypes>::new_unchecked(value)
8972    }
8973
8974    /// Phase A.4: `observable:jacobian_metric` — sealed per-site Jacobian row.
8975    #[inline]
8976    #[must_use]
8977    pub fn jacobian(&self) -> JacobianMetric<T> {
8978        JacobianMetric::from_entries(self.jacobian_entries, self.jacobian_len)
8979    }
8980
8981    /// Phase A.4: `observable:betti_metric` — sealed Betti-number vector.
8982    #[inline]
8983    #[must_use]
8984    pub const fn betti(&self) -> BettiMetric {
8985        BettiMetric::new(self.betti_numbers)
8986    }
8987
8988    /// Phase A.4: `observable:euler_metric` — sealed Euler characteristic χ of
8989    /// the constraint nerve.
8990    #[inline]
8991    #[must_use]
8992    pub const fn euler(&self) -> EulerMetric {
8993        EulerMetric::new(self.euler_characteristic)
8994    }
8995
8996    /// Phase A.4: `observable:residual_metric` — sealed free-site count r at grounding.
8997    #[inline]
8998    #[must_use]
8999    pub const fn residual(&self) -> ResidualMetric {
9000        ResidualMetric::new(self.residual_count)
9001    }
9002
9003    /// v0.2.2 T5: returns the parametric content fingerprint of the source
9004    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
9005    /// Width is set by `H::OUTPUT_BYTES` at the call site. Used by
9006    /// `derivation()` to seed the replayed Trace's fingerprint, which
9007    /// `verify_trace` then passes through to the re-derived certificate.
9008    #[inline]
9009    #[must_use]
9010    pub const fn content_fingerprint(&self) -> ContentFingerprint {
9011        self.content_fingerprint
9012    }
9013
9014    /// v0.2.2 T5 (C2): returns the `Derivation` that produced this grounded
9015    /// value. Use the returned `Derivation` with `Derivation::replay()` and
9016    /// then `uor_foundation_verify::verify_trace` to re-derive the source
9017    /// certificate without re-running the deciders.
9018    /// The round-trip property:
9019    /// ```text
9020    /// verify_trace(&grounded.derivation().replay()).certificate()
9021    ///     == grounded.certificate()
9022    /// ```
9023    /// holds for every conforming substrate `Hasher`.
9024    #[inline]
9025    #[must_use]
9026    pub const fn derivation(&self) -> Derivation {
9027        Derivation::new(
9028            (self.jacobian_len as u32) + 1,
9029            self.witt_level_bits,
9030            self.content_fingerprint,
9031        )
9032    }
9033
9034    /// v0.2.2 Phase B (Q3): coerce this `Grounded<T, Tag>` to a different
9035    /// phantom tag. Zero-cost — the inner witness is unchanged; only the
9036    /// type-system view differs. Downstream uses this to attach a domain
9037    /// marker for use in function signatures (e.g., `Grounded<_, BlockHashTag>`
9038    /// vs `Grounded<_, PixelTag>` are distinct Rust types).
9039    /// **The foundation does not validate the tag.** The tag records what
9040    /// the developer is claiming about the witness's domain semantics; the
9041    /// foundation's contract is about ring soundness, not domain semantics.
9042    #[inline]
9043    #[must_use]
9044    pub fn tag<NewTag>(self) -> Grounded<T, NewTag> {
9045        Grounded {
9046            validated: self.validated,
9047            bindings: self.bindings,
9048            witt_level_bits: self.witt_level_bits,
9049            unit_address: self.unit_address,
9050            uor_time: self.uor_time,
9051            sigma_ppm: self.sigma_ppm,
9052            d_delta: self.d_delta,
9053            euler_characteristic: self.euler_characteristic,
9054            residual_count: self.residual_count,
9055            jacobian_entries: self.jacobian_entries,
9056            jacobian_len: self.jacobian_len,
9057            betti_numbers: self.betti_numbers,
9058            content_fingerprint: self.content_fingerprint,
9059            output_payload: self.output_payload,
9060            output_len: self.output_len,
9061            _phantom: PhantomData,
9062            _tag: PhantomData,
9063        }
9064    }
9065
9066    /// Wiki ADR-028: returns the catamorphism's evaluation output bytes — the
9067    /// active prefix of the on-stack output payload `pipeline::run_route`
9068    /// populated per ADR-029's per-variant fold rules.
9069    /// For the foundation-sanctioned identity output (`ConstrainedTypeInput`)
9070    /// the slice is empty (no transformation, identity route). For shapes
9071    /// declared via the `output_shape!` SDK macro the slice carries the
9072    /// route's evaluation result.
9073    #[inline]
9074    #[must_use]
9075    pub fn output_bytes(&self) -> &[u8] {
9076        let len = self.output_len as usize;
9077        &self.output_payload[..len]
9078    }
9079
9080    /// Phase A.1: the foundation-internal two-clock value read at witness mint time.
9081    /// Maps `rewrite_steps` to `derivation:stepCount` and `landauer_nats` to
9082    /// `observable:LandauerCost`. The value is content-deterministic: two `Grounded`
9083    /// witnesses minted from the same inputs share the same `UorTime`.
9084    /// Compose with a `Calibration` via [`UorTime::min_wall_clock`] to
9085    /// bound the provable minimum wall-clock duration the computation required.
9086    #[inline]
9087    #[must_use]
9088    pub const fn uor_time(&self) -> UorTime {
9089        self.uor_time
9090    }
9091
9092    /// Phase A.2: the sealed triadic coordinate `(stratum, spectrum, address)` at the
9093    /// witness's Witt level, projected from the content-addressed unit.
9094    /// `stratum` is the v₂ valuation of the lower unit-address half; `spectrum`
9095    /// is the lower 64 bits of the unit address; `address` is the upper 64 bits.
9096    /// The projection is deterministic and content-addressed, so replay reproduces the
9097    /// same `Triad` bit-for-bit.
9098    #[inline]
9099    #[must_use]
9100    pub const fn triad(&self) -> Triad<T> {
9101        let addr = self.unit_address.as_u128();
9102        let addr_lo = addr as u64;
9103        let addr_hi = (addr >> 64) as u64;
9104        let stratum = if addr_lo == 0 {
9105            0u64
9106        } else {
9107            addr_lo.trailing_zeros() as u64
9108        };
9109        Triad::new(stratum, addr_lo, addr_hi)
9110    }
9111
9112    /// Crate-internal constructor used by the pipeline at mint time.
9113    /// Not callable from outside `uor-foundation`. The tag defaults to `T`
9114    /// (the unparameterized form); downstream attaches a custom tag via `tag()`.
9115    /// v0.2.2 T2.6 (cleanup): BaseMetric fields are computed here from
9116    /// the input witt level, bindings, and unit address. Two `Grounded`
9117    /// values built from the same inputs return identical metrics; two
9118    /// built from different inputs differ in at least three fields.
9119    #[inline]
9120    #[allow(dead_code)]
9121    pub(crate) const fn new_internal(
9122        validated: Validated<GroundingCertificate>,
9123        bindings: BindingsTable,
9124        witt_level_bits: u16,
9125        unit_address: ContentAddress,
9126        content_fingerprint: ContentFingerprint,
9127    ) -> Self {
9128        let bound_count = bindings.entries.len() as u32;
9129        let declared_sites = if witt_level_bits == 0 {
9130            1u32
9131        } else {
9132            witt_level_bits as u32
9133        };
9134        // sigma = bound / declared, in parts per million.
9135        let sigma_ppm = if bound_count >= declared_sites {
9136            1_000_000u32
9137        } else {
9138            // Integer division, rounded down, cannot exceed 1_000_000.
9139            let num = (bound_count as u64) * 1_000_000u64;
9140            (num / (declared_sites as u64)) as u32
9141        };
9142        // residual_count = declared - bound (saturating).
9143        let residual_count = declared_sites.saturating_sub(bound_count);
9144        // d_delta = witt_bits - bound_count (signed).
9145        let d_delta = (witt_level_bits as i64) - (bound_count as i64);
9146        // Betti numbers: β_0 = 1 (connected); β_k = bit k of witt_level_bits.
9147        let mut betti = [0u32; MAX_BETTI_DIMENSION];
9148        betti[0] = 1;
9149        let mut k = 1usize;
9150        while k < MAX_BETTI_DIMENSION {
9151            betti[k] = ((witt_level_bits as u32) >> (k - 1)) & 1;
9152            k += 1;
9153        }
9154        // Euler characteristic: alternating sum of Betti numbers.
9155        let mut euler: i64 = 0;
9156        let mut k = 0usize;
9157        while k < MAX_BETTI_DIMENSION {
9158            if k & 1 == 0 {
9159                euler += betti[k] as i64;
9160            } else {
9161                euler -= betti[k] as i64;
9162            }
9163            k += 1;
9164        }
9165        // Jacobian row: entry i = (unit_address.as_u128() as i64 XOR (i as i64)) mod witt+1.
9166        let mut jac = [0i64; JACOBIAN_MAX_SITES];
9167        let modulus = (witt_level_bits as i64) + 1;
9168        let ua_lo = unit_address.as_u128() as i64;
9169        let mut i = 0usize;
9170        let jac_len = if (witt_level_bits as usize) < JACOBIAN_MAX_SITES {
9171            witt_level_bits as usize
9172        } else {
9173            JACOBIAN_MAX_SITES
9174        };
9175        while i < jac_len {
9176            let raw = ua_lo ^ (i as i64);
9177            // Rust's % is remainder; ensure non-negative.
9178            let m = if modulus == 0 { 1 } else { modulus };
9179            jac[i] = ((raw % m) + m) % m;
9180            i += 1;
9181        }
9182        // Phase A.1: uor_time is content-deterministic. rewrite_steps counts
9183        // the reduction work proxied by (witt bits + bound count + active jac len);
9184        // Landauer nats = rewrite_steps × ln 2 (Landauer-temperature cost of
9185        // traversing that many orthogonal states). Two Grounded values minted from
9186        // the same inputs share the same UorTime.
9187        let steps = (witt_level_bits as u64) + (bound_count as u64) + (jac_len as u64);
9188        let landauer = LandauerBudget::new((steps as f64) * core::f64::consts::LN_2);
9189        let uor_time = UorTime::new(landauer, steps);
9190        Self {
9191            validated,
9192            bindings,
9193            witt_level_bits,
9194            unit_address,
9195            uor_time,
9196            sigma_ppm,
9197            d_delta,
9198            euler_characteristic: euler,
9199            residual_count,
9200            jacobian_entries: jac,
9201            jacobian_len: jac_len as u16,
9202            betti_numbers: betti,
9203            content_fingerprint,
9204            output_payload: [0u8; crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES],
9205            output_len: 0,
9206            _phantom: PhantomData,
9207            _tag: PhantomData,
9208        }
9209    }
9210
9211    /// Wiki ADR-028: crate-internal setter for the output-value payload.
9212    /// Called by `pipeline::run_route` after the catamorphism evaluates the
9213    /// Term tree per ADR-029. The bytes are copied into the on-stack
9214    /// buffer; bytes beyond `len` are zero-padded. Returns self for chaining.
9215    /// Panics if `bytes.len() > crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES`.
9216    #[inline]
9217    #[must_use]
9218    pub(crate) fn with_output_bytes(mut self, bytes: &[u8]) -> Self {
9219        let len = bytes.len();
9220        debug_assert!(len <= crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES);
9221        let copy_len = if len > crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES {
9222            crate::pipeline::ROUTE_OUTPUT_BUFFER_BYTES
9223        } else {
9224            len
9225        };
9226        let mut i = 0;
9227        while i < copy_len {
9228            self.output_payload[i] = bytes[i];
9229            i += 1;
9230        }
9231        self.output_len = copy_len as u16;
9232        self
9233    }
9234
9235    /// v0.2.2 T6.17: attach a downstream-validated `BindingsTable` to this
9236    /// grounded value. The original `Grounded` was minted by the foundation
9237    /// pipeline with a substrate-computed certificate; this builder lets
9238    /// downstream attach its own binding table without re-grounding.
9239    /// The `bindings` parameter must satisfy the sortedness invariant. Use
9240    /// [`BindingsTable::try_new`] to construct a validated table from a
9241    /// pre-sorted slice.
9242    /// **Trust boundary:** the certificate witnesses the unit's grounding,
9243    /// not the bindings' contents. A downstream consumer that uses the
9244    /// certificate as a trust root for the bindings is wrong.
9245    #[inline]
9246    #[must_use]
9247    pub fn with_bindings(self, bindings: BindingsTable) -> Self {
9248        Self { bindings, ..self }
9249    }
9250
9251    /// Wiki ADR-042: borrow `self` as an
9252    /// [`crate::pipeline::InhabitanceCertificateView`] over the canonical
9253    /// k-invariants branch's verdict envelope.
9254    /// Universal — available for any `Grounded<T, Tag>`; applications whose
9255    /// admission relations are not inhabitance questions simply don't
9256    /// call the typed accessors. The view is zero-cost
9257    /// (`#[repr(transparent)]` over `&'a Grounded<T, Tag>`).
9258    #[inline]
9259    #[must_use]
9260    pub fn as_inhabitance_certificate(
9261        &self,
9262    ) -> crate::pipeline::InhabitanceCertificateView<'_, T, Tag> {
9263        crate::pipeline::InhabitanceCertificateView(self)
9264    }
9265}
9266
9267/// v0.2.2 W8: triadic coordinate of a Datum at level `L`. Bundles the
9268/// (stratum, spectrum, address) projection in one structurally-enforced
9269/// type. No public constructor — `Triad<L>` is built only by foundation code
9270/// at grounding time. Field access goes through the named accessors.
9271#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9272pub struct Triad<L> {
9273    /// The stratum coordinate (two-adic valuation).
9274    stratum: u64,
9275    /// The spectrum coordinate (Walsh-Hadamard image).
9276    spectrum: u64,
9277    /// The address coordinate (Braille-glyph address).
9278    address: u64,
9279    /// Phantom marker for the Witt level.
9280    _level: PhantomData<L>,
9281}
9282
9283impl<L> Triad<L> {
9284    /// Returns the stratum component (`query:TwoAdicValuation` coordinate).
9285    #[inline]
9286    #[must_use]
9287    pub const fn stratum(&self) -> u64 {
9288        self.stratum
9289    }
9290
9291    /// Returns the spectrum component (`query:WalshHadamardImage` coordinate).
9292    #[inline]
9293    #[must_use]
9294    pub const fn spectrum(&self) -> u64 {
9295        self.spectrum
9296    }
9297
9298    /// Returns the address component (`query:Address` coordinate).
9299    #[inline]
9300    #[must_use]
9301    pub const fn address(&self) -> u64 {
9302        self.address
9303    }
9304
9305    /// Crate-internal constructor. Reachable only from grounding-time minting.
9306    #[inline]
9307    #[must_use]
9308    #[allow(dead_code)]
9309    pub(crate) const fn new(stratum: u64, spectrum: u64, address: u64) -> Self {
9310        Self {
9311            stratum,
9312            spectrum,
9313            address,
9314            _level: PhantomData,
9315        }
9316    }
9317}
9318
9319/// The Rust-surface rendering of `reduction:PipelineFailureReason` and the
9320/// v0.2.1 cross-namespace failure variants. Variant set and field shapes are
9321/// generated parametrically by walking `reduction:FailureField` individuals;
9322/// adding a new field requires only an ontology edit.
9323///
9324/// # Wiki ADR-039 — Inhabitance verdict realization mapping
9325///
9326/// An `Err(PipelineFailure)` whose structural cause is "the constraint
9327/// nerve has empty Kan completion" realizes a `cert:InhabitanceImpossibilityCertificate`
9328/// envelope, carrying `proof:InhabitanceImpossibilityWitness` as the
9329/// proof payload with `proof:contradictionProof` as the canonical-form
9330/// encoding of the failure trace. The verdict mapping is the dual of
9331/// the `Grounded<Output>` → `cert:InhabitanceCertificate` mapping; the
9332/// two together realize the ontology's three-primitive inhabitance
9333/// verdict structure (success / impossibility-witnessed / unknown).
9334/// Ontology references:
9335/// `<https://uor.foundation/cert/InhabitanceImpossibilityCertificate>`,
9336/// `<https://uor.foundation/proof/InhabitanceImpossibilityWitness>`,
9337/// `<https://uor.foundation/proof/contradictionProof>`.
9338#[derive(Debug, Clone, PartialEq)]
9339#[non_exhaustive]
9340pub enum PipelineFailure {
9341    /// `DispatchMiss` failure variant.
9342    DispatchMiss {
9343        /// query_iri field.
9344        query_iri: &'static str,
9345        /// table_iri field.
9346        table_iri: &'static str,
9347    },
9348    /// `GroundingFailure` failure variant.
9349    GroundingFailure {
9350        /// reason_iri field.
9351        reason_iri: &'static str,
9352    },
9353    /// `ConvergenceStall` failure variant.
9354    ConvergenceStall {
9355        /// stage_iri field.
9356        stage_iri: &'static str,
9357        /// angle_milliradians field.
9358        angle_milliradians: i64,
9359    },
9360    /// `ContradictionDetected` failure variant.
9361    ContradictionDetected {
9362        /// at_step field.
9363        at_step: usize,
9364        /// trace_iri field.
9365        trace_iri: &'static str,
9366    },
9367    /// `CoherenceViolation` failure variant.
9368    CoherenceViolation {
9369        /// site_position field.
9370        site_position: usize,
9371        /// constraint_iri field.
9372        constraint_iri: &'static str,
9373    },
9374    /// `ShapeMismatch` failure variant.
9375    ShapeMismatch {
9376        /// expected field.
9377        expected: &'static str,
9378        /// got field.
9379        got: &'static str,
9380    },
9381    /// `LiftObstructionFailure` failure variant.
9382    LiftObstructionFailure {
9383        /// site_position field.
9384        site_position: usize,
9385        /// obstruction_class_iri field.
9386        obstruction_class_iri: &'static str,
9387    },
9388    /// `ShapeViolation` failure variant.
9389    ShapeViolation {
9390        /// report field.
9391        report: ShapeViolation,
9392    },
9393}
9394
9395impl core::fmt::Display for PipelineFailure {
9396    fn fmt(&self, ff: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9397        match self {
9398            Self::DispatchMiss {
9399                query_iri,
9400                table_iri,
9401            } => write!(
9402                ff,
9403                "DispatchMiss(query_iri={:?}, table_iri={:?})",
9404                query_iri, table_iri
9405            ),
9406            Self::GroundingFailure { reason_iri } => {
9407                write!(ff, "GroundingFailure(reason_iri={:?})", reason_iri)
9408            }
9409            Self::ConvergenceStall {
9410                stage_iri,
9411                angle_milliradians,
9412            } => write!(
9413                ff,
9414                "ConvergenceStall(stage_iri={:?}, angle_milliradians={:?})",
9415                stage_iri, angle_milliradians
9416            ),
9417            Self::ContradictionDetected { at_step, trace_iri } => write!(
9418                ff,
9419                "ContradictionDetected(at_step={:?}, trace_iri={:?})",
9420                at_step, trace_iri
9421            ),
9422            Self::CoherenceViolation {
9423                site_position,
9424                constraint_iri,
9425            } => write!(
9426                ff,
9427                "CoherenceViolation(site_position={:?}, constraint_iri={:?})",
9428                site_position, constraint_iri
9429            ),
9430            Self::ShapeMismatch { expected, got } => {
9431                write!(ff, "ShapeMismatch(expected={:?}, got={:?})", expected, got)
9432            }
9433            Self::LiftObstructionFailure {
9434                site_position,
9435                obstruction_class_iri,
9436            } => write!(
9437                ff,
9438                "LiftObstructionFailure(site_position={:?}, obstruction_class_iri={:?})",
9439                site_position, obstruction_class_iri
9440            ),
9441            Self::ShapeViolation { report } => write!(ff, "ShapeViolation({:?})", report),
9442        }
9443    }
9444}
9445
9446impl core::error::Error for PipelineFailure {}
9447
9448/// Sealed marker for impossibility witnesses returned by the resolver
9449/// free-function path. Every failure return value of every
9450/// `resolver::<name>::certify(...)` call is a member of this set.
9451pub trait ImpossibilityWitnessKind: impossibility_witness_kind_sealed::Sealed {}
9452
9453mod impossibility_witness_kind_sealed {
9454    /// Private supertrait.
9455    pub trait Sealed {}
9456    impl Sealed for super::GenericImpossibilityWitness {}
9457    impl Sealed for super::InhabitanceImpossibilityWitness {}
9458}
9459
9460impl ImpossibilityWitnessKind for GenericImpossibilityWitness {}
9461impl ImpossibilityWitnessKind for InhabitanceImpossibilityWitness {}
9462
9463/// v0.2.2 W12: resolver free functions. Replaces the v0.2.1 unit-struct
9464/// façades with module-per-resolver free functions returning the W11
9465/// `Certified<C>` parametric carrier.
9466pub mod resolver {
9467    use super::{
9468        BornRuleVerification,
9469        Certified,
9470        CompileUnit,
9471        CompletenessCertificate,
9472        GenericImpossibilityWitness,
9473        GeodesicCertificate,
9474        GroundingCertificate,
9475        InhabitanceCertificate,
9476        InhabitanceImpossibilityWitness,
9477        InvolutionCertificate,
9478        IsometryCertificate,
9479        LiftChainCertificate,
9480        MeasurementCertificate,
9481        // Phase X.1: per-resolver cert discrimination.
9482        TransformCertificate,
9483        Validated,
9484        WittLevel,
9485    };
9486
9487    /// v0.2.2 W12: certify tower-completeness for a constrained type.
9488    ///
9489    /// Replaces `TowerCompletenessResolver::new().certify(input)` from v0.2.1.
9490    /// Delegates to `crate::pipeline::run_tower_completeness` and wraps the
9491    /// returned `LiftChainCertificate` in the W11 `Certified<_>` carrier.
9492    ///
9493    /// # Errors
9494    ///
9495    /// Returns `GenericImpossibilityWitness` when no certificate can be issued.
9496    pub mod tower_completeness {
9497        use super::*;
9498        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9499        ///
9500        /// # Errors
9501        ///
9502        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9503        pub fn certify<T, P, H>(
9504            input: &Validated<T, P>,
9505        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9506        where
9507            T: crate::pipeline::ConstrainedTypeShape,
9508            P: crate::enforcement::ValidationPhase,
9509            H: crate::enforcement::Hasher,
9510        {
9511            certify_at::<T, P, H>(input, WittLevel::W32)
9512        }
9513
9514        /// Certify at an explicit Witt level.
9515        ///
9516        /// # Errors
9517        ///
9518        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9519        pub fn certify_at<T, P, H>(
9520            input: &Validated<T, P>,
9521            level: WittLevel,
9522        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9523        where
9524            T: crate::pipeline::ConstrainedTypeShape,
9525            P: crate::enforcement::ValidationPhase,
9526            H: crate::enforcement::Hasher,
9527        {
9528            crate::pipeline::run_tower_completeness::<T, H>(input.inner(), level)
9529                .map(|v| Certified::new(*v.inner()))
9530                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9531        }
9532    }
9533
9534    /// v0.2.2 closure: certify incremental completeness for a constrained type.
9535    pub mod incremental_completeness {
9536        use super::*;
9537        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9538        ///
9539        /// # Errors
9540        ///
9541        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9542        pub fn certify<T, P, H>(
9543            input: &Validated<T, P>,
9544        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9545        where
9546            T: crate::pipeline::ConstrainedTypeShape,
9547            P: crate::enforcement::ValidationPhase,
9548            H: crate::enforcement::Hasher,
9549        {
9550            certify_at::<T, P, H>(input, WittLevel::W32)
9551        }
9552
9553        /// Certify at an explicit Witt level.
9554        ///
9555        /// # Errors
9556        ///
9557        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9558        pub fn certify_at<T, P, H>(
9559            input: &Validated<T, P>,
9560            level: WittLevel,
9561        ) -> Result<Certified<LiftChainCertificate>, Certified<GenericImpossibilityWitness>>
9562        where
9563            T: crate::pipeline::ConstrainedTypeShape,
9564            P: crate::enforcement::ValidationPhase,
9565            H: crate::enforcement::Hasher,
9566        {
9567            crate::pipeline::run_incremental_completeness::<T, H>(input.inner(), level)
9568                .map(|v| Certified::new(*v.inner()))
9569                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9570        }
9571    }
9572
9573    /// v0.2.2 closure: certify grounding-aware reduction for a CompileUnit.
9574    pub mod grounding_aware {
9575        use super::*;
9576        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9577        ///
9578        /// # Errors
9579        ///
9580        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9581        pub fn certify<P, H>(
9582            input: &Validated<CompileUnit, P>,
9583        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9584        where
9585            P: crate::enforcement::ValidationPhase,
9586            H: crate::enforcement::Hasher,
9587        {
9588            certify_at::<P, H>(input, WittLevel::W32)
9589        }
9590
9591        /// Certify at an explicit Witt level.
9592        ///
9593        /// # Errors
9594        ///
9595        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9596        pub fn certify_at<P, H>(
9597            input: &Validated<CompileUnit, P>,
9598            level: WittLevel,
9599        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9600        where
9601            P: crate::enforcement::ValidationPhase,
9602            H: crate::enforcement::Hasher,
9603        {
9604            crate::pipeline::run_grounding_aware::<H>(input.inner(), level)
9605                .map(|v| Certified::new(*v.inner()))
9606                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9607        }
9608    }
9609
9610    /// v0.2.2 closure: certify inhabitance for a constrained type.
9611    pub mod inhabitance {
9612        use super::*;
9613        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9614        ///
9615        /// # Errors
9616        ///
9617        /// Returns `Certified<InhabitanceImpossibilityWitness>` on failure.
9618        pub fn certify<T, P, H>(
9619            input: &Validated<T, P>,
9620        ) -> Result<Certified<InhabitanceCertificate>, Certified<InhabitanceImpossibilityWitness>>
9621        where
9622            T: crate::pipeline::ConstrainedTypeShape,
9623            P: crate::enforcement::ValidationPhase,
9624            H: crate::enforcement::Hasher,
9625        {
9626            certify_at::<T, P, H>(input, WittLevel::W32)
9627        }
9628
9629        /// Certify at an explicit Witt level.
9630        ///
9631        /// # Errors
9632        ///
9633        /// Returns `Certified<InhabitanceImpossibilityWitness>` on failure.
9634        pub fn certify_at<T, P, H>(
9635            input: &Validated<T, P>,
9636            level: WittLevel,
9637        ) -> Result<Certified<InhabitanceCertificate>, Certified<InhabitanceImpossibilityWitness>>
9638        where
9639            T: crate::pipeline::ConstrainedTypeShape,
9640            P: crate::enforcement::ValidationPhase,
9641            H: crate::enforcement::Hasher,
9642        {
9643            crate::pipeline::run_inhabitance::<T, H>(input.inner(), level)
9644                .map(|v: Validated<InhabitanceCertificate>| Certified::new(*v.inner()))
9645                .map_err(|_| Certified::new(InhabitanceImpossibilityWitness::default()))
9646        }
9647    }
9648
9649    /// v0.2.2 Phase C.4: multiplication resolver — picks the cost-optimal
9650    /// Toom-Cook splitting factor R for a `Datum<L>` × `Datum<L>`
9651    /// multiplication at a given call-site context. The cost function is
9652    /// closed-form and grounded in `op:OA_5`:
9653    ///
9654    /// ```text
9655    /// sub_mul_count(N, R) = (2R - 1)  for R > 1
9656    ///                     = 1         for R = 1 (schoolbook)
9657    /// landauer_cost(N, R) = sub_mul_count(N, R) · (N/R)² · 64 · ln 2  nats
9658    /// ```
9659    pub mod multiplication {
9660        use super::super::{MulContext, MultiplicationCertificate};
9661        use super::*;
9662
9663        /// v0.2.2 T6.7: parameterized over `H: Hasher`. Pick the cost-optimal
9664        /// splitting factor R for a multiplication at the given call-site
9665        /// context and return a `Certified<MultiplicationCertificate>`
9666        /// recording the choice. The certificate carries a substrate-computed
9667        /// content fingerprint.
9668        ///
9669        /// # Errors
9670        ///
9671        /// Returns `GenericImpossibilityWitness` if the call-site context is
9672        /// inadmissible (`stack_budget_bytes == 0`). The resolver is otherwise
9673        /// total over admissible inputs.
9674        pub fn certify<H: crate::enforcement::Hasher>(
9675            context: &MulContext,
9676        ) -> Result<Certified<MultiplicationCertificate>, GenericImpossibilityWitness> {
9677            if context.stack_budget_bytes == 0 {
9678                return Err(GenericImpossibilityWitness::default());
9679            }
9680            // Closed-form cost search: R = 1 (schoolbook) vs R = 2 (Karatsuba).
9681            let limb_count = context.limb_count.max(1);
9682            let karatsuba_stack_need = limb_count * 8 * 6;
9683            let choose_karatsuba = !context.const_eval
9684                && (context.stack_budget_bytes as usize) >= karatsuba_stack_need;
9685            // v0.2.2 T6.7: compute substrate fingerprint over the MulContext.
9686            let mut hasher = H::initial();
9687            hasher = hasher.fold_bytes(&context.stack_budget_bytes.to_be_bytes());
9688            hasher = hasher.fold_byte(if context.const_eval { 1 } else { 0 });
9689            hasher = hasher.fold_bytes(&(limb_count as u64).to_be_bytes());
9690            hasher = hasher.fold_byte(crate::enforcement::certificate_kind_discriminant(
9691                crate::enforcement::CertificateKind::Multiplication,
9692            ));
9693            let buffer = hasher.finalize();
9694            let fp =
9695                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9696            let cert = if choose_karatsuba {
9697                MultiplicationCertificate::with_evidence(
9698                    2,
9699                    3,
9700                    karatsuba_landauer_cost(limb_count),
9701                    fp,
9702                )
9703            } else {
9704                MultiplicationCertificate::with_evidence(
9705                    1,
9706                    1,
9707                    schoolbook_landauer_cost(limb_count),
9708                    fp,
9709                )
9710            };
9711            Ok(Certified::new(cert))
9712        }
9713
9714        // Local default-host alias for the Landauer cost helpers below.
9715        type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
9716
9717        /// Schoolbook Landauer cost in nats for an N-limb multiplication:
9718        /// `N² · 64 · ln 2`. Returns the IEEE-754 bit pattern;
9719        /// see `MultiplicationEvidence::landauer_cost_nats_bits`.
9720        fn schoolbook_landauer_cost(limb_count: usize) -> u64 {
9721            let n = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(limb_count as u32);
9722            let sixty_four = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(64);
9723            let ln_2 =
9724                <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
9725            (n * n * sixty_four * ln_2).to_bits()
9726        }
9727
9728        /// Karatsuba Landauer cost: `3 · (N/2)² · 64 · ln 2`.
9729        /// Returns the IEEE-754 bit pattern.
9730        fn karatsuba_landauer_cost(limb_count: usize) -> u64 {
9731            let n = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(limb_count as u32);
9732            let two = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(2);
9733            let three = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(3);
9734            let sixty_four = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(64);
9735            let ln_2 =
9736                <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
9737            let n_half = n / two;
9738            (three * n_half * n_half * sixty_four * ln_2).to_bits()
9739        }
9740    }
9741
9742    /// v0.2.2 Phase C: `pub(crate)` trait parameterizing the 15 Phase D resolver kernels.
9743    /// Each kernel marker supplies a `CertificateKind` discriminant and its
9744    /// ontology-declared certificate type via `type Cert`. The shared
9745    /// `certify_at` bodies (see `emit_phase_d_ct_body` / `emit_phase_d_cu_body`)
9746    /// mint `Certified<Kernel::Cert>` directly — so each resolver's cert class
9747    /// matches its `resolver:CertifyMapping` in the ontology.
9748    pub(crate) trait ResolverKernel {
9749        const KIND: crate::enforcement::CertificateKind;
9750        /// Phase X.1: the ontology-declared certificate class produced by
9751        /// this resolver (per `resolver:CertifyMapping`).
9752        type Cert: crate::enforcement::Certificate;
9753    }
9754
9755    /// Phase D (target §4.2): `resolver:TwoSatDecider` — certify that `predicate:Is2SatShape` inputs are 2-SAT-decidable via the Aspvall-Plass-Tarjan strongly-connected-components decider.
9756    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9757    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9758    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9759    /// failure — the witness itself is certified so downstream can persist it
9760    /// alongside success certs in a uniform `Certified<_>` channel.
9761    /// Phase X.1: the produced cert class is the ontology-declared class for
9762    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9763    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9764    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9765    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9766    /// kernels so each resolver's class discrimination is load-bearing.
9767    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9768    /// kernel's composition spec) whose output is folded into the canonical
9769    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9770    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9771    /// content-addressed per its ontology class.
9772    pub mod two_sat_decider {
9773        use super::*;
9774
9775        #[doc(hidden)]
9776        pub struct Kernel;
9777        impl super::ResolverKernel for Kernel {
9778            type Cert = crate::enforcement::GroundingCertificate;
9779            const KIND: crate::enforcement::CertificateKind =
9780                crate::enforcement::CertificateKind::TwoSat;
9781        }
9782
9783        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9784        ///
9785        /// # Errors
9786        ///
9787        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9788        pub fn certify<
9789            T: crate::pipeline::ConstrainedTypeShape,
9790            P: crate::enforcement::ValidationPhase,
9791            H: crate::enforcement::Hasher,
9792        >(
9793            input: &Validated<T, P>,
9794        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9795        {
9796            certify_at::<T, P, H>(input, WittLevel::W32)
9797        }
9798
9799        /// Phase D (target §4.2): certify at an explicit Witt level.
9800        ///
9801        /// # Errors
9802        ///
9803        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9804        pub fn certify_at<
9805            T: crate::pipeline::ConstrainedTypeShape,
9806            P: crate::enforcement::ValidationPhase,
9807            H: crate::enforcement::Hasher,
9808        >(
9809            input: &Validated<T, P>,
9810            level: WittLevel,
9811        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9812        {
9813            let _ = input.inner();
9814            let witt_bits = level.witt_length() as u16;
9815            let (tr_bits, tr_constraints, tr_sat) =
9816                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9817                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9818            if tr_sat == 0 {
9819                return Err(Certified::new(GenericImpossibilityWitness::default()));
9820            }
9821            let mut hasher = H::initial();
9822            hasher = crate::enforcement::fold_terminal_reduction(
9823                hasher,
9824                tr_bits,
9825                tr_constraints,
9826                tr_sat,
9827            );
9828            hasher = crate::enforcement::fold_unit_digest(
9829                hasher,
9830                witt_bits,
9831                witt_bits as u64,
9832                T::IRI,
9833                T::SITE_COUNT,
9834                T::CONSTRAINTS,
9835                <Kernel as super::ResolverKernel>::KIND,
9836            );
9837            let buffer = hasher.finalize();
9838            let fp =
9839                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9840            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
9841            Ok(Certified::new(cert))
9842        }
9843    }
9844
9845    /// Phase D (target §4.2): `resolver:HornSatDecider` — certify that `predicate:IsHornShape` inputs are Horn-SAT-decidable via unit propagation (O(n+m)).
9846    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9847    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9848    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9849    /// failure — the witness itself is certified so downstream can persist it
9850    /// alongside success certs in a uniform `Certified<_>` channel.
9851    /// Phase X.1: the produced cert class is the ontology-declared class for
9852    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9853    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9854    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9855    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9856    /// kernels so each resolver's class discrimination is load-bearing.
9857    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9858    /// kernel's composition spec) whose output is folded into the canonical
9859    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9860    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9861    /// content-addressed per its ontology class.
9862    pub mod horn_sat_decider {
9863        use super::*;
9864
9865        #[doc(hidden)]
9866        pub struct Kernel;
9867        impl super::ResolverKernel for Kernel {
9868            type Cert = crate::enforcement::GroundingCertificate;
9869            const KIND: crate::enforcement::CertificateKind =
9870                crate::enforcement::CertificateKind::HornSat;
9871        }
9872
9873        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9874        ///
9875        /// # Errors
9876        ///
9877        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9878        pub fn certify<
9879            T: crate::pipeline::ConstrainedTypeShape,
9880            P: crate::enforcement::ValidationPhase,
9881            H: crate::enforcement::Hasher,
9882        >(
9883            input: &Validated<T, P>,
9884        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9885        {
9886            certify_at::<T, P, H>(input, WittLevel::W32)
9887        }
9888
9889        /// Phase D (target §4.2): certify at an explicit Witt level.
9890        ///
9891        /// # Errors
9892        ///
9893        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9894        pub fn certify_at<
9895            T: crate::pipeline::ConstrainedTypeShape,
9896            P: crate::enforcement::ValidationPhase,
9897            H: crate::enforcement::Hasher,
9898        >(
9899            input: &Validated<T, P>,
9900            level: WittLevel,
9901        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9902        {
9903            let _ = input.inner();
9904            let witt_bits = level.witt_length() as u16;
9905            let (tr_bits, tr_constraints, tr_sat) =
9906                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9907                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9908            if tr_sat == 0 {
9909                return Err(Certified::new(GenericImpossibilityWitness::default()));
9910            }
9911            let mut hasher = H::initial();
9912            hasher = crate::enforcement::fold_terminal_reduction(
9913                hasher,
9914                tr_bits,
9915                tr_constraints,
9916                tr_sat,
9917            );
9918            hasher = crate::enforcement::fold_unit_digest(
9919                hasher,
9920                witt_bits,
9921                witt_bits as u64,
9922                T::IRI,
9923                T::SITE_COUNT,
9924                T::CONSTRAINTS,
9925                <Kernel as super::ResolverKernel>::KIND,
9926            );
9927            let buffer = hasher.finalize();
9928            let fp =
9929                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9930            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
9931            Ok(Certified::new(cert))
9932        }
9933    }
9934
9935    /// Phase D (target §4.2): `resolver:ResidualVerdictResolver` — certify `predicate:IsResidualFragment` inputs; returns `GenericImpossibilityWitness` when the residual fragment has no polynomial decider available (the canonical impossibility path).
9936    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9937    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9938    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9939    /// failure — the witness itself is certified so downstream can persist it
9940    /// alongside success certs in a uniform `Certified<_>` channel.
9941    /// Phase X.1: the produced cert class is the ontology-declared class for
9942    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9943    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9944    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9945    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9946    /// kernels so each resolver's class discrimination is load-bearing.
9947    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9948    /// kernel's composition spec) whose output is folded into the canonical
9949    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9950    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9951    /// content-addressed per its ontology class.
9952    pub mod residual_verdict {
9953        use super::*;
9954
9955        #[doc(hidden)]
9956        pub struct Kernel;
9957        impl super::ResolverKernel for Kernel {
9958            type Cert = crate::enforcement::GroundingCertificate;
9959            const KIND: crate::enforcement::CertificateKind =
9960                crate::enforcement::CertificateKind::ResidualVerdict;
9961        }
9962
9963        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9964        ///
9965        /// # Errors
9966        ///
9967        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9968        pub fn certify<
9969            T: crate::pipeline::ConstrainedTypeShape,
9970            P: crate::enforcement::ValidationPhase,
9971            H: crate::enforcement::Hasher,
9972        >(
9973            input: &Validated<T, P>,
9974        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9975        {
9976            certify_at::<T, P, H>(input, WittLevel::W32)
9977        }
9978
9979        /// Phase D (target §4.2): certify at an explicit Witt level.
9980        ///
9981        /// # Errors
9982        ///
9983        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9984        pub fn certify_at<
9985            T: crate::pipeline::ConstrainedTypeShape,
9986            P: crate::enforcement::ValidationPhase,
9987            H: crate::enforcement::Hasher,
9988        >(
9989            input: &Validated<T, P>,
9990            level: WittLevel,
9991        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
9992        {
9993            let _ = input.inner();
9994            let witt_bits = level.witt_length() as u16;
9995            let (tr_bits, tr_constraints, tr_sat) =
9996                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9997                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9998            if tr_sat == 0 {
9999                return Err(Certified::new(GenericImpossibilityWitness::default()));
10000            }
10001            let mut hasher = H::initial();
10002            hasher = crate::enforcement::fold_terminal_reduction(
10003                hasher,
10004                tr_bits,
10005                tr_constraints,
10006                tr_sat,
10007            );
10008            hasher = crate::enforcement::fold_unit_digest(
10009                hasher,
10010                witt_bits,
10011                witt_bits as u64,
10012                T::IRI,
10013                T::SITE_COUNT,
10014                T::CONSTRAINTS,
10015                <Kernel as super::ResolverKernel>::KIND,
10016            );
10017            let buffer = hasher.finalize();
10018            let fp =
10019                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10020            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10021            Ok(Certified::new(cert))
10022        }
10023    }
10024
10025    /// Phase D (target §4.2): `resolver:CanonicalFormResolver` — compute the canonical form of a `ConstrainedType` by running the reduction stages and emitting a `Certified<TransformCertificate>` whose fingerprint uniquely identifies the canonicalized input.
10026    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10027    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10028    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10029    /// failure — the witness itself is certified so downstream can persist it
10030    /// alongside success certs in a uniform `Certified<_>` channel.
10031    /// Phase X.1: the produced cert class is the ontology-declared class for
10032    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10033    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10034    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10035    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10036    /// kernels so each resolver's class discrimination is load-bearing.
10037    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10038    /// kernel's composition spec) whose output is folded into the canonical
10039    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10040    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10041    /// content-addressed per its ontology class.
10042    pub mod canonical_form {
10043        use super::*;
10044
10045        #[doc(hidden)]
10046        pub struct Kernel;
10047        impl super::ResolverKernel for Kernel {
10048            type Cert = crate::enforcement::TransformCertificate;
10049            const KIND: crate::enforcement::CertificateKind =
10050                crate::enforcement::CertificateKind::CanonicalForm;
10051        }
10052
10053        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10054        ///
10055        /// # Errors
10056        ///
10057        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10058        pub fn certify<
10059            T: crate::pipeline::ConstrainedTypeShape,
10060            P: crate::enforcement::ValidationPhase,
10061            H: crate::enforcement::Hasher,
10062        >(
10063            input: &Validated<T, P>,
10064        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10065        {
10066            certify_at::<T, P, H>(input, WittLevel::W32)
10067        }
10068
10069        /// Phase D (target §4.2): certify at an explicit Witt level.
10070        ///
10071        /// # Errors
10072        ///
10073        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10074        pub fn certify_at<
10075            T: crate::pipeline::ConstrainedTypeShape,
10076            P: crate::enforcement::ValidationPhase,
10077            H: crate::enforcement::Hasher,
10078        >(
10079            input: &Validated<T, P>,
10080            level: WittLevel,
10081        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10082        {
10083            let _ = input.inner();
10084            let witt_bits = level.witt_length() as u16;
10085            let (tr_bits, tr_constraints, tr_sat) =
10086                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10087                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10088            if tr_sat == 0 {
10089                return Err(Certified::new(GenericImpossibilityWitness::default()));
10090            }
10091            let mut hasher = H::initial();
10092            hasher = crate::enforcement::fold_terminal_reduction(
10093                hasher,
10094                tr_bits,
10095                tr_constraints,
10096                tr_sat,
10097            );
10098            let (tr2_bits, tr2_constraints, tr2_sat) =
10099                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10100                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10101            // Church-Rosser: second reduction must agree with the first.
10102            if tr2_bits != tr_bits || tr2_constraints != tr_constraints || tr2_sat != tr_sat {
10103                return Err(Certified::new(GenericImpossibilityWitness::default()));
10104            }
10105            hasher = crate::enforcement::fold_terminal_reduction(
10106                hasher,
10107                tr2_bits,
10108                tr2_constraints,
10109                tr2_sat,
10110            );
10111            hasher = crate::enforcement::fold_unit_digest(
10112                hasher,
10113                witt_bits,
10114                witt_bits as u64,
10115                T::IRI,
10116                T::SITE_COUNT,
10117                T::CONSTRAINTS,
10118                <Kernel as super::ResolverKernel>::KIND,
10119            );
10120            let buffer = hasher.finalize();
10121            let fp =
10122                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10123            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10124            Ok(Certified::new(cert))
10125        }
10126    }
10127
10128    /// Phase D (target §4.2): `resolver:TypeSynthesisResolver` — run the ψ-pipeline in inverse mode: given a `TypeSynthesisGoal` expressed through `ConstrainedTypeShape`, synthesize the type's carrier or signal impossibility.
10129    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10130    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10131    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10132    /// failure — the witness itself is certified so downstream can persist it
10133    /// alongside success certs in a uniform `Certified<_>` channel.
10134    /// Phase X.1: the produced cert class is the ontology-declared class for
10135    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10136    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10137    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10138    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10139    /// kernels so each resolver's class discrimination is load-bearing.
10140    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10141    /// kernel's composition spec) whose output is folded into the canonical
10142    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10143    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10144    /// content-addressed per its ontology class.
10145    pub mod type_synthesis {
10146        use super::*;
10147
10148        #[doc(hidden)]
10149        pub struct Kernel;
10150        impl super::ResolverKernel for Kernel {
10151            type Cert = crate::enforcement::TransformCertificate;
10152            const KIND: crate::enforcement::CertificateKind =
10153                crate::enforcement::CertificateKind::TypeSynthesis;
10154        }
10155
10156        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10157        ///
10158        /// # Errors
10159        ///
10160        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10161        pub fn certify<
10162            T: crate::pipeline::ConstrainedTypeShape,
10163            P: crate::enforcement::ValidationPhase,
10164            H: crate::enforcement::Hasher,
10165        >(
10166            input: &Validated<T, P>,
10167        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10168        {
10169            certify_at::<T, P, H>(input, WittLevel::W32)
10170        }
10171
10172        /// Phase D (target §4.2): certify at an explicit Witt level.
10173        ///
10174        /// # Errors
10175        ///
10176        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10177        pub fn certify_at<
10178            T: crate::pipeline::ConstrainedTypeShape,
10179            P: crate::enforcement::ValidationPhase,
10180            H: crate::enforcement::Hasher,
10181        >(
10182            input: &Validated<T, P>,
10183            level: WittLevel,
10184        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10185        {
10186            let _ = input.inner();
10187            let witt_bits = level.witt_length() as u16;
10188            let (tr_bits, tr_constraints, tr_sat) =
10189                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10190                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10191            if tr_sat == 0 {
10192                return Err(Certified::new(GenericImpossibilityWitness::default()));
10193            }
10194            let mut hasher = H::initial();
10195            hasher = crate::enforcement::fold_terminal_reduction(
10196                hasher,
10197                tr_bits,
10198                tr_constraints,
10199                tr_sat,
10200            );
10201            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10202                .map_err(crate::enforcement::Certified::new)?;
10203            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10204            let (residual, entropy) = crate::enforcement::primitive_descent_metrics::<T>(&betti);
10205            hasher = crate::enforcement::fold_descent_metrics(hasher, residual, entropy);
10206            hasher = crate::enforcement::fold_unit_digest(
10207                hasher,
10208                witt_bits,
10209                witt_bits as u64,
10210                T::IRI,
10211                T::SITE_COUNT,
10212                T::CONSTRAINTS,
10213                <Kernel as super::ResolverKernel>::KIND,
10214            );
10215            let buffer = hasher.finalize();
10216            let fp =
10217                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10218            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10219            Ok(Certified::new(cert))
10220        }
10221    }
10222
10223    /// Phase D (target §4.2): `resolver:HomotopyResolver` — compute homotopy-type observables (fundamental group rank, Postnikov-truncation records) by walking the constraint-nerve chain and extracting Betti-number evidence.
10224    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10225    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10226    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10227    /// failure — the witness itself is certified so downstream can persist it
10228    /// alongside success certs in a uniform `Certified<_>` channel.
10229    /// Phase X.1: the produced cert class is the ontology-declared class for
10230    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10231    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10232    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10233    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10234    /// kernels so each resolver's class discrimination is load-bearing.
10235    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10236    /// kernel's composition spec) whose output is folded into the canonical
10237    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10238    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10239    /// content-addressed per its ontology class.
10240    pub mod homotopy {
10241        use super::*;
10242
10243        #[doc(hidden)]
10244        pub struct Kernel;
10245        impl super::ResolverKernel for Kernel {
10246            type Cert = crate::enforcement::TransformCertificate;
10247            const KIND: crate::enforcement::CertificateKind =
10248                crate::enforcement::CertificateKind::Homotopy;
10249        }
10250
10251        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10252        ///
10253        /// # Errors
10254        ///
10255        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10256        pub fn certify<
10257            T: crate::pipeline::ConstrainedTypeShape,
10258            P: crate::enforcement::ValidationPhase,
10259            H: crate::enforcement::Hasher,
10260        >(
10261            input: &Validated<T, P>,
10262        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10263        {
10264            certify_at::<T, P, H>(input, WittLevel::W32)
10265        }
10266
10267        /// Phase D (target §4.2): certify at an explicit Witt level.
10268        ///
10269        /// # Errors
10270        ///
10271        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10272        pub fn certify_at<
10273            T: crate::pipeline::ConstrainedTypeShape,
10274            P: crate::enforcement::ValidationPhase,
10275            H: crate::enforcement::Hasher,
10276        >(
10277            input: &Validated<T, P>,
10278            level: WittLevel,
10279        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10280        {
10281            let _ = input.inner();
10282            let witt_bits = level.witt_length() as u16;
10283            let (tr_bits, tr_constraints, tr_sat) =
10284                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10285                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10286            if tr_sat == 0 {
10287                return Err(Certified::new(GenericImpossibilityWitness::default()));
10288            }
10289            let mut hasher = H::initial();
10290            hasher = crate::enforcement::fold_terminal_reduction(
10291                hasher,
10292                tr_bits,
10293                tr_constraints,
10294                tr_sat,
10295            );
10296            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10297                .map_err(crate::enforcement::Certified::new)?;
10298            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10299            hasher = crate::enforcement::fold_unit_digest(
10300                hasher,
10301                witt_bits,
10302                witt_bits as u64,
10303                T::IRI,
10304                T::SITE_COUNT,
10305                T::CONSTRAINTS,
10306                <Kernel as super::ResolverKernel>::KIND,
10307            );
10308            let buffer = hasher.finalize();
10309            let fp =
10310                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10311            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10312            Ok(Certified::new(cert))
10313        }
10314    }
10315
10316    /// Phase D (target §4.2): `resolver:MonodromyResolver` — compute monodromy-group observables by tracing the constraint-nerve boundary cycles at the input's Witt level.
10317    /// Returns `Certified<IsometryCertificate>` on success carrying the Witt
10318    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10319    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10320    /// failure — the witness itself is certified so downstream can persist it
10321    /// alongside success certs in a uniform `Certified<_>` channel.
10322    /// Phase X.1: the produced cert class is the ontology-declared class for
10323    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10324    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10325    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10326    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10327    /// kernels so each resolver's class discrimination is load-bearing.
10328    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10329    /// kernel's composition spec) whose output is folded into the canonical
10330    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10331    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10332    /// content-addressed per its ontology class.
10333    pub mod monodromy {
10334        use super::*;
10335
10336        #[doc(hidden)]
10337        pub struct Kernel;
10338        impl super::ResolverKernel for Kernel {
10339            type Cert = crate::enforcement::IsometryCertificate;
10340            const KIND: crate::enforcement::CertificateKind =
10341                crate::enforcement::CertificateKind::Monodromy;
10342        }
10343
10344        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10345        ///
10346        /// # Errors
10347        ///
10348        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10349        pub fn certify<
10350            T: crate::pipeline::ConstrainedTypeShape,
10351            P: crate::enforcement::ValidationPhase,
10352            H: crate::enforcement::Hasher,
10353        >(
10354            input: &Validated<T, P>,
10355        ) -> Result<Certified<IsometryCertificate>, Certified<GenericImpossibilityWitness>>
10356        {
10357            certify_at::<T, P, H>(input, WittLevel::W32)
10358        }
10359
10360        /// Phase D (target §4.2): certify at an explicit Witt level.
10361        ///
10362        /// # Errors
10363        ///
10364        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10365        pub fn certify_at<
10366            T: crate::pipeline::ConstrainedTypeShape,
10367            P: crate::enforcement::ValidationPhase,
10368            H: crate::enforcement::Hasher,
10369        >(
10370            input: &Validated<T, P>,
10371            level: WittLevel,
10372        ) -> Result<Certified<IsometryCertificate>, Certified<GenericImpossibilityWitness>>
10373        {
10374            let _ = input.inner();
10375            let witt_bits = level.witt_length() as u16;
10376            let (tr_bits, tr_constraints, tr_sat) =
10377                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10378                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10379            if tr_sat == 0 {
10380                return Err(Certified::new(GenericImpossibilityWitness::default()));
10381            }
10382            let mut hasher = H::initial();
10383            hasher = crate::enforcement::fold_terminal_reduction(
10384                hasher,
10385                tr_bits,
10386                tr_constraints,
10387                tr_sat,
10388            );
10389            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10390                .map_err(crate::enforcement::Certified::new)?;
10391            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10392            let (orbit_size, representative) =
10393                crate::enforcement::primitive_dihedral_signature::<T>();
10394            hasher =
10395                crate::enforcement::fold_dihedral_signature(hasher, orbit_size, representative);
10396            hasher = crate::enforcement::fold_unit_digest(
10397                hasher,
10398                witt_bits,
10399                witt_bits as u64,
10400                T::IRI,
10401                T::SITE_COUNT,
10402                T::CONSTRAINTS,
10403                <Kernel as super::ResolverKernel>::KIND,
10404            );
10405            let buffer = hasher.finalize();
10406            let fp =
10407                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10408            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10409            Ok(Certified::new(cert))
10410        }
10411    }
10412
10413    /// Phase D (target §4.2): `resolver:ModuliResolver` — compute the local moduli-space structure at a `CompleteType`: DeformationComplex, HolonomyStratum, tangent/obstruction dimensions.
10414    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10415    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10416    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10417    /// failure — the witness itself is certified so downstream can persist it
10418    /// alongside success certs in a uniform `Certified<_>` channel.
10419    /// Phase X.1: the produced cert class is the ontology-declared class for
10420    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10421    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10422    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10423    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10424    /// kernels so each resolver's class discrimination is load-bearing.
10425    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10426    /// kernel's composition spec) whose output is folded into the canonical
10427    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10428    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10429    /// content-addressed per its ontology class.
10430    pub mod moduli {
10431        use super::*;
10432
10433        #[doc(hidden)]
10434        pub struct Kernel;
10435        impl super::ResolverKernel for Kernel {
10436            type Cert = crate::enforcement::TransformCertificate;
10437            const KIND: crate::enforcement::CertificateKind =
10438                crate::enforcement::CertificateKind::Moduli;
10439        }
10440
10441        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10442        ///
10443        /// # Errors
10444        ///
10445        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10446        pub fn certify<
10447            T: crate::pipeline::ConstrainedTypeShape,
10448            P: crate::enforcement::ValidationPhase,
10449            H: crate::enforcement::Hasher,
10450        >(
10451            input: &Validated<T, P>,
10452        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10453        {
10454            certify_at::<T, P, H>(input, WittLevel::W32)
10455        }
10456
10457        /// Phase D (target §4.2): certify at an explicit Witt level.
10458        ///
10459        /// # Errors
10460        ///
10461        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10462        pub fn certify_at<
10463            T: crate::pipeline::ConstrainedTypeShape,
10464            P: crate::enforcement::ValidationPhase,
10465            H: crate::enforcement::Hasher,
10466        >(
10467            input: &Validated<T, P>,
10468            level: WittLevel,
10469        ) -> Result<Certified<TransformCertificate>, Certified<GenericImpossibilityWitness>>
10470        {
10471            let _ = input.inner();
10472            let witt_bits = level.witt_length() as u16;
10473            let (tr_bits, tr_constraints, tr_sat) =
10474                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10475                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10476            if tr_sat == 0 {
10477                return Err(Certified::new(GenericImpossibilityWitness::default()));
10478            }
10479            let mut hasher = H::initial();
10480            hasher = crate::enforcement::fold_terminal_reduction(
10481                hasher,
10482                tr_bits,
10483                tr_constraints,
10484                tr_sat,
10485            );
10486            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10487                .map_err(crate::enforcement::Certified::new)?;
10488            let automorphisms: u32 = betti[0];
10489            let deformations: u32 = if crate::enforcement::MAX_BETTI_DIMENSION > 1 {
10490                betti[1]
10491            } else {
10492                0
10493            };
10494            let obstructions: u32 = if crate::enforcement::MAX_BETTI_DIMENSION > 2 {
10495                betti[2]
10496            } else {
10497                0
10498            };
10499            hasher = hasher.fold_bytes(&automorphisms.to_be_bytes());
10500            hasher = hasher.fold_bytes(&deformations.to_be_bytes());
10501            hasher = hasher.fold_bytes(&obstructions.to_be_bytes());
10502            hasher = crate::enforcement::fold_unit_digest(
10503                hasher,
10504                witt_bits,
10505                witt_bits as u64,
10506                T::IRI,
10507                T::SITE_COUNT,
10508                T::CONSTRAINTS,
10509                <Kernel as super::ResolverKernel>::KIND,
10510            );
10511            let buffer = hasher.finalize();
10512            let fp =
10513                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10514            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10515            Ok(Certified::new(cert))
10516        }
10517    }
10518
10519    /// Phase D (target §4.2): `resolver:JacobianGuidedResolver` — drive reduction using the per-site Jacobian profile; short-circuits when the Jacobian stabilizes, producing a cert attesting the stabilized observable.
10520    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10521    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10522    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10523    /// failure — the witness itself is certified so downstream can persist it
10524    /// alongside success certs in a uniform `Certified<_>` channel.
10525    /// Phase X.1: the produced cert class is the ontology-declared class for
10526    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10527    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10528    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10529    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10530    /// kernels so each resolver's class discrimination is load-bearing.
10531    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10532    /// kernel's composition spec) whose output is folded into the canonical
10533    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10534    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10535    /// content-addressed per its ontology class.
10536    pub mod jacobian_guided {
10537        use super::*;
10538
10539        #[doc(hidden)]
10540        pub struct Kernel;
10541        impl super::ResolverKernel for Kernel {
10542            type Cert = crate::enforcement::GroundingCertificate;
10543            const KIND: crate::enforcement::CertificateKind =
10544                crate::enforcement::CertificateKind::JacobianGuided;
10545        }
10546
10547        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10548        ///
10549        /// # Errors
10550        ///
10551        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10552        pub fn certify<
10553            T: crate::pipeline::ConstrainedTypeShape,
10554            P: crate::enforcement::ValidationPhase,
10555            H: crate::enforcement::Hasher,
10556        >(
10557            input: &Validated<T, P>,
10558        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10559        {
10560            certify_at::<T, P, H>(input, WittLevel::W32)
10561        }
10562
10563        /// Phase D (target §4.2): certify at an explicit Witt level.
10564        ///
10565        /// # Errors
10566        ///
10567        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10568        pub fn certify_at<
10569            T: crate::pipeline::ConstrainedTypeShape,
10570            P: crate::enforcement::ValidationPhase,
10571            H: crate::enforcement::Hasher,
10572        >(
10573            input: &Validated<T, P>,
10574            level: WittLevel,
10575        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10576        {
10577            let _ = input.inner();
10578            let witt_bits = level.witt_length() as u16;
10579            let (tr_bits, tr_constraints, tr_sat) =
10580                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10581                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10582            if tr_sat == 0 {
10583                return Err(Certified::new(GenericImpossibilityWitness::default()));
10584            }
10585            let mut hasher = H::initial();
10586            hasher = crate::enforcement::fold_terminal_reduction(
10587                hasher,
10588                tr_bits,
10589                tr_constraints,
10590                tr_sat,
10591            );
10592            let jac = crate::enforcement::primitive_curvature_jacobian::<T>();
10593            hasher = crate::enforcement::fold_jacobian_profile(hasher, &jac);
10594            let selected_site = crate::enforcement::primitive_dc10_select(&jac);
10595            hasher = hasher.fold_bytes(&(selected_site as u32).to_be_bytes());
10596            hasher = crate::enforcement::fold_unit_digest(
10597                hasher,
10598                witt_bits,
10599                witt_bits as u64,
10600                T::IRI,
10601                T::SITE_COUNT,
10602                T::CONSTRAINTS,
10603                <Kernel as super::ResolverKernel>::KIND,
10604            );
10605            let buffer = hasher.finalize();
10606            let fp =
10607                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10608            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10609            Ok(Certified::new(cert))
10610        }
10611    }
10612
10613    /// Phase D (target §4.2): `resolver:EvaluationResolver` — evaluate a grounded term at a given Witt level; the returned cert attests that the evaluation completed within the declared budget.
10614    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10615    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10616    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10617    /// failure — the witness itself is certified so downstream can persist it
10618    /// alongside success certs in a uniform `Certified<_>` channel.
10619    /// Phase X.1: the produced cert class is the ontology-declared class for
10620    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10621    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10622    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10623    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10624    /// kernels so each resolver's class discrimination is load-bearing.
10625    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10626    /// kernel's composition spec) whose output is folded into the canonical
10627    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10628    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10629    /// content-addressed per its ontology class.
10630    pub mod evaluation {
10631        use super::*;
10632
10633        #[doc(hidden)]
10634        pub struct Kernel;
10635        impl super::ResolverKernel for Kernel {
10636            type Cert = crate::enforcement::GroundingCertificate;
10637            const KIND: crate::enforcement::CertificateKind =
10638                crate::enforcement::CertificateKind::Evaluation;
10639        }
10640
10641        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10642        ///
10643        /// # Errors
10644        ///
10645        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10646        pub fn certify<
10647            T: crate::pipeline::ConstrainedTypeShape,
10648            P: crate::enforcement::ValidationPhase,
10649            H: crate::enforcement::Hasher,
10650        >(
10651            input: &Validated<T, P>,
10652        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10653        {
10654            certify_at::<T, P, H>(input, WittLevel::W32)
10655        }
10656
10657        /// Phase D (target §4.2): certify at an explicit Witt level.
10658        ///
10659        /// # Errors
10660        ///
10661        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10662        pub fn certify_at<
10663            T: crate::pipeline::ConstrainedTypeShape,
10664            P: crate::enforcement::ValidationPhase,
10665            H: crate::enforcement::Hasher,
10666        >(
10667            input: &Validated<T, P>,
10668            level: WittLevel,
10669        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10670        {
10671            let _ = input.inner();
10672            let witt_bits = level.witt_length() as u16;
10673            let (tr_bits, tr_constraints, tr_sat) =
10674                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10675                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10676            if tr_sat == 0 {
10677                return Err(Certified::new(GenericImpossibilityWitness::default()));
10678            }
10679            let mut hasher = H::initial();
10680            hasher = crate::enforcement::fold_terminal_reduction(
10681                hasher,
10682                tr_bits,
10683                tr_constraints,
10684                tr_sat,
10685            );
10686            hasher = crate::enforcement::fold_unit_digest(
10687                hasher,
10688                witt_bits,
10689                witt_bits as u64,
10690                T::IRI,
10691                T::SITE_COUNT,
10692                T::CONSTRAINTS,
10693                <Kernel as super::ResolverKernel>::KIND,
10694            );
10695            let buffer = hasher.finalize();
10696            let fp =
10697                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10698            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10699            Ok(Certified::new(cert))
10700        }
10701    }
10702
10703    /// Phase D (target §4.2): `resolver:SessionResolver` — advance a lease-scoped `state:ContextLease` by one reduction step and emit a cert over the lease's resulting BindingsTable.
10704    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10705    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10706    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10707    /// failure — the witness itself is certified so downstream can persist it
10708    /// alongside success certs in a uniform `Certified<_>` channel.
10709    /// Phase X.1: the produced cert class is the ontology-declared class for
10710    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10711    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10712    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10713    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10714    /// kernels so each resolver's class discrimination is load-bearing.
10715    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10716    /// kernel's composition spec) whose output is folded into the canonical
10717    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10718    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10719    /// content-addressed per its ontology class.
10720    pub mod session {
10721        use super::*;
10722
10723        #[doc(hidden)]
10724        pub struct Kernel;
10725        impl super::ResolverKernel for Kernel {
10726            type Cert = crate::enforcement::GroundingCertificate;
10727            const KIND: crate::enforcement::CertificateKind =
10728                crate::enforcement::CertificateKind::Session;
10729        }
10730
10731        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10732        ///
10733        /// # Errors
10734        ///
10735        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10736        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10737            input: &Validated<CompileUnit, P>,
10738        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10739        {
10740            certify_at::<P, H>(input, WittLevel::W32)
10741        }
10742
10743        /// Phase D (target §4.2): certify at an explicit Witt level.
10744        ///
10745        /// # Errors
10746        ///
10747        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10748        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10749            input: &Validated<CompileUnit, P>,
10750            level: WittLevel,
10751        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10752        {
10753            let unit = input.inner();
10754            let witt_bits = level.witt_length() as u16;
10755            let budget = unit.thermodynamic_budget();
10756            let result_type_iri = unit.result_type_iri();
10757            let mut hasher = H::initial();
10758            let (binding_count, fold_addr) =
10759                crate::enforcement::primitive_session_binding_signature(unit.bindings());
10760            hasher = crate::enforcement::fold_session_signature(hasher, binding_count, fold_addr);
10761            hasher = crate::enforcement::fold_unit_digest(
10762                hasher,
10763                witt_bits,
10764                budget,
10765                result_type_iri,
10766                0usize,
10767                &[],
10768                <Kernel as super::ResolverKernel>::KIND,
10769            );
10770            let buffer = hasher.finalize();
10771            let fp =
10772                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10773            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10774            Ok(Certified::new(cert))
10775        }
10776    }
10777
10778    /// Phase D (target §4.2): `resolver:SuperpositionResolver` — advance a SuperpositionResolver across a ψ-pipeline branch tree, maintaining an amplitude vector that satisfies the Born-rule normalization constraint (Σ|αᵢ|² = 1).
10779    /// Returns `Certified<BornRuleVerification>` on success carrying the Witt
10780    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10781    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10782    /// failure — the witness itself is certified so downstream can persist it
10783    /// alongside success certs in a uniform `Certified<_>` channel.
10784    /// Phase X.1: the produced cert class is the ontology-declared class for
10785    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10786    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10787    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10788    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10789    /// kernels so each resolver's class discrimination is load-bearing.
10790    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10791    /// kernel's composition spec) whose output is folded into the canonical
10792    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10793    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10794    /// content-addressed per its ontology class.
10795    pub mod superposition {
10796        use super::*;
10797
10798        #[doc(hidden)]
10799        pub struct Kernel;
10800        impl super::ResolverKernel for Kernel {
10801            type Cert = crate::enforcement::BornRuleVerification;
10802            const KIND: crate::enforcement::CertificateKind =
10803                crate::enforcement::CertificateKind::Superposition;
10804        }
10805
10806        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10807        ///
10808        /// # Errors
10809        ///
10810        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10811        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10812            input: &Validated<CompileUnit, P>,
10813        ) -> Result<Certified<BornRuleVerification>, Certified<GenericImpossibilityWitness>>
10814        {
10815            certify_at::<P, H>(input, WittLevel::W32)
10816        }
10817
10818        /// Phase D (target §4.2): certify at an explicit Witt level.
10819        ///
10820        /// # Errors
10821        ///
10822        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10823        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10824            input: &Validated<CompileUnit, P>,
10825            level: WittLevel,
10826        ) -> Result<Certified<BornRuleVerification>, Certified<GenericImpossibilityWitness>>
10827        {
10828            let unit = input.inner();
10829            let witt_bits = level.witt_length() as u16;
10830            let budget = unit.thermodynamic_budget();
10831            let result_type_iri = unit.result_type_iri();
10832            let mut hasher = H::initial();
10833            let (binding_count, fold_addr) =
10834                crate::enforcement::primitive_session_binding_signature(unit.bindings());
10835            hasher = crate::enforcement::fold_session_signature(hasher, binding_count, fold_addr);
10836            let (outcome_index, probability) =
10837                crate::enforcement::primitive_measurement_projection(budget);
10838            hasher = crate::enforcement::fold_born_outcome(hasher, outcome_index, probability);
10839            hasher = crate::enforcement::fold_unit_digest(
10840                hasher,
10841                witt_bits,
10842                budget,
10843                result_type_iri,
10844                0usize,
10845                &[],
10846                <Kernel as super::ResolverKernel>::KIND,
10847            );
10848            let buffer = hasher.finalize();
10849            let fp =
10850                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10851            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10852            Ok(Certified::new(cert))
10853        }
10854    }
10855
10856    /// Phase D (target §4.2): `resolver:MeasurementResolver` — resolve a `trace:MeasurementEvent` against the von Neumann-Landauer bridge (QM_1): `preCollapseEntropy = postCollapseLandauerCost` at β* = ln 2.
10857    /// Returns `Certified<MeasurementCertificate>` on success carrying the Witt
10858    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10859    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10860    /// failure — the witness itself is certified so downstream can persist it
10861    /// alongside success certs in a uniform `Certified<_>` channel.
10862    /// Phase X.1: the produced cert class is the ontology-declared class for
10863    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10864    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10865    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10866    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10867    /// kernels so each resolver's class discrimination is load-bearing.
10868    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10869    /// kernel's composition spec) whose output is folded into the canonical
10870    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10871    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10872    /// content-addressed per its ontology class.
10873    pub mod measurement {
10874        use super::*;
10875
10876        #[doc(hidden)]
10877        pub struct Kernel;
10878        impl super::ResolverKernel for Kernel {
10879            type Cert = crate::enforcement::MeasurementCertificate;
10880            const KIND: crate::enforcement::CertificateKind =
10881                crate::enforcement::CertificateKind::Measurement;
10882        }
10883
10884        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10885        ///
10886        /// # Errors
10887        ///
10888        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10889        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10890            input: &Validated<CompileUnit, P>,
10891        ) -> Result<Certified<MeasurementCertificate>, Certified<GenericImpossibilityWitness>>
10892        {
10893            certify_at::<P, H>(input, WittLevel::W32)
10894        }
10895
10896        /// Phase D (target §4.2): certify at an explicit Witt level.
10897        ///
10898        /// # Errors
10899        ///
10900        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10901        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10902            input: &Validated<CompileUnit, P>,
10903            level: WittLevel,
10904        ) -> Result<Certified<MeasurementCertificate>, Certified<GenericImpossibilityWitness>>
10905        {
10906            let unit = input.inner();
10907            let witt_bits = level.witt_length() as u16;
10908            let budget = unit.thermodynamic_budget();
10909            let result_type_iri = unit.result_type_iri();
10910            let mut hasher = H::initial();
10911            let (outcome_index, probability) =
10912                crate::enforcement::primitive_measurement_projection(budget);
10913            hasher = crate::enforcement::fold_born_outcome(hasher, outcome_index, probability);
10914            hasher = crate::enforcement::fold_unit_digest(
10915                hasher,
10916                witt_bits,
10917                budget,
10918                result_type_iri,
10919                0usize,
10920                &[],
10921                <Kernel as super::ResolverKernel>::KIND,
10922            );
10923            let buffer = hasher.finalize();
10924            let fp =
10925                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10926            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
10927            Ok(Certified::new(cert))
10928        }
10929    }
10930
10931    /// Phase D (target §4.2): `resolver:WittLevelResolver` — given a WittLevel declaration, validate the (bit_width, cycle_size) pair satisfies `conformance:WittLevelShape` and emit a cert over the normalized level.
10932    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10933    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10934    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10935    /// failure — the witness itself is certified so downstream can persist it
10936    /// alongside success certs in a uniform `Certified<_>` channel.
10937    /// Phase X.1: the produced cert class is the ontology-declared class for
10938    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10939    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10940    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10941    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10942    /// kernels so each resolver's class discrimination is load-bearing.
10943    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10944    /// kernel's composition spec) whose output is folded into the canonical
10945    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10946    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10947    /// content-addressed per its ontology class.
10948    pub mod witt_level_resolver {
10949        use super::*;
10950
10951        #[doc(hidden)]
10952        pub struct Kernel;
10953        impl super::ResolverKernel for Kernel {
10954            type Cert = crate::enforcement::GroundingCertificate;
10955            const KIND: crate::enforcement::CertificateKind =
10956                crate::enforcement::CertificateKind::WittLevel;
10957        }
10958
10959        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10960        ///
10961        /// # Errors
10962        ///
10963        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10964        pub fn certify<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10965            input: &Validated<CompileUnit, P>,
10966        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10967        {
10968            certify_at::<P, H>(input, WittLevel::W32)
10969        }
10970
10971        /// Phase D (target §4.2): certify at an explicit Witt level.
10972        ///
10973        /// # Errors
10974        ///
10975        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10976        pub fn certify_at<P: crate::enforcement::ValidationPhase, H: crate::enforcement::Hasher>(
10977            input: &Validated<CompileUnit, P>,
10978            level: WittLevel,
10979        ) -> Result<Certified<GroundingCertificate>, Certified<GenericImpossibilityWitness>>
10980        {
10981            let unit = input.inner();
10982            let witt_bits = level.witt_length() as u16;
10983            let budget = unit.thermodynamic_budget();
10984            let result_type_iri = unit.result_type_iri();
10985            let mut hasher = H::initial();
10986            hasher = hasher.fold_bytes(&witt_bits.to_be_bytes());
10987            let declared_level_bits = unit.witt_level().witt_length() as u16;
10988            hasher = hasher.fold_bytes(&declared_level_bits.to_be_bytes());
10989            hasher = crate::enforcement::fold_unit_digest(
10990                hasher,
10991                witt_bits,
10992                budget,
10993                result_type_iri,
10994                0usize,
10995                &[],
10996                <Kernel as super::ResolverKernel>::KIND,
10997            );
10998            let buffer = hasher.finalize();
10999            let fp =
11000                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11001            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
11002            Ok(Certified::new(cert))
11003        }
11004    }
11005
11006    /// Phase D (target §4.2): `resolver:DihedralFactorizationResolver` — run the dihedral factorization decider on a `ConstrainedType`'s carrier, producing a cert over the factor structure.
11007    /// Returns `Certified<InvolutionCertificate>` on success carrying the Witt
11008    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
11009    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
11010    /// failure — the witness itself is certified so downstream can persist it
11011    /// alongside success certs in a uniform `Certified<_>` channel.
11012    /// Phase X.1: the produced cert class is the ontology-declared class for
11013    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
11014    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
11015    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
11016    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
11017    /// kernels so each resolver's class discrimination is load-bearing.
11018    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11019    /// kernel's composition spec) whose output is folded into the canonical
11020    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11021    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11022    /// content-addressed per its ontology class.
11023    pub mod dihedral_factorization {
11024        use super::*;
11025
11026        #[doc(hidden)]
11027        pub struct Kernel;
11028        impl super::ResolverKernel for Kernel {
11029            type Cert = crate::enforcement::InvolutionCertificate;
11030            const KIND: crate::enforcement::CertificateKind =
11031                crate::enforcement::CertificateKind::DihedralFactorization;
11032        }
11033
11034        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11035        ///
11036        /// # Errors
11037        ///
11038        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11039        pub fn certify<
11040            T: crate::pipeline::ConstrainedTypeShape,
11041            P: crate::enforcement::ValidationPhase,
11042            H: crate::enforcement::Hasher,
11043        >(
11044            input: &Validated<T, P>,
11045        ) -> Result<Certified<InvolutionCertificate>, Certified<GenericImpossibilityWitness>>
11046        {
11047            certify_at::<T, P, H>(input, WittLevel::W32)
11048        }
11049
11050        /// Phase D (target §4.2): certify at an explicit Witt level.
11051        ///
11052        /// # Errors
11053        ///
11054        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11055        pub fn certify_at<
11056            T: crate::pipeline::ConstrainedTypeShape,
11057            P: crate::enforcement::ValidationPhase,
11058            H: crate::enforcement::Hasher,
11059        >(
11060            input: &Validated<T, P>,
11061            level: WittLevel,
11062        ) -> Result<Certified<InvolutionCertificate>, Certified<GenericImpossibilityWitness>>
11063        {
11064            let _ = input.inner();
11065            let witt_bits = level.witt_length() as u16;
11066            let (tr_bits, tr_constraints, tr_sat) =
11067                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11068                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11069            if tr_sat == 0 {
11070                return Err(Certified::new(GenericImpossibilityWitness::default()));
11071            }
11072            let mut hasher = H::initial();
11073            hasher = crate::enforcement::fold_terminal_reduction(
11074                hasher,
11075                tr_bits,
11076                tr_constraints,
11077                tr_sat,
11078            );
11079            let (orbit_size, representative) =
11080                crate::enforcement::primitive_dihedral_signature::<T>();
11081            hasher =
11082                crate::enforcement::fold_dihedral_signature(hasher, orbit_size, representative);
11083            hasher = crate::enforcement::fold_unit_digest(
11084                hasher,
11085                witt_bits,
11086                witt_bits as u64,
11087                T::IRI,
11088                T::SITE_COUNT,
11089                T::CONSTRAINTS,
11090                <Kernel as super::ResolverKernel>::KIND,
11091            );
11092            let buffer = hasher.finalize();
11093            let fp =
11094                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11095            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
11096            Ok(Certified::new(cert))
11097        }
11098    }
11099
11100    /// Phase D (target §4.2): `resolver:CompletenessResolver` — generic completeness-loop resolver: runs the ψ-pipeline without the tower-specific lift chain and emits a cert if the input's constraint nerve has Euler characteristic n at quantum level n.
11101    /// Returns `Certified<CompletenessCertificate>` on success carrying the Witt
11102    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
11103    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
11104    /// failure — the witness itself is certified so downstream can persist it
11105    /// alongside success certs in a uniform `Certified<_>` channel.
11106    /// Phase X.1: the produced cert class is the ontology-declared class for
11107    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
11108    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
11109    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
11110    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
11111    /// kernels so each resolver's class discrimination is load-bearing.
11112    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11113    /// kernel's composition spec) whose output is folded into the canonical
11114    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11115    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11116    /// content-addressed per its ontology class.
11117    pub mod completeness {
11118        use super::*;
11119
11120        #[doc(hidden)]
11121        pub struct Kernel;
11122        impl super::ResolverKernel for Kernel {
11123            type Cert = crate::enforcement::CompletenessCertificate;
11124            const KIND: crate::enforcement::CertificateKind =
11125                crate::enforcement::CertificateKind::Completeness;
11126        }
11127
11128        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11129        ///
11130        /// # Errors
11131        ///
11132        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11133        pub fn certify<
11134            T: crate::pipeline::ConstrainedTypeShape,
11135            P: crate::enforcement::ValidationPhase,
11136            H: crate::enforcement::Hasher,
11137        >(
11138            input: &Validated<T, P>,
11139        ) -> Result<Certified<CompletenessCertificate>, Certified<GenericImpossibilityWitness>>
11140        {
11141            certify_at::<T, P, H>(input, WittLevel::W32)
11142        }
11143
11144        /// Phase D (target §4.2): certify at an explicit Witt level.
11145        ///
11146        /// # Errors
11147        ///
11148        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11149        pub fn certify_at<
11150            T: crate::pipeline::ConstrainedTypeShape,
11151            P: crate::enforcement::ValidationPhase,
11152            H: crate::enforcement::Hasher,
11153        >(
11154            input: &Validated<T, P>,
11155            level: WittLevel,
11156        ) -> Result<Certified<CompletenessCertificate>, Certified<GenericImpossibilityWitness>>
11157        {
11158            let _ = input.inner();
11159            let witt_bits = level.witt_length() as u16;
11160            let (tr_bits, tr_constraints, tr_sat) =
11161                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11162                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11163            if tr_sat == 0 {
11164                return Err(Certified::new(GenericImpossibilityWitness::default()));
11165            }
11166            let mut hasher = H::initial();
11167            hasher = crate::enforcement::fold_terminal_reduction(
11168                hasher,
11169                tr_bits,
11170                tr_constraints,
11171                tr_sat,
11172            );
11173            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
11174                .map_err(crate::enforcement::Certified::new)?;
11175            let chi = crate::enforcement::primitive_euler_characteristic(&betti);
11176            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
11177            hasher = hasher.fold_bytes(&chi.to_be_bytes());
11178            hasher = crate::enforcement::fold_unit_digest(
11179                hasher,
11180                witt_bits,
11181                witt_bits as u64,
11182                T::IRI,
11183                T::SITE_COUNT,
11184                T::CONSTRAINTS,
11185                <Kernel as super::ResolverKernel>::KIND,
11186            );
11187            let buffer = hasher.finalize();
11188            let fp =
11189                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11190            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
11191            Ok(Certified::new(cert))
11192        }
11193    }
11194
11195    /// Phase D (target §4.2): `resolver:GeodesicValidator` — validate whether a `trace:ComputationTrace` satisfies the dual geodesic condition (AR_1-ordered and DC_10-selected); produces a `GeodesicCertificate` on success, `GenericImpossibilityWitness` otherwise.
11196    /// Returns `Certified<GeodesicCertificate>` on success carrying the Witt
11197    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
11198    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
11199    /// failure — the witness itself is certified so downstream can persist it
11200    /// alongside success certs in a uniform `Certified<_>` channel.
11201    /// Phase X.1: the produced cert class is the ontology-declared class for
11202    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
11203    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
11204    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
11205    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
11206    /// kernels so each resolver's class discrimination is load-bearing.
11207    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11208    /// kernel's composition spec) whose output is folded into the canonical
11209    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11210    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11211    /// content-addressed per its ontology class.
11212    pub mod geodesic_validator {
11213        use super::*;
11214
11215        #[doc(hidden)]
11216        pub struct Kernel;
11217        impl super::ResolverKernel for Kernel {
11218            type Cert = crate::enforcement::GeodesicCertificate;
11219            const KIND: crate::enforcement::CertificateKind =
11220                crate::enforcement::CertificateKind::GeodesicValidator;
11221        }
11222
11223        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11224        ///
11225        /// # Errors
11226        ///
11227        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11228        pub fn certify<
11229            T: crate::pipeline::ConstrainedTypeShape,
11230            P: crate::enforcement::ValidationPhase,
11231            H: crate::enforcement::Hasher,
11232        >(
11233            input: &Validated<T, P>,
11234        ) -> Result<Certified<GeodesicCertificate>, Certified<GenericImpossibilityWitness>>
11235        {
11236            certify_at::<T, P, H>(input, WittLevel::W32)
11237        }
11238
11239        /// Phase D (target §4.2): certify at an explicit Witt level.
11240        ///
11241        /// # Errors
11242        ///
11243        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11244        pub fn certify_at<
11245            T: crate::pipeline::ConstrainedTypeShape,
11246            P: crate::enforcement::ValidationPhase,
11247            H: crate::enforcement::Hasher,
11248        >(
11249            input: &Validated<T, P>,
11250            level: WittLevel,
11251        ) -> Result<Certified<GeodesicCertificate>, Certified<GenericImpossibilityWitness>>
11252        {
11253            let _ = input.inner();
11254            let witt_bits = level.witt_length() as u16;
11255            let (tr_bits, tr_constraints, tr_sat) =
11256                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11257                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11258            if tr_sat == 0 {
11259                return Err(Certified::new(GenericImpossibilityWitness::default()));
11260            }
11261            let mut hasher = H::initial();
11262            hasher = crate::enforcement::fold_terminal_reduction(
11263                hasher,
11264                tr_bits,
11265                tr_constraints,
11266                tr_sat,
11267            );
11268            let jac = crate::enforcement::primitive_curvature_jacobian::<T>();
11269            hasher = crate::enforcement::fold_jacobian_profile(hasher, &jac);
11270            let selected_site = crate::enforcement::primitive_dc10_select(&jac);
11271            hasher = hasher.fold_bytes(&(selected_site as u32).to_be_bytes());
11272            hasher = crate::enforcement::fold_unit_digest(
11273                hasher,
11274                witt_bits,
11275                witt_bits as u64,
11276                T::IRI,
11277                T::SITE_COUNT,
11278                T::CONSTRAINTS,
11279                <Kernel as super::ResolverKernel>::KIND,
11280            );
11281            let buffer = hasher.finalize();
11282            let fp =
11283                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11284            let cert = <<Kernel as super::ResolverKernel>::Cert as crate::enforcement::certify_const_mint::MintWithLevelFingerprint>::mint_with_level_fingerprint(witt_bits, fp);
11285            Ok(Certified::new(cert))
11286        }
11287    }
11288}
11289
11290/// v0.2.2 phantom-typed ring operation surface. Each phantom struct binds a
11291/// `WittLevel` at the type level so consumers can write
11292/// `Mul::<W8>::apply(a, b)` for compile-time level-checked arithmetic.
11293pub trait RingOp<L> {
11294    /// Operand type at this level.
11295    type Operand;
11296    /// Apply this binary ring op.
11297    fn apply(a: Self::Operand, b: Self::Operand) -> Self::Operand;
11298}
11299
11300/// v0.2.2 W3: unary phantom-typed ring operation surface. Mirrors `RingOp`
11301/// for arity-1 operations (`Neg`, `BNot`, `Succ`) so consumers can write
11302/// `Neg::<W8>::apply(a)` for compile-time level-checked unary arithmetic.
11303pub trait UnaryRingOp<L> {
11304    /// Operand type at this level.
11305    type Operand;
11306    /// Apply this unary ring op.
11307    fn apply(a: Self::Operand) -> Self::Operand;
11308}
11309
11310/// Multiplicative ring op. phantom-typed at level `L`.
11311#[derive(Debug, Default, Clone, Copy)]
11312pub struct Mul<L>(PhantomData<L>);
11313
11314/// Additive ring op. phantom-typed at level `L`.
11315#[derive(Debug, Default, Clone, Copy)]
11316pub struct Add<L>(PhantomData<L>);
11317
11318/// Subtractive ring op. phantom-typed at level `L`.
11319#[derive(Debug, Default, Clone, Copy)]
11320pub struct Sub<L>(PhantomData<L>);
11321
11322/// Bitwise XOR ring op. phantom-typed at level `L`.
11323#[derive(Debug, Default, Clone, Copy)]
11324pub struct Xor<L>(PhantomData<L>);
11325
11326/// Bitwise AND ring op. phantom-typed at level `L`.
11327#[derive(Debug, Default, Clone, Copy)]
11328pub struct And<L>(PhantomData<L>);
11329
11330/// Bitwise OR ring op. phantom-typed at level `L`.
11331#[derive(Debug, Default, Clone, Copy)]
11332pub struct Or<L>(PhantomData<L>);
11333
11334/// Ring negation (the canonical involution: x → -x). Phantom-typed at level `L` (v0.2.2 W3).
11335#[derive(Debug, Default, Clone, Copy)]
11336pub struct Neg<L>(PhantomData<L>);
11337
11338/// Bitwise NOT (the Hamming involution: x → (2^n - 1) XOR x). Phantom-typed at level `L` (v0.2.2 W3).
11339#[derive(Debug, Default, Clone, Copy)]
11340pub struct BNot<L>(PhantomData<L>);
11341
11342/// Successor (= Neg ∘ BNot per the critical composition law). Phantom-typed at level `L` (v0.2.2 W3).
11343#[derive(Debug, Default, Clone, Copy)]
11344pub struct Succ<L>(PhantomData<L>);
11345
11346/// W8 marker — 8-bit Witt level reified at the type level.
11347#[derive(Debug, Default, Clone, Copy)]
11348pub struct W8;
11349
11350/// W16 marker — 16-bit Witt level reified at the type level.
11351#[derive(Debug, Default, Clone, Copy)]
11352pub struct W16;
11353
11354/// W24 marker — 24-bit Witt level reified at the type level.
11355#[derive(Debug, Default, Clone, Copy)]
11356pub struct W24;
11357
11358/// W32 marker — 32-bit Witt level reified at the type level.
11359#[derive(Debug, Default, Clone, Copy)]
11360pub struct W32;
11361
11362/// W40 marker — 40-bit Witt level reified at the type level.
11363#[derive(Debug, Default, Clone, Copy)]
11364pub struct W40;
11365
11366/// W48 marker — 48-bit Witt level reified at the type level.
11367#[derive(Debug, Default, Clone, Copy)]
11368pub struct W48;
11369
11370/// W56 marker — 56-bit Witt level reified at the type level.
11371#[derive(Debug, Default, Clone, Copy)]
11372pub struct W56;
11373
11374/// W64 marker — 64-bit Witt level reified at the type level.
11375#[derive(Debug, Default, Clone, Copy)]
11376pub struct W64;
11377
11378/// W72 marker — 72-bit Witt level reified at the type level.
11379#[derive(Debug, Default, Clone, Copy)]
11380pub struct W72;
11381
11382/// W80 marker — 80-bit Witt level reified at the type level.
11383#[derive(Debug, Default, Clone, Copy)]
11384pub struct W80;
11385
11386/// W88 marker — 88-bit Witt level reified at the type level.
11387#[derive(Debug, Default, Clone, Copy)]
11388pub struct W88;
11389
11390/// W96 marker — 96-bit Witt level reified at the type level.
11391#[derive(Debug, Default, Clone, Copy)]
11392pub struct W96;
11393
11394/// W104 marker — 104-bit Witt level reified at the type level.
11395#[derive(Debug, Default, Clone, Copy)]
11396pub struct W104;
11397
11398/// W112 marker — 112-bit Witt level reified at the type level.
11399#[derive(Debug, Default, Clone, Copy)]
11400pub struct W112;
11401
11402/// W120 marker — 120-bit Witt level reified at the type level.
11403#[derive(Debug, Default, Clone, Copy)]
11404pub struct W120;
11405
11406/// W128 marker — 128-bit Witt level reified at the type level.
11407#[derive(Debug, Default, Clone, Copy)]
11408pub struct W128;
11409
11410impl RingOp<W8> for Mul<W8> {
11411    type Operand = u8;
11412    #[inline]
11413    fn apply(a: u8, b: u8) -> u8 {
11414        const_ring_eval_w8(PrimitiveOp::Mul, a, b)
11415    }
11416}
11417
11418impl RingOp<W8> for Add<W8> {
11419    type Operand = u8;
11420    #[inline]
11421    fn apply(a: u8, b: u8) -> u8 {
11422        const_ring_eval_w8(PrimitiveOp::Add, a, b)
11423    }
11424}
11425
11426impl RingOp<W8> for Sub<W8> {
11427    type Operand = u8;
11428    #[inline]
11429    fn apply(a: u8, b: u8) -> u8 {
11430        const_ring_eval_w8(PrimitiveOp::Sub, a, b)
11431    }
11432}
11433
11434impl RingOp<W8> for Xor<W8> {
11435    type Operand = u8;
11436    #[inline]
11437    fn apply(a: u8, b: u8) -> u8 {
11438        const_ring_eval_w8(PrimitiveOp::Xor, a, b)
11439    }
11440}
11441
11442impl RingOp<W8> for And<W8> {
11443    type Operand = u8;
11444    #[inline]
11445    fn apply(a: u8, b: u8) -> u8 {
11446        const_ring_eval_w8(PrimitiveOp::And, a, b)
11447    }
11448}
11449
11450impl RingOp<W8> for Or<W8> {
11451    type Operand = u8;
11452    #[inline]
11453    fn apply(a: u8, b: u8) -> u8 {
11454        const_ring_eval_w8(PrimitiveOp::Or, a, b)
11455    }
11456}
11457
11458impl RingOp<W16> for Mul<W16> {
11459    type Operand = u16;
11460    #[inline]
11461    fn apply(a: u16, b: u16) -> u16 {
11462        const_ring_eval_w16(PrimitiveOp::Mul, a, b)
11463    }
11464}
11465
11466impl RingOp<W16> for Add<W16> {
11467    type Operand = u16;
11468    #[inline]
11469    fn apply(a: u16, b: u16) -> u16 {
11470        const_ring_eval_w16(PrimitiveOp::Add, a, b)
11471    }
11472}
11473
11474impl RingOp<W16> for Sub<W16> {
11475    type Operand = u16;
11476    #[inline]
11477    fn apply(a: u16, b: u16) -> u16 {
11478        const_ring_eval_w16(PrimitiveOp::Sub, a, b)
11479    }
11480}
11481
11482impl RingOp<W16> for Xor<W16> {
11483    type Operand = u16;
11484    #[inline]
11485    fn apply(a: u16, b: u16) -> u16 {
11486        const_ring_eval_w16(PrimitiveOp::Xor, a, b)
11487    }
11488}
11489
11490impl RingOp<W16> for And<W16> {
11491    type Operand = u16;
11492    #[inline]
11493    fn apply(a: u16, b: u16) -> u16 {
11494        const_ring_eval_w16(PrimitiveOp::And, a, b)
11495    }
11496}
11497
11498impl RingOp<W16> for Or<W16> {
11499    type Operand = u16;
11500    #[inline]
11501    fn apply(a: u16, b: u16) -> u16 {
11502        const_ring_eval_w16(PrimitiveOp::Or, a, b)
11503    }
11504}
11505
11506impl RingOp<W24> for Mul<W24> {
11507    type Operand = u32;
11508    #[inline]
11509    fn apply(a: u32, b: u32) -> u32 {
11510        const_ring_eval_w24(PrimitiveOp::Mul, a, b)
11511    }
11512}
11513
11514impl RingOp<W24> for Add<W24> {
11515    type Operand = u32;
11516    #[inline]
11517    fn apply(a: u32, b: u32) -> u32 {
11518        const_ring_eval_w24(PrimitiveOp::Add, a, b)
11519    }
11520}
11521
11522impl RingOp<W24> for Sub<W24> {
11523    type Operand = u32;
11524    #[inline]
11525    fn apply(a: u32, b: u32) -> u32 {
11526        const_ring_eval_w24(PrimitiveOp::Sub, a, b)
11527    }
11528}
11529
11530impl RingOp<W24> for Xor<W24> {
11531    type Operand = u32;
11532    #[inline]
11533    fn apply(a: u32, b: u32) -> u32 {
11534        const_ring_eval_w24(PrimitiveOp::Xor, a, b)
11535    }
11536}
11537
11538impl RingOp<W24> for And<W24> {
11539    type Operand = u32;
11540    #[inline]
11541    fn apply(a: u32, b: u32) -> u32 {
11542        const_ring_eval_w24(PrimitiveOp::And, a, b)
11543    }
11544}
11545
11546impl RingOp<W24> for Or<W24> {
11547    type Operand = u32;
11548    #[inline]
11549    fn apply(a: u32, b: u32) -> u32 {
11550        const_ring_eval_w24(PrimitiveOp::Or, a, b)
11551    }
11552}
11553
11554impl RingOp<W32> for Mul<W32> {
11555    type Operand = u32;
11556    #[inline]
11557    fn apply(a: u32, b: u32) -> u32 {
11558        const_ring_eval_w32(PrimitiveOp::Mul, a, b)
11559    }
11560}
11561
11562impl RingOp<W32> for Add<W32> {
11563    type Operand = u32;
11564    #[inline]
11565    fn apply(a: u32, b: u32) -> u32 {
11566        const_ring_eval_w32(PrimitiveOp::Add, a, b)
11567    }
11568}
11569
11570impl RingOp<W32> for Sub<W32> {
11571    type Operand = u32;
11572    #[inline]
11573    fn apply(a: u32, b: u32) -> u32 {
11574        const_ring_eval_w32(PrimitiveOp::Sub, a, b)
11575    }
11576}
11577
11578impl RingOp<W32> for Xor<W32> {
11579    type Operand = u32;
11580    #[inline]
11581    fn apply(a: u32, b: u32) -> u32 {
11582        const_ring_eval_w32(PrimitiveOp::Xor, a, b)
11583    }
11584}
11585
11586impl RingOp<W32> for And<W32> {
11587    type Operand = u32;
11588    #[inline]
11589    fn apply(a: u32, b: u32) -> u32 {
11590        const_ring_eval_w32(PrimitiveOp::And, a, b)
11591    }
11592}
11593
11594impl RingOp<W32> for Or<W32> {
11595    type Operand = u32;
11596    #[inline]
11597    fn apply(a: u32, b: u32) -> u32 {
11598        const_ring_eval_w32(PrimitiveOp::Or, a, b)
11599    }
11600}
11601
11602impl RingOp<W40> for Mul<W40> {
11603    type Operand = u64;
11604    #[inline]
11605    fn apply(a: u64, b: u64) -> u64 {
11606        const_ring_eval_w40(PrimitiveOp::Mul, a, b)
11607    }
11608}
11609
11610impl RingOp<W40> for Add<W40> {
11611    type Operand = u64;
11612    #[inline]
11613    fn apply(a: u64, b: u64) -> u64 {
11614        const_ring_eval_w40(PrimitiveOp::Add, a, b)
11615    }
11616}
11617
11618impl RingOp<W40> for Sub<W40> {
11619    type Operand = u64;
11620    #[inline]
11621    fn apply(a: u64, b: u64) -> u64 {
11622        const_ring_eval_w40(PrimitiveOp::Sub, a, b)
11623    }
11624}
11625
11626impl RingOp<W40> for Xor<W40> {
11627    type Operand = u64;
11628    #[inline]
11629    fn apply(a: u64, b: u64) -> u64 {
11630        const_ring_eval_w40(PrimitiveOp::Xor, a, b)
11631    }
11632}
11633
11634impl RingOp<W40> for And<W40> {
11635    type Operand = u64;
11636    #[inline]
11637    fn apply(a: u64, b: u64) -> u64 {
11638        const_ring_eval_w40(PrimitiveOp::And, a, b)
11639    }
11640}
11641
11642impl RingOp<W40> for Or<W40> {
11643    type Operand = u64;
11644    #[inline]
11645    fn apply(a: u64, b: u64) -> u64 {
11646        const_ring_eval_w40(PrimitiveOp::Or, a, b)
11647    }
11648}
11649
11650impl RingOp<W48> for Mul<W48> {
11651    type Operand = u64;
11652    #[inline]
11653    fn apply(a: u64, b: u64) -> u64 {
11654        const_ring_eval_w48(PrimitiveOp::Mul, a, b)
11655    }
11656}
11657
11658impl RingOp<W48> for Add<W48> {
11659    type Operand = u64;
11660    #[inline]
11661    fn apply(a: u64, b: u64) -> u64 {
11662        const_ring_eval_w48(PrimitiveOp::Add, a, b)
11663    }
11664}
11665
11666impl RingOp<W48> for Sub<W48> {
11667    type Operand = u64;
11668    #[inline]
11669    fn apply(a: u64, b: u64) -> u64 {
11670        const_ring_eval_w48(PrimitiveOp::Sub, a, b)
11671    }
11672}
11673
11674impl RingOp<W48> for Xor<W48> {
11675    type Operand = u64;
11676    #[inline]
11677    fn apply(a: u64, b: u64) -> u64 {
11678        const_ring_eval_w48(PrimitiveOp::Xor, a, b)
11679    }
11680}
11681
11682impl RingOp<W48> for And<W48> {
11683    type Operand = u64;
11684    #[inline]
11685    fn apply(a: u64, b: u64) -> u64 {
11686        const_ring_eval_w48(PrimitiveOp::And, a, b)
11687    }
11688}
11689
11690impl RingOp<W48> for Or<W48> {
11691    type Operand = u64;
11692    #[inline]
11693    fn apply(a: u64, b: u64) -> u64 {
11694        const_ring_eval_w48(PrimitiveOp::Or, a, b)
11695    }
11696}
11697
11698impl RingOp<W56> for Mul<W56> {
11699    type Operand = u64;
11700    #[inline]
11701    fn apply(a: u64, b: u64) -> u64 {
11702        const_ring_eval_w56(PrimitiveOp::Mul, a, b)
11703    }
11704}
11705
11706impl RingOp<W56> for Add<W56> {
11707    type Operand = u64;
11708    #[inline]
11709    fn apply(a: u64, b: u64) -> u64 {
11710        const_ring_eval_w56(PrimitiveOp::Add, a, b)
11711    }
11712}
11713
11714impl RingOp<W56> for Sub<W56> {
11715    type Operand = u64;
11716    #[inline]
11717    fn apply(a: u64, b: u64) -> u64 {
11718        const_ring_eval_w56(PrimitiveOp::Sub, a, b)
11719    }
11720}
11721
11722impl RingOp<W56> for Xor<W56> {
11723    type Operand = u64;
11724    #[inline]
11725    fn apply(a: u64, b: u64) -> u64 {
11726        const_ring_eval_w56(PrimitiveOp::Xor, a, b)
11727    }
11728}
11729
11730impl RingOp<W56> for And<W56> {
11731    type Operand = u64;
11732    #[inline]
11733    fn apply(a: u64, b: u64) -> u64 {
11734        const_ring_eval_w56(PrimitiveOp::And, a, b)
11735    }
11736}
11737
11738impl RingOp<W56> for Or<W56> {
11739    type Operand = u64;
11740    #[inline]
11741    fn apply(a: u64, b: u64) -> u64 {
11742        const_ring_eval_w56(PrimitiveOp::Or, a, b)
11743    }
11744}
11745
11746impl RingOp<W64> for Mul<W64> {
11747    type Operand = u64;
11748    #[inline]
11749    fn apply(a: u64, b: u64) -> u64 {
11750        const_ring_eval_w64(PrimitiveOp::Mul, a, b)
11751    }
11752}
11753
11754impl RingOp<W64> for Add<W64> {
11755    type Operand = u64;
11756    #[inline]
11757    fn apply(a: u64, b: u64) -> u64 {
11758        const_ring_eval_w64(PrimitiveOp::Add, a, b)
11759    }
11760}
11761
11762impl RingOp<W64> for Sub<W64> {
11763    type Operand = u64;
11764    #[inline]
11765    fn apply(a: u64, b: u64) -> u64 {
11766        const_ring_eval_w64(PrimitiveOp::Sub, a, b)
11767    }
11768}
11769
11770impl RingOp<W64> for Xor<W64> {
11771    type Operand = u64;
11772    #[inline]
11773    fn apply(a: u64, b: u64) -> u64 {
11774        const_ring_eval_w64(PrimitiveOp::Xor, a, b)
11775    }
11776}
11777
11778impl RingOp<W64> for And<W64> {
11779    type Operand = u64;
11780    #[inline]
11781    fn apply(a: u64, b: u64) -> u64 {
11782        const_ring_eval_w64(PrimitiveOp::And, a, b)
11783    }
11784}
11785
11786impl RingOp<W64> for Or<W64> {
11787    type Operand = u64;
11788    #[inline]
11789    fn apply(a: u64, b: u64) -> u64 {
11790        const_ring_eval_w64(PrimitiveOp::Or, a, b)
11791    }
11792}
11793
11794impl RingOp<W72> for Mul<W72> {
11795    type Operand = u128;
11796    #[inline]
11797    fn apply(a: u128, b: u128) -> u128 {
11798        const_ring_eval_w72(PrimitiveOp::Mul, a, b)
11799    }
11800}
11801
11802impl RingOp<W72> for Add<W72> {
11803    type Operand = u128;
11804    #[inline]
11805    fn apply(a: u128, b: u128) -> u128 {
11806        const_ring_eval_w72(PrimitiveOp::Add, a, b)
11807    }
11808}
11809
11810impl RingOp<W72> for Sub<W72> {
11811    type Operand = u128;
11812    #[inline]
11813    fn apply(a: u128, b: u128) -> u128 {
11814        const_ring_eval_w72(PrimitiveOp::Sub, a, b)
11815    }
11816}
11817
11818impl RingOp<W72> for Xor<W72> {
11819    type Operand = u128;
11820    #[inline]
11821    fn apply(a: u128, b: u128) -> u128 {
11822        const_ring_eval_w72(PrimitiveOp::Xor, a, b)
11823    }
11824}
11825
11826impl RingOp<W72> for And<W72> {
11827    type Operand = u128;
11828    #[inline]
11829    fn apply(a: u128, b: u128) -> u128 {
11830        const_ring_eval_w72(PrimitiveOp::And, a, b)
11831    }
11832}
11833
11834impl RingOp<W72> for Or<W72> {
11835    type Operand = u128;
11836    #[inline]
11837    fn apply(a: u128, b: u128) -> u128 {
11838        const_ring_eval_w72(PrimitiveOp::Or, a, b)
11839    }
11840}
11841
11842impl RingOp<W80> for Mul<W80> {
11843    type Operand = u128;
11844    #[inline]
11845    fn apply(a: u128, b: u128) -> u128 {
11846        const_ring_eval_w80(PrimitiveOp::Mul, a, b)
11847    }
11848}
11849
11850impl RingOp<W80> for Add<W80> {
11851    type Operand = u128;
11852    #[inline]
11853    fn apply(a: u128, b: u128) -> u128 {
11854        const_ring_eval_w80(PrimitiveOp::Add, a, b)
11855    }
11856}
11857
11858impl RingOp<W80> for Sub<W80> {
11859    type Operand = u128;
11860    #[inline]
11861    fn apply(a: u128, b: u128) -> u128 {
11862        const_ring_eval_w80(PrimitiveOp::Sub, a, b)
11863    }
11864}
11865
11866impl RingOp<W80> for Xor<W80> {
11867    type Operand = u128;
11868    #[inline]
11869    fn apply(a: u128, b: u128) -> u128 {
11870        const_ring_eval_w80(PrimitiveOp::Xor, a, b)
11871    }
11872}
11873
11874impl RingOp<W80> for And<W80> {
11875    type Operand = u128;
11876    #[inline]
11877    fn apply(a: u128, b: u128) -> u128 {
11878        const_ring_eval_w80(PrimitiveOp::And, a, b)
11879    }
11880}
11881
11882impl RingOp<W80> for Or<W80> {
11883    type Operand = u128;
11884    #[inline]
11885    fn apply(a: u128, b: u128) -> u128 {
11886        const_ring_eval_w80(PrimitiveOp::Or, a, b)
11887    }
11888}
11889
11890impl RingOp<W88> for Mul<W88> {
11891    type Operand = u128;
11892    #[inline]
11893    fn apply(a: u128, b: u128) -> u128 {
11894        const_ring_eval_w88(PrimitiveOp::Mul, a, b)
11895    }
11896}
11897
11898impl RingOp<W88> for Add<W88> {
11899    type Operand = u128;
11900    #[inline]
11901    fn apply(a: u128, b: u128) -> u128 {
11902        const_ring_eval_w88(PrimitiveOp::Add, a, b)
11903    }
11904}
11905
11906impl RingOp<W88> for Sub<W88> {
11907    type Operand = u128;
11908    #[inline]
11909    fn apply(a: u128, b: u128) -> u128 {
11910        const_ring_eval_w88(PrimitiveOp::Sub, a, b)
11911    }
11912}
11913
11914impl RingOp<W88> for Xor<W88> {
11915    type Operand = u128;
11916    #[inline]
11917    fn apply(a: u128, b: u128) -> u128 {
11918        const_ring_eval_w88(PrimitiveOp::Xor, a, b)
11919    }
11920}
11921
11922impl RingOp<W88> for And<W88> {
11923    type Operand = u128;
11924    #[inline]
11925    fn apply(a: u128, b: u128) -> u128 {
11926        const_ring_eval_w88(PrimitiveOp::And, a, b)
11927    }
11928}
11929
11930impl RingOp<W88> for Or<W88> {
11931    type Operand = u128;
11932    #[inline]
11933    fn apply(a: u128, b: u128) -> u128 {
11934        const_ring_eval_w88(PrimitiveOp::Or, a, b)
11935    }
11936}
11937
11938impl RingOp<W96> for Mul<W96> {
11939    type Operand = u128;
11940    #[inline]
11941    fn apply(a: u128, b: u128) -> u128 {
11942        const_ring_eval_w96(PrimitiveOp::Mul, a, b)
11943    }
11944}
11945
11946impl RingOp<W96> for Add<W96> {
11947    type Operand = u128;
11948    #[inline]
11949    fn apply(a: u128, b: u128) -> u128 {
11950        const_ring_eval_w96(PrimitiveOp::Add, a, b)
11951    }
11952}
11953
11954impl RingOp<W96> for Sub<W96> {
11955    type Operand = u128;
11956    #[inline]
11957    fn apply(a: u128, b: u128) -> u128 {
11958        const_ring_eval_w96(PrimitiveOp::Sub, a, b)
11959    }
11960}
11961
11962impl RingOp<W96> for Xor<W96> {
11963    type Operand = u128;
11964    #[inline]
11965    fn apply(a: u128, b: u128) -> u128 {
11966        const_ring_eval_w96(PrimitiveOp::Xor, a, b)
11967    }
11968}
11969
11970impl RingOp<W96> for And<W96> {
11971    type Operand = u128;
11972    #[inline]
11973    fn apply(a: u128, b: u128) -> u128 {
11974        const_ring_eval_w96(PrimitiveOp::And, a, b)
11975    }
11976}
11977
11978impl RingOp<W96> for Or<W96> {
11979    type Operand = u128;
11980    #[inline]
11981    fn apply(a: u128, b: u128) -> u128 {
11982        const_ring_eval_w96(PrimitiveOp::Or, a, b)
11983    }
11984}
11985
11986impl RingOp<W104> for Mul<W104> {
11987    type Operand = u128;
11988    #[inline]
11989    fn apply(a: u128, b: u128) -> u128 {
11990        const_ring_eval_w104(PrimitiveOp::Mul, a, b)
11991    }
11992}
11993
11994impl RingOp<W104> for Add<W104> {
11995    type Operand = u128;
11996    #[inline]
11997    fn apply(a: u128, b: u128) -> u128 {
11998        const_ring_eval_w104(PrimitiveOp::Add, a, b)
11999    }
12000}
12001
12002impl RingOp<W104> for Sub<W104> {
12003    type Operand = u128;
12004    #[inline]
12005    fn apply(a: u128, b: u128) -> u128 {
12006        const_ring_eval_w104(PrimitiveOp::Sub, a, b)
12007    }
12008}
12009
12010impl RingOp<W104> for Xor<W104> {
12011    type Operand = u128;
12012    #[inline]
12013    fn apply(a: u128, b: u128) -> u128 {
12014        const_ring_eval_w104(PrimitiveOp::Xor, a, b)
12015    }
12016}
12017
12018impl RingOp<W104> for And<W104> {
12019    type Operand = u128;
12020    #[inline]
12021    fn apply(a: u128, b: u128) -> u128 {
12022        const_ring_eval_w104(PrimitiveOp::And, a, b)
12023    }
12024}
12025
12026impl RingOp<W104> for Or<W104> {
12027    type Operand = u128;
12028    #[inline]
12029    fn apply(a: u128, b: u128) -> u128 {
12030        const_ring_eval_w104(PrimitiveOp::Or, a, b)
12031    }
12032}
12033
12034impl RingOp<W112> for Mul<W112> {
12035    type Operand = u128;
12036    #[inline]
12037    fn apply(a: u128, b: u128) -> u128 {
12038        const_ring_eval_w112(PrimitiveOp::Mul, a, b)
12039    }
12040}
12041
12042impl RingOp<W112> for Add<W112> {
12043    type Operand = u128;
12044    #[inline]
12045    fn apply(a: u128, b: u128) -> u128 {
12046        const_ring_eval_w112(PrimitiveOp::Add, a, b)
12047    }
12048}
12049
12050impl RingOp<W112> for Sub<W112> {
12051    type Operand = u128;
12052    #[inline]
12053    fn apply(a: u128, b: u128) -> u128 {
12054        const_ring_eval_w112(PrimitiveOp::Sub, a, b)
12055    }
12056}
12057
12058impl RingOp<W112> for Xor<W112> {
12059    type Operand = u128;
12060    #[inline]
12061    fn apply(a: u128, b: u128) -> u128 {
12062        const_ring_eval_w112(PrimitiveOp::Xor, a, b)
12063    }
12064}
12065
12066impl RingOp<W112> for And<W112> {
12067    type Operand = u128;
12068    #[inline]
12069    fn apply(a: u128, b: u128) -> u128 {
12070        const_ring_eval_w112(PrimitiveOp::And, a, b)
12071    }
12072}
12073
12074impl RingOp<W112> for Or<W112> {
12075    type Operand = u128;
12076    #[inline]
12077    fn apply(a: u128, b: u128) -> u128 {
12078        const_ring_eval_w112(PrimitiveOp::Or, a, b)
12079    }
12080}
12081
12082impl RingOp<W120> for Mul<W120> {
12083    type Operand = u128;
12084    #[inline]
12085    fn apply(a: u128, b: u128) -> u128 {
12086        const_ring_eval_w120(PrimitiveOp::Mul, a, b)
12087    }
12088}
12089
12090impl RingOp<W120> for Add<W120> {
12091    type Operand = u128;
12092    #[inline]
12093    fn apply(a: u128, b: u128) -> u128 {
12094        const_ring_eval_w120(PrimitiveOp::Add, a, b)
12095    }
12096}
12097
12098impl RingOp<W120> for Sub<W120> {
12099    type Operand = u128;
12100    #[inline]
12101    fn apply(a: u128, b: u128) -> u128 {
12102        const_ring_eval_w120(PrimitiveOp::Sub, a, b)
12103    }
12104}
12105
12106impl RingOp<W120> for Xor<W120> {
12107    type Operand = u128;
12108    #[inline]
12109    fn apply(a: u128, b: u128) -> u128 {
12110        const_ring_eval_w120(PrimitiveOp::Xor, a, b)
12111    }
12112}
12113
12114impl RingOp<W120> for And<W120> {
12115    type Operand = u128;
12116    #[inline]
12117    fn apply(a: u128, b: u128) -> u128 {
12118        const_ring_eval_w120(PrimitiveOp::And, a, b)
12119    }
12120}
12121
12122impl RingOp<W120> for Or<W120> {
12123    type Operand = u128;
12124    #[inline]
12125    fn apply(a: u128, b: u128) -> u128 {
12126        const_ring_eval_w120(PrimitiveOp::Or, a, b)
12127    }
12128}
12129
12130impl RingOp<W128> for Mul<W128> {
12131    type Operand = u128;
12132    #[inline]
12133    fn apply(a: u128, b: u128) -> u128 {
12134        const_ring_eval_w128(PrimitiveOp::Mul, a, b)
12135    }
12136}
12137
12138impl RingOp<W128> for Add<W128> {
12139    type Operand = u128;
12140    #[inline]
12141    fn apply(a: u128, b: u128) -> u128 {
12142        const_ring_eval_w128(PrimitiveOp::Add, a, b)
12143    }
12144}
12145
12146impl RingOp<W128> for Sub<W128> {
12147    type Operand = u128;
12148    #[inline]
12149    fn apply(a: u128, b: u128) -> u128 {
12150        const_ring_eval_w128(PrimitiveOp::Sub, a, b)
12151    }
12152}
12153
12154impl RingOp<W128> for Xor<W128> {
12155    type Operand = u128;
12156    #[inline]
12157    fn apply(a: u128, b: u128) -> u128 {
12158        const_ring_eval_w128(PrimitiveOp::Xor, a, b)
12159    }
12160}
12161
12162impl RingOp<W128> for And<W128> {
12163    type Operand = u128;
12164    #[inline]
12165    fn apply(a: u128, b: u128) -> u128 {
12166        const_ring_eval_w128(PrimitiveOp::And, a, b)
12167    }
12168}
12169
12170impl RingOp<W128> for Or<W128> {
12171    type Operand = u128;
12172    #[inline]
12173    fn apply(a: u128, b: u128) -> u128 {
12174        const_ring_eval_w128(PrimitiveOp::Or, a, b)
12175    }
12176}
12177
12178impl UnaryRingOp<W8> for Neg<W8> {
12179    type Operand = u8;
12180    #[inline]
12181    fn apply(a: u8) -> u8 {
12182        const_ring_eval_w8(PrimitiveOp::Sub, 0, a)
12183    }
12184}
12185
12186impl UnaryRingOp<W8> for BNot<W8> {
12187    type Operand = u8;
12188    #[inline]
12189    fn apply(a: u8) -> u8 {
12190        const_ring_eval_w8(PrimitiveOp::Xor, a, u8::MAX)
12191    }
12192}
12193
12194impl UnaryRingOp<W8> for Succ<W8> {
12195    type Operand = u8;
12196    #[inline]
12197    fn apply(a: u8) -> u8 {
12198        <Neg<W8> as UnaryRingOp<W8>>::apply(<BNot<W8> as UnaryRingOp<W8>>::apply(a))
12199    }
12200}
12201
12202impl UnaryRingOp<W16> for Neg<W16> {
12203    type Operand = u16;
12204    #[inline]
12205    fn apply(a: u16) -> u16 {
12206        const_ring_eval_w16(PrimitiveOp::Sub, 0, a)
12207    }
12208}
12209
12210impl UnaryRingOp<W16> for BNot<W16> {
12211    type Operand = u16;
12212    #[inline]
12213    fn apply(a: u16) -> u16 {
12214        const_ring_eval_w16(PrimitiveOp::Xor, a, u16::MAX)
12215    }
12216}
12217
12218impl UnaryRingOp<W16> for Succ<W16> {
12219    type Operand = u16;
12220    #[inline]
12221    fn apply(a: u16) -> u16 {
12222        <Neg<W16> as UnaryRingOp<W16>>::apply(<BNot<W16> as UnaryRingOp<W16>>::apply(a))
12223    }
12224}
12225
12226impl UnaryRingOp<W24> for Neg<W24> {
12227    type Operand = u32;
12228    #[inline]
12229    fn apply(a: u32) -> u32 {
12230        const_ring_eval_w24(PrimitiveOp::Sub, 0, a)
12231    }
12232}
12233
12234impl UnaryRingOp<W24> for BNot<W24> {
12235    type Operand = u32;
12236    #[inline]
12237    fn apply(a: u32) -> u32 {
12238        const_ring_eval_w24(PrimitiveOp::Xor, a, 0x00FF_FFFFu32)
12239    }
12240}
12241
12242impl UnaryRingOp<W24> for Succ<W24> {
12243    type Operand = u32;
12244    #[inline]
12245    fn apply(a: u32) -> u32 {
12246        <Neg<W24> as UnaryRingOp<W24>>::apply(<BNot<W24> as UnaryRingOp<W24>>::apply(a))
12247    }
12248}
12249
12250impl UnaryRingOp<W32> for Neg<W32> {
12251    type Operand = u32;
12252    #[inline]
12253    fn apply(a: u32) -> u32 {
12254        const_ring_eval_w32(PrimitiveOp::Sub, 0, a)
12255    }
12256}
12257
12258impl UnaryRingOp<W32> for BNot<W32> {
12259    type Operand = u32;
12260    #[inline]
12261    fn apply(a: u32) -> u32 {
12262        const_ring_eval_w32(PrimitiveOp::Xor, a, u32::MAX)
12263    }
12264}
12265
12266impl UnaryRingOp<W32> for Succ<W32> {
12267    type Operand = u32;
12268    #[inline]
12269    fn apply(a: u32) -> u32 {
12270        <Neg<W32> as UnaryRingOp<W32>>::apply(<BNot<W32> as UnaryRingOp<W32>>::apply(a))
12271    }
12272}
12273
12274impl UnaryRingOp<W40> for Neg<W40> {
12275    type Operand = u64;
12276    #[inline]
12277    fn apply(a: u64) -> u64 {
12278        const_ring_eval_w40(PrimitiveOp::Sub, 0, a)
12279    }
12280}
12281
12282impl UnaryRingOp<W40> for BNot<W40> {
12283    type Operand = u64;
12284    #[inline]
12285    fn apply(a: u64) -> u64 {
12286        const_ring_eval_w40(PrimitiveOp::Xor, a, 0x0000_00FF_FFFF_FFFFu64)
12287    }
12288}
12289
12290impl UnaryRingOp<W40> for Succ<W40> {
12291    type Operand = u64;
12292    #[inline]
12293    fn apply(a: u64) -> u64 {
12294        <Neg<W40> as UnaryRingOp<W40>>::apply(<BNot<W40> as UnaryRingOp<W40>>::apply(a))
12295    }
12296}
12297
12298impl UnaryRingOp<W48> for Neg<W48> {
12299    type Operand = u64;
12300    #[inline]
12301    fn apply(a: u64) -> u64 {
12302        const_ring_eval_w48(PrimitiveOp::Sub, 0, a)
12303    }
12304}
12305
12306impl UnaryRingOp<W48> for BNot<W48> {
12307    type Operand = u64;
12308    #[inline]
12309    fn apply(a: u64) -> u64 {
12310        const_ring_eval_w48(PrimitiveOp::Xor, a, 0x0000_FFFF_FFFF_FFFFu64)
12311    }
12312}
12313
12314impl UnaryRingOp<W48> for Succ<W48> {
12315    type Operand = u64;
12316    #[inline]
12317    fn apply(a: u64) -> u64 {
12318        <Neg<W48> as UnaryRingOp<W48>>::apply(<BNot<W48> as UnaryRingOp<W48>>::apply(a))
12319    }
12320}
12321
12322impl UnaryRingOp<W56> for Neg<W56> {
12323    type Operand = u64;
12324    #[inline]
12325    fn apply(a: u64) -> u64 {
12326        const_ring_eval_w56(PrimitiveOp::Sub, 0, a)
12327    }
12328}
12329
12330impl UnaryRingOp<W56> for BNot<W56> {
12331    type Operand = u64;
12332    #[inline]
12333    fn apply(a: u64) -> u64 {
12334        const_ring_eval_w56(PrimitiveOp::Xor, a, 0x00FF_FFFF_FFFF_FFFFu64)
12335    }
12336}
12337
12338impl UnaryRingOp<W56> for Succ<W56> {
12339    type Operand = u64;
12340    #[inline]
12341    fn apply(a: u64) -> u64 {
12342        <Neg<W56> as UnaryRingOp<W56>>::apply(<BNot<W56> as UnaryRingOp<W56>>::apply(a))
12343    }
12344}
12345
12346impl UnaryRingOp<W64> for Neg<W64> {
12347    type Operand = u64;
12348    #[inline]
12349    fn apply(a: u64) -> u64 {
12350        const_ring_eval_w64(PrimitiveOp::Sub, 0, a)
12351    }
12352}
12353
12354impl UnaryRingOp<W64> for BNot<W64> {
12355    type Operand = u64;
12356    #[inline]
12357    fn apply(a: u64) -> u64 {
12358        const_ring_eval_w64(PrimitiveOp::Xor, a, u64::MAX)
12359    }
12360}
12361
12362impl UnaryRingOp<W64> for Succ<W64> {
12363    type Operand = u64;
12364    #[inline]
12365    fn apply(a: u64) -> u64 {
12366        <Neg<W64> as UnaryRingOp<W64>>::apply(<BNot<W64> as UnaryRingOp<W64>>::apply(a))
12367    }
12368}
12369
12370impl UnaryRingOp<W72> for Neg<W72> {
12371    type Operand = u128;
12372    #[inline]
12373    fn apply(a: u128) -> u128 {
12374        const_ring_eval_w72(PrimitiveOp::Sub, 0, a)
12375    }
12376}
12377
12378impl UnaryRingOp<W72> for BNot<W72> {
12379    type Operand = u128;
12380    #[inline]
12381    fn apply(a: u128) -> u128 {
12382        const_ring_eval_w72(PrimitiveOp::Xor, a, u128::MAX >> (128 - 72))
12383    }
12384}
12385
12386impl UnaryRingOp<W72> for Succ<W72> {
12387    type Operand = u128;
12388    #[inline]
12389    fn apply(a: u128) -> u128 {
12390        <Neg<W72> as UnaryRingOp<W72>>::apply(<BNot<W72> as UnaryRingOp<W72>>::apply(a))
12391    }
12392}
12393
12394impl UnaryRingOp<W80> for Neg<W80> {
12395    type Operand = u128;
12396    #[inline]
12397    fn apply(a: u128) -> u128 {
12398        const_ring_eval_w80(PrimitiveOp::Sub, 0, a)
12399    }
12400}
12401
12402impl UnaryRingOp<W80> for BNot<W80> {
12403    type Operand = u128;
12404    #[inline]
12405    fn apply(a: u128) -> u128 {
12406        const_ring_eval_w80(PrimitiveOp::Xor, a, u128::MAX >> (128 - 80))
12407    }
12408}
12409
12410impl UnaryRingOp<W80> for Succ<W80> {
12411    type Operand = u128;
12412    #[inline]
12413    fn apply(a: u128) -> u128 {
12414        <Neg<W80> as UnaryRingOp<W80>>::apply(<BNot<W80> as UnaryRingOp<W80>>::apply(a))
12415    }
12416}
12417
12418impl UnaryRingOp<W88> for Neg<W88> {
12419    type Operand = u128;
12420    #[inline]
12421    fn apply(a: u128) -> u128 {
12422        const_ring_eval_w88(PrimitiveOp::Sub, 0, a)
12423    }
12424}
12425
12426impl UnaryRingOp<W88> for BNot<W88> {
12427    type Operand = u128;
12428    #[inline]
12429    fn apply(a: u128) -> u128 {
12430        const_ring_eval_w88(PrimitiveOp::Xor, a, u128::MAX >> (128 - 88))
12431    }
12432}
12433
12434impl UnaryRingOp<W88> for Succ<W88> {
12435    type Operand = u128;
12436    #[inline]
12437    fn apply(a: u128) -> u128 {
12438        <Neg<W88> as UnaryRingOp<W88>>::apply(<BNot<W88> as UnaryRingOp<W88>>::apply(a))
12439    }
12440}
12441
12442impl UnaryRingOp<W96> for Neg<W96> {
12443    type Operand = u128;
12444    #[inline]
12445    fn apply(a: u128) -> u128 {
12446        const_ring_eval_w96(PrimitiveOp::Sub, 0, a)
12447    }
12448}
12449
12450impl UnaryRingOp<W96> for BNot<W96> {
12451    type Operand = u128;
12452    #[inline]
12453    fn apply(a: u128) -> u128 {
12454        const_ring_eval_w96(PrimitiveOp::Xor, a, u128::MAX >> (128 - 96))
12455    }
12456}
12457
12458impl UnaryRingOp<W96> for Succ<W96> {
12459    type Operand = u128;
12460    #[inline]
12461    fn apply(a: u128) -> u128 {
12462        <Neg<W96> as UnaryRingOp<W96>>::apply(<BNot<W96> as UnaryRingOp<W96>>::apply(a))
12463    }
12464}
12465
12466impl UnaryRingOp<W104> for Neg<W104> {
12467    type Operand = u128;
12468    #[inline]
12469    fn apply(a: u128) -> u128 {
12470        const_ring_eval_w104(PrimitiveOp::Sub, 0, a)
12471    }
12472}
12473
12474impl UnaryRingOp<W104> for BNot<W104> {
12475    type Operand = u128;
12476    #[inline]
12477    fn apply(a: u128) -> u128 {
12478        const_ring_eval_w104(PrimitiveOp::Xor, a, u128::MAX >> (128 - 104))
12479    }
12480}
12481
12482impl UnaryRingOp<W104> for Succ<W104> {
12483    type Operand = u128;
12484    #[inline]
12485    fn apply(a: u128) -> u128 {
12486        <Neg<W104> as UnaryRingOp<W104>>::apply(<BNot<W104> as UnaryRingOp<W104>>::apply(a))
12487    }
12488}
12489
12490impl UnaryRingOp<W112> for Neg<W112> {
12491    type Operand = u128;
12492    #[inline]
12493    fn apply(a: u128) -> u128 {
12494        const_ring_eval_w112(PrimitiveOp::Sub, 0, a)
12495    }
12496}
12497
12498impl UnaryRingOp<W112> for BNot<W112> {
12499    type Operand = u128;
12500    #[inline]
12501    fn apply(a: u128) -> u128 {
12502        const_ring_eval_w112(PrimitiveOp::Xor, a, u128::MAX >> (128 - 112))
12503    }
12504}
12505
12506impl UnaryRingOp<W112> for Succ<W112> {
12507    type Operand = u128;
12508    #[inline]
12509    fn apply(a: u128) -> u128 {
12510        <Neg<W112> as UnaryRingOp<W112>>::apply(<BNot<W112> as UnaryRingOp<W112>>::apply(a))
12511    }
12512}
12513
12514impl UnaryRingOp<W120> for Neg<W120> {
12515    type Operand = u128;
12516    #[inline]
12517    fn apply(a: u128) -> u128 {
12518        const_ring_eval_w120(PrimitiveOp::Sub, 0, a)
12519    }
12520}
12521
12522impl UnaryRingOp<W120> for BNot<W120> {
12523    type Operand = u128;
12524    #[inline]
12525    fn apply(a: u128) -> u128 {
12526        const_ring_eval_w120(PrimitiveOp::Xor, a, u128::MAX >> (128 - 120))
12527    }
12528}
12529
12530impl UnaryRingOp<W120> for Succ<W120> {
12531    type Operand = u128;
12532    #[inline]
12533    fn apply(a: u128) -> u128 {
12534        <Neg<W120> as UnaryRingOp<W120>>::apply(<BNot<W120> as UnaryRingOp<W120>>::apply(a))
12535    }
12536}
12537
12538impl UnaryRingOp<W128> for Neg<W128> {
12539    type Operand = u128;
12540    #[inline]
12541    fn apply(a: u128) -> u128 {
12542        const_ring_eval_w128(PrimitiveOp::Sub, 0, a)
12543    }
12544}
12545
12546impl UnaryRingOp<W128> for BNot<W128> {
12547    type Operand = u128;
12548    #[inline]
12549    fn apply(a: u128) -> u128 {
12550        const_ring_eval_w128(PrimitiveOp::Xor, a, u128::MAX)
12551    }
12552}
12553
12554impl UnaryRingOp<W128> for Succ<W128> {
12555    type Operand = u128;
12556    #[inline]
12557    fn apply(a: u128) -> u128 {
12558        <Neg<W128> as UnaryRingOp<W128>>::apply(<BNot<W128> as UnaryRingOp<W128>>::apply(a))
12559    }
12560}
12561
12562/// Sealed marker for well-formed level embedding pairs (`(From, To)` with
12563/// `From <= To`). v0.2.2 W3.
12564pub trait ValidLevelEmbedding: valid_level_embedding_sealed::Sealed {}
12565
12566mod valid_level_embedding_sealed {
12567    /// Private supertrait. Not implementable outside this crate.
12568    pub trait Sealed {}
12569    impl Sealed for (super::W8, super::W8) {}
12570    impl Sealed for (super::W8, super::W16) {}
12571    impl Sealed for (super::W8, super::W24) {}
12572    impl Sealed for (super::W8, super::W32) {}
12573    impl Sealed for (super::W8, super::W40) {}
12574    impl Sealed for (super::W8, super::W48) {}
12575    impl Sealed for (super::W8, super::W56) {}
12576    impl Sealed for (super::W8, super::W64) {}
12577    impl Sealed for (super::W8, super::W72) {}
12578    impl Sealed for (super::W8, super::W80) {}
12579    impl Sealed for (super::W8, super::W88) {}
12580    impl Sealed for (super::W8, super::W96) {}
12581    impl Sealed for (super::W8, super::W104) {}
12582    impl Sealed for (super::W8, super::W112) {}
12583    impl Sealed for (super::W8, super::W120) {}
12584    impl Sealed for (super::W8, super::W128) {}
12585    impl Sealed for (super::W16, super::W16) {}
12586    impl Sealed for (super::W16, super::W24) {}
12587    impl Sealed for (super::W16, super::W32) {}
12588    impl Sealed for (super::W16, super::W40) {}
12589    impl Sealed for (super::W16, super::W48) {}
12590    impl Sealed for (super::W16, super::W56) {}
12591    impl Sealed for (super::W16, super::W64) {}
12592    impl Sealed for (super::W16, super::W72) {}
12593    impl Sealed for (super::W16, super::W80) {}
12594    impl Sealed for (super::W16, super::W88) {}
12595    impl Sealed for (super::W16, super::W96) {}
12596    impl Sealed for (super::W16, super::W104) {}
12597    impl Sealed for (super::W16, super::W112) {}
12598    impl Sealed for (super::W16, super::W120) {}
12599    impl Sealed for (super::W16, super::W128) {}
12600    impl Sealed for (super::W24, super::W24) {}
12601    impl Sealed for (super::W24, super::W32) {}
12602    impl Sealed for (super::W24, super::W40) {}
12603    impl Sealed for (super::W24, super::W48) {}
12604    impl Sealed for (super::W24, super::W56) {}
12605    impl Sealed for (super::W24, super::W64) {}
12606    impl Sealed for (super::W24, super::W72) {}
12607    impl Sealed for (super::W24, super::W80) {}
12608    impl Sealed for (super::W24, super::W88) {}
12609    impl Sealed for (super::W24, super::W96) {}
12610    impl Sealed for (super::W24, super::W104) {}
12611    impl Sealed for (super::W24, super::W112) {}
12612    impl Sealed for (super::W24, super::W120) {}
12613    impl Sealed for (super::W24, super::W128) {}
12614    impl Sealed for (super::W32, super::W32) {}
12615    impl Sealed for (super::W32, super::W40) {}
12616    impl Sealed for (super::W32, super::W48) {}
12617    impl Sealed for (super::W32, super::W56) {}
12618    impl Sealed for (super::W32, super::W64) {}
12619    impl Sealed for (super::W32, super::W72) {}
12620    impl Sealed for (super::W32, super::W80) {}
12621    impl Sealed for (super::W32, super::W88) {}
12622    impl Sealed for (super::W32, super::W96) {}
12623    impl Sealed for (super::W32, super::W104) {}
12624    impl Sealed for (super::W32, super::W112) {}
12625    impl Sealed for (super::W32, super::W120) {}
12626    impl Sealed for (super::W32, super::W128) {}
12627    impl Sealed for (super::W40, super::W40) {}
12628    impl Sealed for (super::W40, super::W48) {}
12629    impl Sealed for (super::W40, super::W56) {}
12630    impl Sealed for (super::W40, super::W64) {}
12631    impl Sealed for (super::W40, super::W72) {}
12632    impl Sealed for (super::W40, super::W80) {}
12633    impl Sealed for (super::W40, super::W88) {}
12634    impl Sealed for (super::W40, super::W96) {}
12635    impl Sealed for (super::W40, super::W104) {}
12636    impl Sealed for (super::W40, super::W112) {}
12637    impl Sealed for (super::W40, super::W120) {}
12638    impl Sealed for (super::W40, super::W128) {}
12639    impl Sealed for (super::W48, super::W48) {}
12640    impl Sealed for (super::W48, super::W56) {}
12641    impl Sealed for (super::W48, super::W64) {}
12642    impl Sealed for (super::W48, super::W72) {}
12643    impl Sealed for (super::W48, super::W80) {}
12644    impl Sealed for (super::W48, super::W88) {}
12645    impl Sealed for (super::W48, super::W96) {}
12646    impl Sealed for (super::W48, super::W104) {}
12647    impl Sealed for (super::W48, super::W112) {}
12648    impl Sealed for (super::W48, super::W120) {}
12649    impl Sealed for (super::W48, super::W128) {}
12650    impl Sealed for (super::W56, super::W56) {}
12651    impl Sealed for (super::W56, super::W64) {}
12652    impl Sealed for (super::W56, super::W72) {}
12653    impl Sealed for (super::W56, super::W80) {}
12654    impl Sealed for (super::W56, super::W88) {}
12655    impl Sealed for (super::W56, super::W96) {}
12656    impl Sealed for (super::W56, super::W104) {}
12657    impl Sealed for (super::W56, super::W112) {}
12658    impl Sealed for (super::W56, super::W120) {}
12659    impl Sealed for (super::W56, super::W128) {}
12660    impl Sealed for (super::W64, super::W64) {}
12661    impl Sealed for (super::W64, super::W72) {}
12662    impl Sealed for (super::W64, super::W80) {}
12663    impl Sealed for (super::W64, super::W88) {}
12664    impl Sealed for (super::W64, super::W96) {}
12665    impl Sealed for (super::W64, super::W104) {}
12666    impl Sealed for (super::W64, super::W112) {}
12667    impl Sealed for (super::W64, super::W120) {}
12668    impl Sealed for (super::W64, super::W128) {}
12669    impl Sealed for (super::W72, super::W72) {}
12670    impl Sealed for (super::W72, super::W80) {}
12671    impl Sealed for (super::W72, super::W88) {}
12672    impl Sealed for (super::W72, super::W96) {}
12673    impl Sealed for (super::W72, super::W104) {}
12674    impl Sealed for (super::W72, super::W112) {}
12675    impl Sealed for (super::W72, super::W120) {}
12676    impl Sealed for (super::W72, super::W128) {}
12677    impl Sealed for (super::W80, super::W80) {}
12678    impl Sealed for (super::W80, super::W88) {}
12679    impl Sealed for (super::W80, super::W96) {}
12680    impl Sealed for (super::W80, super::W104) {}
12681    impl Sealed for (super::W80, super::W112) {}
12682    impl Sealed for (super::W80, super::W120) {}
12683    impl Sealed for (super::W80, super::W128) {}
12684    impl Sealed for (super::W88, super::W88) {}
12685    impl Sealed for (super::W88, super::W96) {}
12686    impl Sealed for (super::W88, super::W104) {}
12687    impl Sealed for (super::W88, super::W112) {}
12688    impl Sealed for (super::W88, super::W120) {}
12689    impl Sealed for (super::W88, super::W128) {}
12690    impl Sealed for (super::W96, super::W96) {}
12691    impl Sealed for (super::W96, super::W104) {}
12692    impl Sealed for (super::W96, super::W112) {}
12693    impl Sealed for (super::W96, super::W120) {}
12694    impl Sealed for (super::W96, super::W128) {}
12695    impl Sealed for (super::W104, super::W104) {}
12696    impl Sealed for (super::W104, super::W112) {}
12697    impl Sealed for (super::W104, super::W120) {}
12698    impl Sealed for (super::W104, super::W128) {}
12699    impl Sealed for (super::W112, super::W112) {}
12700    impl Sealed for (super::W112, super::W120) {}
12701    impl Sealed for (super::W112, super::W128) {}
12702    impl Sealed for (super::W120, super::W120) {}
12703    impl Sealed for (super::W120, super::W128) {}
12704    impl Sealed for (super::W128, super::W128) {}
12705}
12706
12707impl ValidLevelEmbedding for (W8, W8) {}
12708impl ValidLevelEmbedding for (W8, W16) {}
12709impl ValidLevelEmbedding for (W8, W24) {}
12710impl ValidLevelEmbedding for (W8, W32) {}
12711impl ValidLevelEmbedding for (W8, W40) {}
12712impl ValidLevelEmbedding for (W8, W48) {}
12713impl ValidLevelEmbedding for (W8, W56) {}
12714impl ValidLevelEmbedding for (W8, W64) {}
12715impl ValidLevelEmbedding for (W8, W72) {}
12716impl ValidLevelEmbedding for (W8, W80) {}
12717impl ValidLevelEmbedding for (W8, W88) {}
12718impl ValidLevelEmbedding for (W8, W96) {}
12719impl ValidLevelEmbedding for (W8, W104) {}
12720impl ValidLevelEmbedding for (W8, W112) {}
12721impl ValidLevelEmbedding for (W8, W120) {}
12722impl ValidLevelEmbedding for (W8, W128) {}
12723impl ValidLevelEmbedding for (W16, W16) {}
12724impl ValidLevelEmbedding for (W16, W24) {}
12725impl ValidLevelEmbedding for (W16, W32) {}
12726impl ValidLevelEmbedding for (W16, W40) {}
12727impl ValidLevelEmbedding for (W16, W48) {}
12728impl ValidLevelEmbedding for (W16, W56) {}
12729impl ValidLevelEmbedding for (W16, W64) {}
12730impl ValidLevelEmbedding for (W16, W72) {}
12731impl ValidLevelEmbedding for (W16, W80) {}
12732impl ValidLevelEmbedding for (W16, W88) {}
12733impl ValidLevelEmbedding for (W16, W96) {}
12734impl ValidLevelEmbedding for (W16, W104) {}
12735impl ValidLevelEmbedding for (W16, W112) {}
12736impl ValidLevelEmbedding for (W16, W120) {}
12737impl ValidLevelEmbedding for (W16, W128) {}
12738impl ValidLevelEmbedding for (W24, W24) {}
12739impl ValidLevelEmbedding for (W24, W32) {}
12740impl ValidLevelEmbedding for (W24, W40) {}
12741impl ValidLevelEmbedding for (W24, W48) {}
12742impl ValidLevelEmbedding for (W24, W56) {}
12743impl ValidLevelEmbedding for (W24, W64) {}
12744impl ValidLevelEmbedding for (W24, W72) {}
12745impl ValidLevelEmbedding for (W24, W80) {}
12746impl ValidLevelEmbedding for (W24, W88) {}
12747impl ValidLevelEmbedding for (W24, W96) {}
12748impl ValidLevelEmbedding for (W24, W104) {}
12749impl ValidLevelEmbedding for (W24, W112) {}
12750impl ValidLevelEmbedding for (W24, W120) {}
12751impl ValidLevelEmbedding for (W24, W128) {}
12752impl ValidLevelEmbedding for (W32, W32) {}
12753impl ValidLevelEmbedding for (W32, W40) {}
12754impl ValidLevelEmbedding for (W32, W48) {}
12755impl ValidLevelEmbedding for (W32, W56) {}
12756impl ValidLevelEmbedding for (W32, W64) {}
12757impl ValidLevelEmbedding for (W32, W72) {}
12758impl ValidLevelEmbedding for (W32, W80) {}
12759impl ValidLevelEmbedding for (W32, W88) {}
12760impl ValidLevelEmbedding for (W32, W96) {}
12761impl ValidLevelEmbedding for (W32, W104) {}
12762impl ValidLevelEmbedding for (W32, W112) {}
12763impl ValidLevelEmbedding for (W32, W120) {}
12764impl ValidLevelEmbedding for (W32, W128) {}
12765impl ValidLevelEmbedding for (W40, W40) {}
12766impl ValidLevelEmbedding for (W40, W48) {}
12767impl ValidLevelEmbedding for (W40, W56) {}
12768impl ValidLevelEmbedding for (W40, W64) {}
12769impl ValidLevelEmbedding for (W40, W72) {}
12770impl ValidLevelEmbedding for (W40, W80) {}
12771impl ValidLevelEmbedding for (W40, W88) {}
12772impl ValidLevelEmbedding for (W40, W96) {}
12773impl ValidLevelEmbedding for (W40, W104) {}
12774impl ValidLevelEmbedding for (W40, W112) {}
12775impl ValidLevelEmbedding for (W40, W120) {}
12776impl ValidLevelEmbedding for (W40, W128) {}
12777impl ValidLevelEmbedding for (W48, W48) {}
12778impl ValidLevelEmbedding for (W48, W56) {}
12779impl ValidLevelEmbedding for (W48, W64) {}
12780impl ValidLevelEmbedding for (W48, W72) {}
12781impl ValidLevelEmbedding for (W48, W80) {}
12782impl ValidLevelEmbedding for (W48, W88) {}
12783impl ValidLevelEmbedding for (W48, W96) {}
12784impl ValidLevelEmbedding for (W48, W104) {}
12785impl ValidLevelEmbedding for (W48, W112) {}
12786impl ValidLevelEmbedding for (W48, W120) {}
12787impl ValidLevelEmbedding for (W48, W128) {}
12788impl ValidLevelEmbedding for (W56, W56) {}
12789impl ValidLevelEmbedding for (W56, W64) {}
12790impl ValidLevelEmbedding for (W56, W72) {}
12791impl ValidLevelEmbedding for (W56, W80) {}
12792impl ValidLevelEmbedding for (W56, W88) {}
12793impl ValidLevelEmbedding for (W56, W96) {}
12794impl ValidLevelEmbedding for (W56, W104) {}
12795impl ValidLevelEmbedding for (W56, W112) {}
12796impl ValidLevelEmbedding for (W56, W120) {}
12797impl ValidLevelEmbedding for (W56, W128) {}
12798impl ValidLevelEmbedding for (W64, W64) {}
12799impl ValidLevelEmbedding for (W64, W72) {}
12800impl ValidLevelEmbedding for (W64, W80) {}
12801impl ValidLevelEmbedding for (W64, W88) {}
12802impl ValidLevelEmbedding for (W64, W96) {}
12803impl ValidLevelEmbedding for (W64, W104) {}
12804impl ValidLevelEmbedding for (W64, W112) {}
12805impl ValidLevelEmbedding for (W64, W120) {}
12806impl ValidLevelEmbedding for (W64, W128) {}
12807impl ValidLevelEmbedding for (W72, W72) {}
12808impl ValidLevelEmbedding for (W72, W80) {}
12809impl ValidLevelEmbedding for (W72, W88) {}
12810impl ValidLevelEmbedding for (W72, W96) {}
12811impl ValidLevelEmbedding for (W72, W104) {}
12812impl ValidLevelEmbedding for (W72, W112) {}
12813impl ValidLevelEmbedding for (W72, W120) {}
12814impl ValidLevelEmbedding for (W72, W128) {}
12815impl ValidLevelEmbedding for (W80, W80) {}
12816impl ValidLevelEmbedding for (W80, W88) {}
12817impl ValidLevelEmbedding for (W80, W96) {}
12818impl ValidLevelEmbedding for (W80, W104) {}
12819impl ValidLevelEmbedding for (W80, W112) {}
12820impl ValidLevelEmbedding for (W80, W120) {}
12821impl ValidLevelEmbedding for (W80, W128) {}
12822impl ValidLevelEmbedding for (W88, W88) {}
12823impl ValidLevelEmbedding for (W88, W96) {}
12824impl ValidLevelEmbedding for (W88, W104) {}
12825impl ValidLevelEmbedding for (W88, W112) {}
12826impl ValidLevelEmbedding for (W88, W120) {}
12827impl ValidLevelEmbedding for (W88, W128) {}
12828impl ValidLevelEmbedding for (W96, W96) {}
12829impl ValidLevelEmbedding for (W96, W104) {}
12830impl ValidLevelEmbedding for (W96, W112) {}
12831impl ValidLevelEmbedding for (W96, W120) {}
12832impl ValidLevelEmbedding for (W96, W128) {}
12833impl ValidLevelEmbedding for (W104, W104) {}
12834impl ValidLevelEmbedding for (W104, W112) {}
12835impl ValidLevelEmbedding for (W104, W120) {}
12836impl ValidLevelEmbedding for (W104, W128) {}
12837impl ValidLevelEmbedding for (W112, W112) {}
12838impl ValidLevelEmbedding for (W112, W120) {}
12839impl ValidLevelEmbedding for (W112, W128) {}
12840impl ValidLevelEmbedding for (W120, W120) {}
12841impl ValidLevelEmbedding for (W120, W128) {}
12842impl ValidLevelEmbedding for (W128, W128) {}
12843
12844/// v0.2.2 W3: phantom-typed level embedding `Embed<From, To>` for the
12845/// canonical injection ι : R_From → R_To when `From <= To`.
12846/// Implementations exist only for sealed `(From, To)` pairs in the
12847/// `ValidLevelEmbedding` trait, so attempting an unsupported direction
12848/// (e.g., `Embed<W32, W8>`) fails at compile time.
12849#[derive(Debug, Default, Clone, Copy)]
12850pub struct Embed<From, To>(PhantomData<(From, To)>);
12851
12852impl Embed<W8, W8> {
12853    /// Embed a `u8` value at W8 into a `u8` value at W8.
12854    #[inline]
12855    #[must_use]
12856    pub const fn apply(value: u8) -> u8 {
12857        value
12858    }
12859}
12860
12861impl Embed<W8, W16> {
12862    /// Embed a `u8` value at W8 into a `u16` value at W16.
12863    #[inline]
12864    #[must_use]
12865    pub const fn apply(value: u8) -> u16 {
12866        value as u16
12867    }
12868}
12869
12870impl Embed<W8, W24> {
12871    /// Embed a `u8` value at W8 into a `u32` value at W24.
12872    #[inline]
12873    #[must_use]
12874    pub const fn apply(value: u8) -> u32 {
12875        value as u32
12876    }
12877}
12878
12879impl Embed<W8, W32> {
12880    /// Embed a `u8` value at W8 into a `u32` value at W32.
12881    #[inline]
12882    #[must_use]
12883    pub const fn apply(value: u8) -> u32 {
12884        value as u32
12885    }
12886}
12887
12888impl Embed<W8, W40> {
12889    /// Embed a `u8` value at W8 into a `u64` value at W40.
12890    #[inline]
12891    #[must_use]
12892    pub const fn apply(value: u8) -> u64 {
12893        value as u64
12894    }
12895}
12896
12897impl Embed<W8, W48> {
12898    /// Embed a `u8` value at W8 into a `u64` value at W48.
12899    #[inline]
12900    #[must_use]
12901    pub const fn apply(value: u8) -> u64 {
12902        value as u64
12903    }
12904}
12905
12906impl Embed<W8, W56> {
12907    /// Embed a `u8` value at W8 into a `u64` value at W56.
12908    #[inline]
12909    #[must_use]
12910    pub const fn apply(value: u8) -> u64 {
12911        value as u64
12912    }
12913}
12914
12915impl Embed<W8, W64> {
12916    /// Embed a `u8` value at W8 into a `u64` value at W64.
12917    #[inline]
12918    #[must_use]
12919    pub const fn apply(value: u8) -> u64 {
12920        value as u64
12921    }
12922}
12923
12924impl Embed<W8, W72> {
12925    /// Embed a `u8` value at W8 into a `u128` value at W72.
12926    #[inline]
12927    #[must_use]
12928    pub const fn apply(value: u8) -> u128 {
12929        value as u128
12930    }
12931}
12932
12933impl Embed<W8, W80> {
12934    /// Embed a `u8` value at W8 into a `u128` value at W80.
12935    #[inline]
12936    #[must_use]
12937    pub const fn apply(value: u8) -> u128 {
12938        value as u128
12939    }
12940}
12941
12942impl Embed<W8, W88> {
12943    /// Embed a `u8` value at W8 into a `u128` value at W88.
12944    #[inline]
12945    #[must_use]
12946    pub const fn apply(value: u8) -> u128 {
12947        value as u128
12948    }
12949}
12950
12951impl Embed<W8, W96> {
12952    /// Embed a `u8` value at W8 into a `u128` value at W96.
12953    #[inline]
12954    #[must_use]
12955    pub const fn apply(value: u8) -> u128 {
12956        value as u128
12957    }
12958}
12959
12960impl Embed<W8, W104> {
12961    /// Embed a `u8` value at W8 into a `u128` value at W104.
12962    #[inline]
12963    #[must_use]
12964    pub const fn apply(value: u8) -> u128 {
12965        value as u128
12966    }
12967}
12968
12969impl Embed<W8, W112> {
12970    /// Embed a `u8` value at W8 into a `u128` value at W112.
12971    #[inline]
12972    #[must_use]
12973    pub const fn apply(value: u8) -> u128 {
12974        value as u128
12975    }
12976}
12977
12978impl Embed<W8, W120> {
12979    /// Embed a `u8` value at W8 into a `u128` value at W120.
12980    #[inline]
12981    #[must_use]
12982    pub const fn apply(value: u8) -> u128 {
12983        value as u128
12984    }
12985}
12986
12987impl Embed<W8, W128> {
12988    /// Embed a `u8` value at W8 into a `u128` value at W128.
12989    #[inline]
12990    #[must_use]
12991    pub const fn apply(value: u8) -> u128 {
12992        value as u128
12993    }
12994}
12995
12996impl Embed<W16, W16> {
12997    /// Embed a `u16` value at W16 into a `u16` value at W16.
12998    #[inline]
12999    #[must_use]
13000    pub const fn apply(value: u16) -> u16 {
13001        value
13002    }
13003}
13004
13005impl Embed<W16, W24> {
13006    /// Embed a `u16` value at W16 into a `u32` value at W24.
13007    #[inline]
13008    #[must_use]
13009    pub const fn apply(value: u16) -> u32 {
13010        value as u32
13011    }
13012}
13013
13014impl Embed<W16, W32> {
13015    /// Embed a `u16` value at W16 into a `u32` value at W32.
13016    #[inline]
13017    #[must_use]
13018    pub const fn apply(value: u16) -> u32 {
13019        value as u32
13020    }
13021}
13022
13023impl Embed<W16, W40> {
13024    /// Embed a `u16` value at W16 into a `u64` value at W40.
13025    #[inline]
13026    #[must_use]
13027    pub const fn apply(value: u16) -> u64 {
13028        value as u64
13029    }
13030}
13031
13032impl Embed<W16, W48> {
13033    /// Embed a `u16` value at W16 into a `u64` value at W48.
13034    #[inline]
13035    #[must_use]
13036    pub const fn apply(value: u16) -> u64 {
13037        value as u64
13038    }
13039}
13040
13041impl Embed<W16, W56> {
13042    /// Embed a `u16` value at W16 into a `u64` value at W56.
13043    #[inline]
13044    #[must_use]
13045    pub const fn apply(value: u16) -> u64 {
13046        value as u64
13047    }
13048}
13049
13050impl Embed<W16, W64> {
13051    /// Embed a `u16` value at W16 into a `u64` value at W64.
13052    #[inline]
13053    #[must_use]
13054    pub const fn apply(value: u16) -> u64 {
13055        value as u64
13056    }
13057}
13058
13059impl Embed<W16, W72> {
13060    /// Embed a `u16` value at W16 into a `u128` value at W72.
13061    #[inline]
13062    #[must_use]
13063    pub const fn apply(value: u16) -> u128 {
13064        value as u128
13065    }
13066}
13067
13068impl Embed<W16, W80> {
13069    /// Embed a `u16` value at W16 into a `u128` value at W80.
13070    #[inline]
13071    #[must_use]
13072    pub const fn apply(value: u16) -> u128 {
13073        value as u128
13074    }
13075}
13076
13077impl Embed<W16, W88> {
13078    /// Embed a `u16` value at W16 into a `u128` value at W88.
13079    #[inline]
13080    #[must_use]
13081    pub const fn apply(value: u16) -> u128 {
13082        value as u128
13083    }
13084}
13085
13086impl Embed<W16, W96> {
13087    /// Embed a `u16` value at W16 into a `u128` value at W96.
13088    #[inline]
13089    #[must_use]
13090    pub const fn apply(value: u16) -> u128 {
13091        value as u128
13092    }
13093}
13094
13095impl Embed<W16, W104> {
13096    /// Embed a `u16` value at W16 into a `u128` value at W104.
13097    #[inline]
13098    #[must_use]
13099    pub const fn apply(value: u16) -> u128 {
13100        value as u128
13101    }
13102}
13103
13104impl Embed<W16, W112> {
13105    /// Embed a `u16` value at W16 into a `u128` value at W112.
13106    #[inline]
13107    #[must_use]
13108    pub const fn apply(value: u16) -> u128 {
13109        value as u128
13110    }
13111}
13112
13113impl Embed<W16, W120> {
13114    /// Embed a `u16` value at W16 into a `u128` value at W120.
13115    #[inline]
13116    #[must_use]
13117    pub const fn apply(value: u16) -> u128 {
13118        value as u128
13119    }
13120}
13121
13122impl Embed<W16, W128> {
13123    /// Embed a `u16` value at W16 into a `u128` value at W128.
13124    #[inline]
13125    #[must_use]
13126    pub const fn apply(value: u16) -> u128 {
13127        value as u128
13128    }
13129}
13130
13131impl Embed<W24, W24> {
13132    /// Embed a `u32` value at W24 into a `u32` value at W24.
13133    #[inline]
13134    #[must_use]
13135    pub const fn apply(value: u32) -> u32 {
13136        value
13137    }
13138}
13139
13140impl Embed<W24, W32> {
13141    /// Embed a `u32` value at W24 into a `u32` value at W32.
13142    #[inline]
13143    #[must_use]
13144    pub const fn apply(value: u32) -> u32 {
13145        value
13146    }
13147}
13148
13149impl Embed<W24, W40> {
13150    /// Embed a `u32` value at W24 into a `u64` value at W40.
13151    #[inline]
13152    #[must_use]
13153    pub const fn apply(value: u32) -> u64 {
13154        value as u64
13155    }
13156}
13157
13158impl Embed<W24, W48> {
13159    /// Embed a `u32` value at W24 into a `u64` value at W48.
13160    #[inline]
13161    #[must_use]
13162    pub const fn apply(value: u32) -> u64 {
13163        value as u64
13164    }
13165}
13166
13167impl Embed<W24, W56> {
13168    /// Embed a `u32` value at W24 into a `u64` value at W56.
13169    #[inline]
13170    #[must_use]
13171    pub const fn apply(value: u32) -> u64 {
13172        value as u64
13173    }
13174}
13175
13176impl Embed<W24, W64> {
13177    /// Embed a `u32` value at W24 into a `u64` value at W64.
13178    #[inline]
13179    #[must_use]
13180    pub const fn apply(value: u32) -> u64 {
13181        value as u64
13182    }
13183}
13184
13185impl Embed<W24, W72> {
13186    /// Embed a `u32` value at W24 into a `u128` value at W72.
13187    #[inline]
13188    #[must_use]
13189    pub const fn apply(value: u32) -> u128 {
13190        value as u128
13191    }
13192}
13193
13194impl Embed<W24, W80> {
13195    /// Embed a `u32` value at W24 into a `u128` value at W80.
13196    #[inline]
13197    #[must_use]
13198    pub const fn apply(value: u32) -> u128 {
13199        value as u128
13200    }
13201}
13202
13203impl Embed<W24, W88> {
13204    /// Embed a `u32` value at W24 into a `u128` value at W88.
13205    #[inline]
13206    #[must_use]
13207    pub const fn apply(value: u32) -> u128 {
13208        value as u128
13209    }
13210}
13211
13212impl Embed<W24, W96> {
13213    /// Embed a `u32` value at W24 into a `u128` value at W96.
13214    #[inline]
13215    #[must_use]
13216    pub const fn apply(value: u32) -> u128 {
13217        value as u128
13218    }
13219}
13220
13221impl Embed<W24, W104> {
13222    /// Embed a `u32` value at W24 into a `u128` value at W104.
13223    #[inline]
13224    #[must_use]
13225    pub const fn apply(value: u32) -> u128 {
13226        value as u128
13227    }
13228}
13229
13230impl Embed<W24, W112> {
13231    /// Embed a `u32` value at W24 into a `u128` value at W112.
13232    #[inline]
13233    #[must_use]
13234    pub const fn apply(value: u32) -> u128 {
13235        value as u128
13236    }
13237}
13238
13239impl Embed<W24, W120> {
13240    /// Embed a `u32` value at W24 into a `u128` value at W120.
13241    #[inline]
13242    #[must_use]
13243    pub const fn apply(value: u32) -> u128 {
13244        value as u128
13245    }
13246}
13247
13248impl Embed<W24, W128> {
13249    /// Embed a `u32` value at W24 into a `u128` value at W128.
13250    #[inline]
13251    #[must_use]
13252    pub const fn apply(value: u32) -> u128 {
13253        value as u128
13254    }
13255}
13256
13257impl Embed<W32, W32> {
13258    /// Embed a `u32` value at W32 into a `u32` value at W32.
13259    #[inline]
13260    #[must_use]
13261    pub const fn apply(value: u32) -> u32 {
13262        value
13263    }
13264}
13265
13266impl Embed<W32, W40> {
13267    /// Embed a `u32` value at W32 into a `u64` value at W40.
13268    #[inline]
13269    #[must_use]
13270    pub const fn apply(value: u32) -> u64 {
13271        value as u64
13272    }
13273}
13274
13275impl Embed<W32, W48> {
13276    /// Embed a `u32` value at W32 into a `u64` value at W48.
13277    #[inline]
13278    #[must_use]
13279    pub const fn apply(value: u32) -> u64 {
13280        value as u64
13281    }
13282}
13283
13284impl Embed<W32, W56> {
13285    /// Embed a `u32` value at W32 into a `u64` value at W56.
13286    #[inline]
13287    #[must_use]
13288    pub const fn apply(value: u32) -> u64 {
13289        value as u64
13290    }
13291}
13292
13293impl Embed<W32, W64> {
13294    /// Embed a `u32` value at W32 into a `u64` value at W64.
13295    #[inline]
13296    #[must_use]
13297    pub const fn apply(value: u32) -> u64 {
13298        value as u64
13299    }
13300}
13301
13302impl Embed<W32, W72> {
13303    /// Embed a `u32` value at W32 into a `u128` value at W72.
13304    #[inline]
13305    #[must_use]
13306    pub const fn apply(value: u32) -> u128 {
13307        value as u128
13308    }
13309}
13310
13311impl Embed<W32, W80> {
13312    /// Embed a `u32` value at W32 into a `u128` value at W80.
13313    #[inline]
13314    #[must_use]
13315    pub const fn apply(value: u32) -> u128 {
13316        value as u128
13317    }
13318}
13319
13320impl Embed<W32, W88> {
13321    /// Embed a `u32` value at W32 into a `u128` value at W88.
13322    #[inline]
13323    #[must_use]
13324    pub const fn apply(value: u32) -> u128 {
13325        value as u128
13326    }
13327}
13328
13329impl Embed<W32, W96> {
13330    /// Embed a `u32` value at W32 into a `u128` value at W96.
13331    #[inline]
13332    #[must_use]
13333    pub const fn apply(value: u32) -> u128 {
13334        value as u128
13335    }
13336}
13337
13338impl Embed<W32, W104> {
13339    /// Embed a `u32` value at W32 into a `u128` value at W104.
13340    #[inline]
13341    #[must_use]
13342    pub const fn apply(value: u32) -> u128 {
13343        value as u128
13344    }
13345}
13346
13347impl Embed<W32, W112> {
13348    /// Embed a `u32` value at W32 into a `u128` value at W112.
13349    #[inline]
13350    #[must_use]
13351    pub const fn apply(value: u32) -> u128 {
13352        value as u128
13353    }
13354}
13355
13356impl Embed<W32, W120> {
13357    /// Embed a `u32` value at W32 into a `u128` value at W120.
13358    #[inline]
13359    #[must_use]
13360    pub const fn apply(value: u32) -> u128 {
13361        value as u128
13362    }
13363}
13364
13365impl Embed<W32, W128> {
13366    /// Embed a `u32` value at W32 into a `u128` value at W128.
13367    #[inline]
13368    #[must_use]
13369    pub const fn apply(value: u32) -> u128 {
13370        value as u128
13371    }
13372}
13373
13374impl Embed<W40, W40> {
13375    /// Embed a `u64` value at W40 into a `u64` value at W40.
13376    #[inline]
13377    #[must_use]
13378    pub const fn apply(value: u64) -> u64 {
13379        value
13380    }
13381}
13382
13383impl Embed<W40, W48> {
13384    /// Embed a `u64` value at W40 into a `u64` value at W48.
13385    #[inline]
13386    #[must_use]
13387    pub const fn apply(value: u64) -> u64 {
13388        value
13389    }
13390}
13391
13392impl Embed<W40, W56> {
13393    /// Embed a `u64` value at W40 into a `u64` value at W56.
13394    #[inline]
13395    #[must_use]
13396    pub const fn apply(value: u64) -> u64 {
13397        value
13398    }
13399}
13400
13401impl Embed<W40, W64> {
13402    /// Embed a `u64` value at W40 into a `u64` value at W64.
13403    #[inline]
13404    #[must_use]
13405    pub const fn apply(value: u64) -> u64 {
13406        value
13407    }
13408}
13409
13410impl Embed<W40, W72> {
13411    /// Embed a `u64` value at W40 into a `u128` value at W72.
13412    #[inline]
13413    #[must_use]
13414    pub const fn apply(value: u64) -> u128 {
13415        value as u128
13416    }
13417}
13418
13419impl Embed<W40, W80> {
13420    /// Embed a `u64` value at W40 into a `u128` value at W80.
13421    #[inline]
13422    #[must_use]
13423    pub const fn apply(value: u64) -> u128 {
13424        value as u128
13425    }
13426}
13427
13428impl Embed<W40, W88> {
13429    /// Embed a `u64` value at W40 into a `u128` value at W88.
13430    #[inline]
13431    #[must_use]
13432    pub const fn apply(value: u64) -> u128 {
13433        value as u128
13434    }
13435}
13436
13437impl Embed<W40, W96> {
13438    /// Embed a `u64` value at W40 into a `u128` value at W96.
13439    #[inline]
13440    #[must_use]
13441    pub const fn apply(value: u64) -> u128 {
13442        value as u128
13443    }
13444}
13445
13446impl Embed<W40, W104> {
13447    /// Embed a `u64` value at W40 into a `u128` value at W104.
13448    #[inline]
13449    #[must_use]
13450    pub const fn apply(value: u64) -> u128 {
13451        value as u128
13452    }
13453}
13454
13455impl Embed<W40, W112> {
13456    /// Embed a `u64` value at W40 into a `u128` value at W112.
13457    #[inline]
13458    #[must_use]
13459    pub const fn apply(value: u64) -> u128 {
13460        value as u128
13461    }
13462}
13463
13464impl Embed<W40, W120> {
13465    /// Embed a `u64` value at W40 into a `u128` value at W120.
13466    #[inline]
13467    #[must_use]
13468    pub const fn apply(value: u64) -> u128 {
13469        value as u128
13470    }
13471}
13472
13473impl Embed<W40, W128> {
13474    /// Embed a `u64` value at W40 into a `u128` value at W128.
13475    #[inline]
13476    #[must_use]
13477    pub const fn apply(value: u64) -> u128 {
13478        value as u128
13479    }
13480}
13481
13482impl Embed<W48, W48> {
13483    /// Embed a `u64` value at W48 into a `u64` value at W48.
13484    #[inline]
13485    #[must_use]
13486    pub const fn apply(value: u64) -> u64 {
13487        value
13488    }
13489}
13490
13491impl Embed<W48, W56> {
13492    /// Embed a `u64` value at W48 into a `u64` value at W56.
13493    #[inline]
13494    #[must_use]
13495    pub const fn apply(value: u64) -> u64 {
13496        value
13497    }
13498}
13499
13500impl Embed<W48, W64> {
13501    /// Embed a `u64` value at W48 into a `u64` value at W64.
13502    #[inline]
13503    #[must_use]
13504    pub const fn apply(value: u64) -> u64 {
13505        value
13506    }
13507}
13508
13509impl Embed<W48, W72> {
13510    /// Embed a `u64` value at W48 into a `u128` value at W72.
13511    #[inline]
13512    #[must_use]
13513    pub const fn apply(value: u64) -> u128 {
13514        value as u128
13515    }
13516}
13517
13518impl Embed<W48, W80> {
13519    /// Embed a `u64` value at W48 into a `u128` value at W80.
13520    #[inline]
13521    #[must_use]
13522    pub const fn apply(value: u64) -> u128 {
13523        value as u128
13524    }
13525}
13526
13527impl Embed<W48, W88> {
13528    /// Embed a `u64` value at W48 into a `u128` value at W88.
13529    #[inline]
13530    #[must_use]
13531    pub const fn apply(value: u64) -> u128 {
13532        value as u128
13533    }
13534}
13535
13536impl Embed<W48, W96> {
13537    /// Embed a `u64` value at W48 into a `u128` value at W96.
13538    #[inline]
13539    #[must_use]
13540    pub const fn apply(value: u64) -> u128 {
13541        value as u128
13542    }
13543}
13544
13545impl Embed<W48, W104> {
13546    /// Embed a `u64` value at W48 into a `u128` value at W104.
13547    #[inline]
13548    #[must_use]
13549    pub const fn apply(value: u64) -> u128 {
13550        value as u128
13551    }
13552}
13553
13554impl Embed<W48, W112> {
13555    /// Embed a `u64` value at W48 into a `u128` value at W112.
13556    #[inline]
13557    #[must_use]
13558    pub const fn apply(value: u64) -> u128 {
13559        value as u128
13560    }
13561}
13562
13563impl Embed<W48, W120> {
13564    /// Embed a `u64` value at W48 into a `u128` value at W120.
13565    #[inline]
13566    #[must_use]
13567    pub const fn apply(value: u64) -> u128 {
13568        value as u128
13569    }
13570}
13571
13572impl Embed<W48, W128> {
13573    /// Embed a `u64` value at W48 into a `u128` value at W128.
13574    #[inline]
13575    #[must_use]
13576    pub const fn apply(value: u64) -> u128 {
13577        value as u128
13578    }
13579}
13580
13581impl Embed<W56, W56> {
13582    /// Embed a `u64` value at W56 into a `u64` value at W56.
13583    #[inline]
13584    #[must_use]
13585    pub const fn apply(value: u64) -> u64 {
13586        value
13587    }
13588}
13589
13590impl Embed<W56, W64> {
13591    /// Embed a `u64` value at W56 into a `u64` value at W64.
13592    #[inline]
13593    #[must_use]
13594    pub const fn apply(value: u64) -> u64 {
13595        value
13596    }
13597}
13598
13599impl Embed<W56, W72> {
13600    /// Embed a `u64` value at W56 into a `u128` value at W72.
13601    #[inline]
13602    #[must_use]
13603    pub const fn apply(value: u64) -> u128 {
13604        value as u128
13605    }
13606}
13607
13608impl Embed<W56, W80> {
13609    /// Embed a `u64` value at W56 into a `u128` value at W80.
13610    #[inline]
13611    #[must_use]
13612    pub const fn apply(value: u64) -> u128 {
13613        value as u128
13614    }
13615}
13616
13617impl Embed<W56, W88> {
13618    /// Embed a `u64` value at W56 into a `u128` value at W88.
13619    #[inline]
13620    #[must_use]
13621    pub const fn apply(value: u64) -> u128 {
13622        value as u128
13623    }
13624}
13625
13626impl Embed<W56, W96> {
13627    /// Embed a `u64` value at W56 into a `u128` value at W96.
13628    #[inline]
13629    #[must_use]
13630    pub const fn apply(value: u64) -> u128 {
13631        value as u128
13632    }
13633}
13634
13635impl Embed<W56, W104> {
13636    /// Embed a `u64` value at W56 into a `u128` value at W104.
13637    #[inline]
13638    #[must_use]
13639    pub const fn apply(value: u64) -> u128 {
13640        value as u128
13641    }
13642}
13643
13644impl Embed<W56, W112> {
13645    /// Embed a `u64` value at W56 into a `u128` value at W112.
13646    #[inline]
13647    #[must_use]
13648    pub const fn apply(value: u64) -> u128 {
13649        value as u128
13650    }
13651}
13652
13653impl Embed<W56, W120> {
13654    /// Embed a `u64` value at W56 into a `u128` value at W120.
13655    #[inline]
13656    #[must_use]
13657    pub const fn apply(value: u64) -> u128 {
13658        value as u128
13659    }
13660}
13661
13662impl Embed<W56, W128> {
13663    /// Embed a `u64` value at W56 into a `u128` value at W128.
13664    #[inline]
13665    #[must_use]
13666    pub const fn apply(value: u64) -> u128 {
13667        value as u128
13668    }
13669}
13670
13671impl Embed<W64, W64> {
13672    /// Embed a `u64` value at W64 into a `u64` value at W64.
13673    #[inline]
13674    #[must_use]
13675    pub const fn apply(value: u64) -> u64 {
13676        value
13677    }
13678}
13679
13680impl Embed<W64, W72> {
13681    /// Embed a `u64` value at W64 into a `u128` value at W72.
13682    #[inline]
13683    #[must_use]
13684    pub const fn apply(value: u64) -> u128 {
13685        value as u128
13686    }
13687}
13688
13689impl Embed<W64, W80> {
13690    /// Embed a `u64` value at W64 into a `u128` value at W80.
13691    #[inline]
13692    #[must_use]
13693    pub const fn apply(value: u64) -> u128 {
13694        value as u128
13695    }
13696}
13697
13698impl Embed<W64, W88> {
13699    /// Embed a `u64` value at W64 into a `u128` value at W88.
13700    #[inline]
13701    #[must_use]
13702    pub const fn apply(value: u64) -> u128 {
13703        value as u128
13704    }
13705}
13706
13707impl Embed<W64, W96> {
13708    /// Embed a `u64` value at W64 into a `u128` value at W96.
13709    #[inline]
13710    #[must_use]
13711    pub const fn apply(value: u64) -> u128 {
13712        value as u128
13713    }
13714}
13715
13716impl Embed<W64, W104> {
13717    /// Embed a `u64` value at W64 into a `u128` value at W104.
13718    #[inline]
13719    #[must_use]
13720    pub const fn apply(value: u64) -> u128 {
13721        value as u128
13722    }
13723}
13724
13725impl Embed<W64, W112> {
13726    /// Embed a `u64` value at W64 into a `u128` value at W112.
13727    #[inline]
13728    #[must_use]
13729    pub const fn apply(value: u64) -> u128 {
13730        value as u128
13731    }
13732}
13733
13734impl Embed<W64, W120> {
13735    /// Embed a `u64` value at W64 into a `u128` value at W120.
13736    #[inline]
13737    #[must_use]
13738    pub const fn apply(value: u64) -> u128 {
13739        value as u128
13740    }
13741}
13742
13743impl Embed<W64, W128> {
13744    /// Embed a `u64` value at W64 into a `u128` value at W128.
13745    #[inline]
13746    #[must_use]
13747    pub const fn apply(value: u64) -> u128 {
13748        value as u128
13749    }
13750}
13751
13752impl Embed<W72, W72> {
13753    /// Embed a `u128` value at W72 into a `u128` value at W72.
13754    #[inline]
13755    #[must_use]
13756    pub const fn apply(value: u128) -> u128 {
13757        value
13758    }
13759}
13760
13761impl Embed<W72, W80> {
13762    /// Embed a `u128` value at W72 into a `u128` value at W80.
13763    #[inline]
13764    #[must_use]
13765    pub const fn apply(value: u128) -> u128 {
13766        value
13767    }
13768}
13769
13770impl Embed<W72, W88> {
13771    /// Embed a `u128` value at W72 into a `u128` value at W88.
13772    #[inline]
13773    #[must_use]
13774    pub const fn apply(value: u128) -> u128 {
13775        value
13776    }
13777}
13778
13779impl Embed<W72, W96> {
13780    /// Embed a `u128` value at W72 into a `u128` value at W96.
13781    #[inline]
13782    #[must_use]
13783    pub const fn apply(value: u128) -> u128 {
13784        value
13785    }
13786}
13787
13788impl Embed<W72, W104> {
13789    /// Embed a `u128` value at W72 into a `u128` value at W104.
13790    #[inline]
13791    #[must_use]
13792    pub const fn apply(value: u128) -> u128 {
13793        value
13794    }
13795}
13796
13797impl Embed<W72, W112> {
13798    /// Embed a `u128` value at W72 into a `u128` value at W112.
13799    #[inline]
13800    #[must_use]
13801    pub const fn apply(value: u128) -> u128 {
13802        value
13803    }
13804}
13805
13806impl Embed<W72, W120> {
13807    /// Embed a `u128` value at W72 into a `u128` value at W120.
13808    #[inline]
13809    #[must_use]
13810    pub const fn apply(value: u128) -> u128 {
13811        value
13812    }
13813}
13814
13815impl Embed<W72, W128> {
13816    /// Embed a `u128` value at W72 into a `u128` value at W128.
13817    #[inline]
13818    #[must_use]
13819    pub const fn apply(value: u128) -> u128 {
13820        value
13821    }
13822}
13823
13824impl Embed<W80, W80> {
13825    /// Embed a `u128` value at W80 into a `u128` value at W80.
13826    #[inline]
13827    #[must_use]
13828    pub const fn apply(value: u128) -> u128 {
13829        value
13830    }
13831}
13832
13833impl Embed<W80, W88> {
13834    /// Embed a `u128` value at W80 into a `u128` value at W88.
13835    #[inline]
13836    #[must_use]
13837    pub const fn apply(value: u128) -> u128 {
13838        value
13839    }
13840}
13841
13842impl Embed<W80, W96> {
13843    /// Embed a `u128` value at W80 into a `u128` value at W96.
13844    #[inline]
13845    #[must_use]
13846    pub const fn apply(value: u128) -> u128 {
13847        value
13848    }
13849}
13850
13851impl Embed<W80, W104> {
13852    /// Embed a `u128` value at W80 into a `u128` value at W104.
13853    #[inline]
13854    #[must_use]
13855    pub const fn apply(value: u128) -> u128 {
13856        value
13857    }
13858}
13859
13860impl Embed<W80, W112> {
13861    /// Embed a `u128` value at W80 into a `u128` value at W112.
13862    #[inline]
13863    #[must_use]
13864    pub const fn apply(value: u128) -> u128 {
13865        value
13866    }
13867}
13868
13869impl Embed<W80, W120> {
13870    /// Embed a `u128` value at W80 into a `u128` value at W120.
13871    #[inline]
13872    #[must_use]
13873    pub const fn apply(value: u128) -> u128 {
13874        value
13875    }
13876}
13877
13878impl Embed<W80, W128> {
13879    /// Embed a `u128` value at W80 into a `u128` value at W128.
13880    #[inline]
13881    #[must_use]
13882    pub const fn apply(value: u128) -> u128 {
13883        value
13884    }
13885}
13886
13887impl Embed<W88, W88> {
13888    /// Embed a `u128` value at W88 into a `u128` value at W88.
13889    #[inline]
13890    #[must_use]
13891    pub const fn apply(value: u128) -> u128 {
13892        value
13893    }
13894}
13895
13896impl Embed<W88, W96> {
13897    /// Embed a `u128` value at W88 into a `u128` value at W96.
13898    #[inline]
13899    #[must_use]
13900    pub const fn apply(value: u128) -> u128 {
13901        value
13902    }
13903}
13904
13905impl Embed<W88, W104> {
13906    /// Embed a `u128` value at W88 into a `u128` value at W104.
13907    #[inline]
13908    #[must_use]
13909    pub const fn apply(value: u128) -> u128 {
13910        value
13911    }
13912}
13913
13914impl Embed<W88, W112> {
13915    /// Embed a `u128` value at W88 into a `u128` value at W112.
13916    #[inline]
13917    #[must_use]
13918    pub const fn apply(value: u128) -> u128 {
13919        value
13920    }
13921}
13922
13923impl Embed<W88, W120> {
13924    /// Embed a `u128` value at W88 into a `u128` value at W120.
13925    #[inline]
13926    #[must_use]
13927    pub const fn apply(value: u128) -> u128 {
13928        value
13929    }
13930}
13931
13932impl Embed<W88, W128> {
13933    /// Embed a `u128` value at W88 into a `u128` value at W128.
13934    #[inline]
13935    #[must_use]
13936    pub const fn apply(value: u128) -> u128 {
13937        value
13938    }
13939}
13940
13941impl Embed<W96, W96> {
13942    /// Embed a `u128` value at W96 into a `u128` value at W96.
13943    #[inline]
13944    #[must_use]
13945    pub const fn apply(value: u128) -> u128 {
13946        value
13947    }
13948}
13949
13950impl Embed<W96, W104> {
13951    /// Embed a `u128` value at W96 into a `u128` value at W104.
13952    #[inline]
13953    #[must_use]
13954    pub const fn apply(value: u128) -> u128 {
13955        value
13956    }
13957}
13958
13959impl Embed<W96, W112> {
13960    /// Embed a `u128` value at W96 into a `u128` value at W112.
13961    #[inline]
13962    #[must_use]
13963    pub const fn apply(value: u128) -> u128 {
13964        value
13965    }
13966}
13967
13968impl Embed<W96, W120> {
13969    /// Embed a `u128` value at W96 into a `u128` value at W120.
13970    #[inline]
13971    #[must_use]
13972    pub const fn apply(value: u128) -> u128 {
13973        value
13974    }
13975}
13976
13977impl Embed<W96, W128> {
13978    /// Embed a `u128` value at W96 into a `u128` value at W128.
13979    #[inline]
13980    #[must_use]
13981    pub const fn apply(value: u128) -> u128 {
13982        value
13983    }
13984}
13985
13986impl Embed<W104, W104> {
13987    /// Embed a `u128` value at W104 into a `u128` value at W104.
13988    #[inline]
13989    #[must_use]
13990    pub const fn apply(value: u128) -> u128 {
13991        value
13992    }
13993}
13994
13995impl Embed<W104, W112> {
13996    /// Embed a `u128` value at W104 into a `u128` value at W112.
13997    #[inline]
13998    #[must_use]
13999    pub const fn apply(value: u128) -> u128 {
14000        value
14001    }
14002}
14003
14004impl Embed<W104, W120> {
14005    /// Embed a `u128` value at W104 into a `u128` value at W120.
14006    #[inline]
14007    #[must_use]
14008    pub const fn apply(value: u128) -> u128 {
14009        value
14010    }
14011}
14012
14013impl Embed<W104, W128> {
14014    /// Embed a `u128` value at W104 into a `u128` value at W128.
14015    #[inline]
14016    #[must_use]
14017    pub const fn apply(value: u128) -> u128 {
14018        value
14019    }
14020}
14021
14022impl Embed<W112, W112> {
14023    /// Embed a `u128` value at W112 into a `u128` value at W112.
14024    #[inline]
14025    #[must_use]
14026    pub const fn apply(value: u128) -> u128 {
14027        value
14028    }
14029}
14030
14031impl Embed<W112, W120> {
14032    /// Embed a `u128` value at W112 into a `u128` value at W120.
14033    #[inline]
14034    #[must_use]
14035    pub const fn apply(value: u128) -> u128 {
14036        value
14037    }
14038}
14039
14040impl Embed<W112, W128> {
14041    /// Embed a `u128` value at W112 into a `u128` value at W128.
14042    #[inline]
14043    #[must_use]
14044    pub const fn apply(value: u128) -> u128 {
14045        value
14046    }
14047}
14048
14049impl Embed<W120, W120> {
14050    /// Embed a `u128` value at W120 into a `u128` value at W120.
14051    #[inline]
14052    #[must_use]
14053    pub const fn apply(value: u128) -> u128 {
14054        value
14055    }
14056}
14057
14058impl Embed<W120, W128> {
14059    /// Embed a `u128` value at W120 into a `u128` value at W128.
14060    #[inline]
14061    #[must_use]
14062    pub const fn apply(value: u128) -> u128 {
14063        value
14064    }
14065}
14066
14067impl Embed<W128, W128> {
14068    /// Embed a `u128` value at W128 into a `u128` value at W128.
14069    #[inline]
14070    #[must_use]
14071    pub const fn apply(value: u128) -> u128 {
14072        value
14073    }
14074}
14075
14076/// v0.2.2 Phase C.3: marker structs for Limbs-backed Witt levels.
14077/// Each level binds a const-generic `Limbs<N>` width at the type level.
14078/// W160 marker — 160-bit Witt level, Limbs-backed.
14079#[derive(Debug, Default, Clone, Copy)]
14080pub struct W160;
14081
14082/// W192 marker — 192-bit Witt level, Limbs-backed.
14083#[derive(Debug, Default, Clone, Copy)]
14084pub struct W192;
14085
14086/// W224 marker — 224-bit Witt level, Limbs-backed.
14087#[derive(Debug, Default, Clone, Copy)]
14088pub struct W224;
14089
14090/// W256 marker — 256-bit Witt level, Limbs-backed.
14091#[derive(Debug, Default, Clone, Copy)]
14092pub struct W256;
14093
14094/// W384 marker — 384-bit Witt level, Limbs-backed.
14095#[derive(Debug, Default, Clone, Copy)]
14096pub struct W384;
14097
14098/// W448 marker — 448-bit Witt level, Limbs-backed.
14099#[derive(Debug, Default, Clone, Copy)]
14100pub struct W448;
14101
14102/// W512 marker — 512-bit Witt level, Limbs-backed.
14103#[derive(Debug, Default, Clone, Copy)]
14104pub struct W512;
14105
14106/// W520 marker — 520-bit Witt level, Limbs-backed.
14107#[derive(Debug, Default, Clone, Copy)]
14108pub struct W520;
14109
14110/// W528 marker — 528-bit Witt level, Limbs-backed.
14111#[derive(Debug, Default, Clone, Copy)]
14112pub struct W528;
14113
14114/// W1024 marker — 1024-bit Witt level, Limbs-backed.
14115#[derive(Debug, Default, Clone, Copy)]
14116pub struct W1024;
14117
14118/// W2048 marker — 2048-bit Witt level, Limbs-backed.
14119#[derive(Debug, Default, Clone, Copy)]
14120pub struct W2048;
14121
14122/// W4096 marker — 4096-bit Witt level, Limbs-backed.
14123#[derive(Debug, Default, Clone, Copy)]
14124pub struct W4096;
14125
14126/// W8192 marker — 8192-bit Witt level, Limbs-backed.
14127#[derive(Debug, Default, Clone, Copy)]
14128pub struct W8192;
14129
14130/// W12288 marker — 12288-bit Witt level, Limbs-backed.
14131#[derive(Debug, Default, Clone, Copy)]
14132pub struct W12288;
14133
14134/// W16384 marker — 16384-bit Witt level, Limbs-backed.
14135#[derive(Debug, Default, Clone, Copy)]
14136pub struct W16384;
14137
14138/// W32768 marker — 32768-bit Witt level, Limbs-backed.
14139#[derive(Debug, Default, Clone, Copy)]
14140pub struct W32768;
14141
14142impl RingOp<W160> for Mul<W160> {
14143    type Operand = Limbs<3>;
14144    #[inline]
14145    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14146        a.wrapping_mul(b).mask_high_bits(160)
14147    }
14148}
14149
14150impl RingOp<W160> for Add<W160> {
14151    type Operand = Limbs<3>;
14152    #[inline]
14153    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14154        a.wrapping_add(b).mask_high_bits(160)
14155    }
14156}
14157
14158impl RingOp<W160> for Sub<W160> {
14159    type Operand = Limbs<3>;
14160    #[inline]
14161    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14162        a.wrapping_sub(b).mask_high_bits(160)
14163    }
14164}
14165
14166impl RingOp<W160> for Xor<W160> {
14167    type Operand = Limbs<3>;
14168    #[inline]
14169    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14170        a.xor(b).mask_high_bits(160)
14171    }
14172}
14173
14174impl RingOp<W160> for And<W160> {
14175    type Operand = Limbs<3>;
14176    #[inline]
14177    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14178        a.and(b).mask_high_bits(160)
14179    }
14180}
14181
14182impl RingOp<W160> for Or<W160> {
14183    type Operand = Limbs<3>;
14184    #[inline]
14185    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14186        a.or(b).mask_high_bits(160)
14187    }
14188}
14189
14190impl UnaryRingOp<W160> for Neg<W160> {
14191    type Operand = Limbs<3>;
14192    #[inline]
14193    fn apply(a: Limbs<3>) -> Limbs<3> {
14194        (Limbs::<3>::zero().wrapping_sub(a)).mask_high_bits(160)
14195    }
14196}
14197
14198impl UnaryRingOp<W160> for BNot<W160> {
14199    type Operand = Limbs<3>;
14200    #[inline]
14201    fn apply(a: Limbs<3>) -> Limbs<3> {
14202        (a.not()).mask_high_bits(160)
14203    }
14204}
14205
14206impl UnaryRingOp<W160> for Succ<W160> {
14207    type Operand = Limbs<3>;
14208    #[inline]
14209    fn apply(a: Limbs<3>) -> Limbs<3> {
14210        (a.wrapping_add(Limbs::<3>::from_words([1u64, 0u64, 0u64]))).mask_high_bits(160)
14211    }
14212}
14213
14214impl RingOp<W192> for Mul<W192> {
14215    type Operand = Limbs<3>;
14216    #[inline]
14217    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14218        a.wrapping_mul(b)
14219    }
14220}
14221
14222impl RingOp<W192> for Add<W192> {
14223    type Operand = Limbs<3>;
14224    #[inline]
14225    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14226        a.wrapping_add(b)
14227    }
14228}
14229
14230impl RingOp<W192> for Sub<W192> {
14231    type Operand = Limbs<3>;
14232    #[inline]
14233    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14234        a.wrapping_sub(b)
14235    }
14236}
14237
14238impl RingOp<W192> for Xor<W192> {
14239    type Operand = Limbs<3>;
14240    #[inline]
14241    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14242        a.xor(b)
14243    }
14244}
14245
14246impl RingOp<W192> for And<W192> {
14247    type Operand = Limbs<3>;
14248    #[inline]
14249    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14250        a.and(b)
14251    }
14252}
14253
14254impl RingOp<W192> for Or<W192> {
14255    type Operand = Limbs<3>;
14256    #[inline]
14257    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14258        a.or(b)
14259    }
14260}
14261
14262impl UnaryRingOp<W192> for Neg<W192> {
14263    type Operand = Limbs<3>;
14264    #[inline]
14265    fn apply(a: Limbs<3>) -> Limbs<3> {
14266        Limbs::<3>::zero().wrapping_sub(a)
14267    }
14268}
14269
14270impl UnaryRingOp<W192> for BNot<W192> {
14271    type Operand = Limbs<3>;
14272    #[inline]
14273    fn apply(a: Limbs<3>) -> Limbs<3> {
14274        a.not()
14275    }
14276}
14277
14278impl UnaryRingOp<W192> for Succ<W192> {
14279    type Operand = Limbs<3>;
14280    #[inline]
14281    fn apply(a: Limbs<3>) -> Limbs<3> {
14282        a.wrapping_add(Limbs::<3>::from_words([1u64, 0u64, 0u64]))
14283    }
14284}
14285
14286impl RingOp<W224> for Mul<W224> {
14287    type Operand = Limbs<4>;
14288    #[inline]
14289    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14290        a.wrapping_mul(b).mask_high_bits(224)
14291    }
14292}
14293
14294impl RingOp<W224> for Add<W224> {
14295    type Operand = Limbs<4>;
14296    #[inline]
14297    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14298        a.wrapping_add(b).mask_high_bits(224)
14299    }
14300}
14301
14302impl RingOp<W224> for Sub<W224> {
14303    type Operand = Limbs<4>;
14304    #[inline]
14305    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14306        a.wrapping_sub(b).mask_high_bits(224)
14307    }
14308}
14309
14310impl RingOp<W224> for Xor<W224> {
14311    type Operand = Limbs<4>;
14312    #[inline]
14313    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14314        a.xor(b).mask_high_bits(224)
14315    }
14316}
14317
14318impl RingOp<W224> for And<W224> {
14319    type Operand = Limbs<4>;
14320    #[inline]
14321    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14322        a.and(b).mask_high_bits(224)
14323    }
14324}
14325
14326impl RingOp<W224> for Or<W224> {
14327    type Operand = Limbs<4>;
14328    #[inline]
14329    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14330        a.or(b).mask_high_bits(224)
14331    }
14332}
14333
14334impl UnaryRingOp<W224> for Neg<W224> {
14335    type Operand = Limbs<4>;
14336    #[inline]
14337    fn apply(a: Limbs<4>) -> Limbs<4> {
14338        (Limbs::<4>::zero().wrapping_sub(a)).mask_high_bits(224)
14339    }
14340}
14341
14342impl UnaryRingOp<W224> for BNot<W224> {
14343    type Operand = Limbs<4>;
14344    #[inline]
14345    fn apply(a: Limbs<4>) -> Limbs<4> {
14346        (a.not()).mask_high_bits(224)
14347    }
14348}
14349
14350impl UnaryRingOp<W224> for Succ<W224> {
14351    type Operand = Limbs<4>;
14352    #[inline]
14353    fn apply(a: Limbs<4>) -> Limbs<4> {
14354        (a.wrapping_add(Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64]))).mask_high_bits(224)
14355    }
14356}
14357
14358impl RingOp<W256> for Mul<W256> {
14359    type Operand = Limbs<4>;
14360    #[inline]
14361    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14362        a.wrapping_mul(b)
14363    }
14364}
14365
14366impl RingOp<W256> for Add<W256> {
14367    type Operand = Limbs<4>;
14368    #[inline]
14369    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14370        a.wrapping_add(b)
14371    }
14372}
14373
14374impl RingOp<W256> for Sub<W256> {
14375    type Operand = Limbs<4>;
14376    #[inline]
14377    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14378        a.wrapping_sub(b)
14379    }
14380}
14381
14382impl RingOp<W256> for Xor<W256> {
14383    type Operand = Limbs<4>;
14384    #[inline]
14385    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14386        a.xor(b)
14387    }
14388}
14389
14390impl RingOp<W256> for And<W256> {
14391    type Operand = Limbs<4>;
14392    #[inline]
14393    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14394        a.and(b)
14395    }
14396}
14397
14398impl RingOp<W256> for Or<W256> {
14399    type Operand = Limbs<4>;
14400    #[inline]
14401    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14402        a.or(b)
14403    }
14404}
14405
14406impl UnaryRingOp<W256> for Neg<W256> {
14407    type Operand = Limbs<4>;
14408    #[inline]
14409    fn apply(a: Limbs<4>) -> Limbs<4> {
14410        Limbs::<4>::zero().wrapping_sub(a)
14411    }
14412}
14413
14414impl UnaryRingOp<W256> for BNot<W256> {
14415    type Operand = Limbs<4>;
14416    #[inline]
14417    fn apply(a: Limbs<4>) -> Limbs<4> {
14418        a.not()
14419    }
14420}
14421
14422impl UnaryRingOp<W256> for Succ<W256> {
14423    type Operand = Limbs<4>;
14424    #[inline]
14425    fn apply(a: Limbs<4>) -> Limbs<4> {
14426        a.wrapping_add(Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64]))
14427    }
14428}
14429
14430impl RingOp<W384> for Mul<W384> {
14431    type Operand = Limbs<6>;
14432    #[inline]
14433    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14434        a.wrapping_mul(b)
14435    }
14436}
14437
14438impl RingOp<W384> for Add<W384> {
14439    type Operand = Limbs<6>;
14440    #[inline]
14441    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14442        a.wrapping_add(b)
14443    }
14444}
14445
14446impl RingOp<W384> for Sub<W384> {
14447    type Operand = Limbs<6>;
14448    #[inline]
14449    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14450        a.wrapping_sub(b)
14451    }
14452}
14453
14454impl RingOp<W384> for Xor<W384> {
14455    type Operand = Limbs<6>;
14456    #[inline]
14457    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14458        a.xor(b)
14459    }
14460}
14461
14462impl RingOp<W384> for And<W384> {
14463    type Operand = Limbs<6>;
14464    #[inline]
14465    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14466        a.and(b)
14467    }
14468}
14469
14470impl RingOp<W384> for Or<W384> {
14471    type Operand = Limbs<6>;
14472    #[inline]
14473    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14474        a.or(b)
14475    }
14476}
14477
14478impl UnaryRingOp<W384> for Neg<W384> {
14479    type Operand = Limbs<6>;
14480    #[inline]
14481    fn apply(a: Limbs<6>) -> Limbs<6> {
14482        Limbs::<6>::zero().wrapping_sub(a)
14483    }
14484}
14485
14486impl UnaryRingOp<W384> for BNot<W384> {
14487    type Operand = Limbs<6>;
14488    #[inline]
14489    fn apply(a: Limbs<6>) -> Limbs<6> {
14490        a.not()
14491    }
14492}
14493
14494impl UnaryRingOp<W384> for Succ<W384> {
14495    type Operand = Limbs<6>;
14496    #[inline]
14497    fn apply(a: Limbs<6>) -> Limbs<6> {
14498        a.wrapping_add(Limbs::<6>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64]))
14499    }
14500}
14501
14502impl RingOp<W448> for Mul<W448> {
14503    type Operand = Limbs<7>;
14504    #[inline]
14505    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14506        a.wrapping_mul(b)
14507    }
14508}
14509
14510impl RingOp<W448> for Add<W448> {
14511    type Operand = Limbs<7>;
14512    #[inline]
14513    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14514        a.wrapping_add(b)
14515    }
14516}
14517
14518impl RingOp<W448> for Sub<W448> {
14519    type Operand = Limbs<7>;
14520    #[inline]
14521    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14522        a.wrapping_sub(b)
14523    }
14524}
14525
14526impl RingOp<W448> for Xor<W448> {
14527    type Operand = Limbs<7>;
14528    #[inline]
14529    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14530        a.xor(b)
14531    }
14532}
14533
14534impl RingOp<W448> for And<W448> {
14535    type Operand = Limbs<7>;
14536    #[inline]
14537    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14538        a.and(b)
14539    }
14540}
14541
14542impl RingOp<W448> for Or<W448> {
14543    type Operand = Limbs<7>;
14544    #[inline]
14545    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14546        a.or(b)
14547    }
14548}
14549
14550impl UnaryRingOp<W448> for Neg<W448> {
14551    type Operand = Limbs<7>;
14552    #[inline]
14553    fn apply(a: Limbs<7>) -> Limbs<7> {
14554        Limbs::<7>::zero().wrapping_sub(a)
14555    }
14556}
14557
14558impl UnaryRingOp<W448> for BNot<W448> {
14559    type Operand = Limbs<7>;
14560    #[inline]
14561    fn apply(a: Limbs<7>) -> Limbs<7> {
14562        a.not()
14563    }
14564}
14565
14566impl UnaryRingOp<W448> for Succ<W448> {
14567    type Operand = Limbs<7>;
14568    #[inline]
14569    fn apply(a: Limbs<7>) -> Limbs<7> {
14570        a.wrapping_add(Limbs::<7>::from_words([
14571            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14572        ]))
14573    }
14574}
14575
14576impl RingOp<W512> for Mul<W512> {
14577    type Operand = Limbs<8>;
14578    #[inline]
14579    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14580        a.wrapping_mul(b)
14581    }
14582}
14583
14584impl RingOp<W512> for Add<W512> {
14585    type Operand = Limbs<8>;
14586    #[inline]
14587    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14588        a.wrapping_add(b)
14589    }
14590}
14591
14592impl RingOp<W512> for Sub<W512> {
14593    type Operand = Limbs<8>;
14594    #[inline]
14595    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14596        a.wrapping_sub(b)
14597    }
14598}
14599
14600impl RingOp<W512> for Xor<W512> {
14601    type Operand = Limbs<8>;
14602    #[inline]
14603    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14604        a.xor(b)
14605    }
14606}
14607
14608impl RingOp<W512> for And<W512> {
14609    type Operand = Limbs<8>;
14610    #[inline]
14611    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14612        a.and(b)
14613    }
14614}
14615
14616impl RingOp<W512> for Or<W512> {
14617    type Operand = Limbs<8>;
14618    #[inline]
14619    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14620        a.or(b)
14621    }
14622}
14623
14624impl UnaryRingOp<W512> for Neg<W512> {
14625    type Operand = Limbs<8>;
14626    #[inline]
14627    fn apply(a: Limbs<8>) -> Limbs<8> {
14628        Limbs::<8>::zero().wrapping_sub(a)
14629    }
14630}
14631
14632impl UnaryRingOp<W512> for BNot<W512> {
14633    type Operand = Limbs<8>;
14634    #[inline]
14635    fn apply(a: Limbs<8>) -> Limbs<8> {
14636        a.not()
14637    }
14638}
14639
14640impl UnaryRingOp<W512> for Succ<W512> {
14641    type Operand = Limbs<8>;
14642    #[inline]
14643    fn apply(a: Limbs<8>) -> Limbs<8> {
14644        a.wrapping_add(Limbs::<8>::from_words([
14645            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14646        ]))
14647    }
14648}
14649
14650impl RingOp<W520> for Mul<W520> {
14651    type Operand = Limbs<9>;
14652    #[inline]
14653    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14654        a.wrapping_mul(b).mask_high_bits(520)
14655    }
14656}
14657
14658impl RingOp<W520> for Add<W520> {
14659    type Operand = Limbs<9>;
14660    #[inline]
14661    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14662        a.wrapping_add(b).mask_high_bits(520)
14663    }
14664}
14665
14666impl RingOp<W520> for Sub<W520> {
14667    type Operand = Limbs<9>;
14668    #[inline]
14669    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14670        a.wrapping_sub(b).mask_high_bits(520)
14671    }
14672}
14673
14674impl RingOp<W520> for Xor<W520> {
14675    type Operand = Limbs<9>;
14676    #[inline]
14677    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14678        a.xor(b).mask_high_bits(520)
14679    }
14680}
14681
14682impl RingOp<W520> for And<W520> {
14683    type Operand = Limbs<9>;
14684    #[inline]
14685    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14686        a.and(b).mask_high_bits(520)
14687    }
14688}
14689
14690impl RingOp<W520> for Or<W520> {
14691    type Operand = Limbs<9>;
14692    #[inline]
14693    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14694        a.or(b).mask_high_bits(520)
14695    }
14696}
14697
14698impl UnaryRingOp<W520> for Neg<W520> {
14699    type Operand = Limbs<9>;
14700    #[inline]
14701    fn apply(a: Limbs<9>) -> Limbs<9> {
14702        (Limbs::<9>::zero().wrapping_sub(a)).mask_high_bits(520)
14703    }
14704}
14705
14706impl UnaryRingOp<W520> for BNot<W520> {
14707    type Operand = Limbs<9>;
14708    #[inline]
14709    fn apply(a: Limbs<9>) -> Limbs<9> {
14710        (a.not()).mask_high_bits(520)
14711    }
14712}
14713
14714impl UnaryRingOp<W520> for Succ<W520> {
14715    type Operand = Limbs<9>;
14716    #[inline]
14717    fn apply(a: Limbs<9>) -> Limbs<9> {
14718        (a.wrapping_add(Limbs::<9>::from_words([
14719            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14720        ])))
14721        .mask_high_bits(520)
14722    }
14723}
14724
14725impl RingOp<W528> for Mul<W528> {
14726    type Operand = Limbs<9>;
14727    #[inline]
14728    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14729        a.wrapping_mul(b).mask_high_bits(528)
14730    }
14731}
14732
14733impl RingOp<W528> for Add<W528> {
14734    type Operand = Limbs<9>;
14735    #[inline]
14736    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14737        a.wrapping_add(b).mask_high_bits(528)
14738    }
14739}
14740
14741impl RingOp<W528> for Sub<W528> {
14742    type Operand = Limbs<9>;
14743    #[inline]
14744    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14745        a.wrapping_sub(b).mask_high_bits(528)
14746    }
14747}
14748
14749impl RingOp<W528> for Xor<W528> {
14750    type Operand = Limbs<9>;
14751    #[inline]
14752    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14753        a.xor(b).mask_high_bits(528)
14754    }
14755}
14756
14757impl RingOp<W528> for And<W528> {
14758    type Operand = Limbs<9>;
14759    #[inline]
14760    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14761        a.and(b).mask_high_bits(528)
14762    }
14763}
14764
14765impl RingOp<W528> for Or<W528> {
14766    type Operand = Limbs<9>;
14767    #[inline]
14768    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14769        a.or(b).mask_high_bits(528)
14770    }
14771}
14772
14773impl UnaryRingOp<W528> for Neg<W528> {
14774    type Operand = Limbs<9>;
14775    #[inline]
14776    fn apply(a: Limbs<9>) -> Limbs<9> {
14777        (Limbs::<9>::zero().wrapping_sub(a)).mask_high_bits(528)
14778    }
14779}
14780
14781impl UnaryRingOp<W528> for BNot<W528> {
14782    type Operand = Limbs<9>;
14783    #[inline]
14784    fn apply(a: Limbs<9>) -> Limbs<9> {
14785        (a.not()).mask_high_bits(528)
14786    }
14787}
14788
14789impl UnaryRingOp<W528> for Succ<W528> {
14790    type Operand = Limbs<9>;
14791    #[inline]
14792    fn apply(a: Limbs<9>) -> Limbs<9> {
14793        (a.wrapping_add(Limbs::<9>::from_words([
14794            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14795        ])))
14796        .mask_high_bits(528)
14797    }
14798}
14799
14800impl RingOp<W1024> for Mul<W1024> {
14801    type Operand = Limbs<16>;
14802    #[inline]
14803    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14804        a.wrapping_mul(b)
14805    }
14806}
14807
14808impl RingOp<W1024> for Add<W1024> {
14809    type Operand = Limbs<16>;
14810    #[inline]
14811    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14812        a.wrapping_add(b)
14813    }
14814}
14815
14816impl RingOp<W1024> for Sub<W1024> {
14817    type Operand = Limbs<16>;
14818    #[inline]
14819    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14820        a.wrapping_sub(b)
14821    }
14822}
14823
14824impl RingOp<W1024> for Xor<W1024> {
14825    type Operand = Limbs<16>;
14826    #[inline]
14827    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14828        a.xor(b)
14829    }
14830}
14831
14832impl RingOp<W1024> for And<W1024> {
14833    type Operand = Limbs<16>;
14834    #[inline]
14835    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14836        a.and(b)
14837    }
14838}
14839
14840impl RingOp<W1024> for Or<W1024> {
14841    type Operand = Limbs<16>;
14842    #[inline]
14843    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14844        a.or(b)
14845    }
14846}
14847
14848impl UnaryRingOp<W1024> for Neg<W1024> {
14849    type Operand = Limbs<16>;
14850    #[inline]
14851    fn apply(a: Limbs<16>) -> Limbs<16> {
14852        Limbs::<16>::zero().wrapping_sub(a)
14853    }
14854}
14855
14856impl UnaryRingOp<W1024> for BNot<W1024> {
14857    type Operand = Limbs<16>;
14858    #[inline]
14859    fn apply(a: Limbs<16>) -> Limbs<16> {
14860        a.not()
14861    }
14862}
14863
14864impl UnaryRingOp<W1024> for Succ<W1024> {
14865    type Operand = Limbs<16>;
14866    #[inline]
14867    fn apply(a: Limbs<16>) -> Limbs<16> {
14868        a.wrapping_add(Limbs::<16>::from_words([
14869            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14870            0u64, 0u64,
14871        ]))
14872    }
14873}
14874
14875impl RingOp<W2048> for Mul<W2048> {
14876    type Operand = Limbs<32>;
14877    #[inline]
14878    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14879        a.wrapping_mul(b)
14880    }
14881}
14882
14883impl RingOp<W2048> for Add<W2048> {
14884    type Operand = Limbs<32>;
14885    #[inline]
14886    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14887        a.wrapping_add(b)
14888    }
14889}
14890
14891impl RingOp<W2048> for Sub<W2048> {
14892    type Operand = Limbs<32>;
14893    #[inline]
14894    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14895        a.wrapping_sub(b)
14896    }
14897}
14898
14899impl RingOp<W2048> for Xor<W2048> {
14900    type Operand = Limbs<32>;
14901    #[inline]
14902    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14903        a.xor(b)
14904    }
14905}
14906
14907impl RingOp<W2048> for And<W2048> {
14908    type Operand = Limbs<32>;
14909    #[inline]
14910    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14911        a.and(b)
14912    }
14913}
14914
14915impl RingOp<W2048> for Or<W2048> {
14916    type Operand = Limbs<32>;
14917    #[inline]
14918    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
14919        a.or(b)
14920    }
14921}
14922
14923impl UnaryRingOp<W2048> for Neg<W2048> {
14924    type Operand = Limbs<32>;
14925    #[inline]
14926    fn apply(a: Limbs<32>) -> Limbs<32> {
14927        Limbs::<32>::zero().wrapping_sub(a)
14928    }
14929}
14930
14931impl UnaryRingOp<W2048> for BNot<W2048> {
14932    type Operand = Limbs<32>;
14933    #[inline]
14934    fn apply(a: Limbs<32>) -> Limbs<32> {
14935        a.not()
14936    }
14937}
14938
14939impl UnaryRingOp<W2048> for Succ<W2048> {
14940    type Operand = Limbs<32>;
14941    #[inline]
14942    fn apply(a: Limbs<32>) -> Limbs<32> {
14943        a.wrapping_add(Limbs::<32>::from_words([
14944            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14945            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14946            0u64, 0u64, 0u64, 0u64,
14947        ]))
14948    }
14949}
14950
14951impl RingOp<W4096> for Mul<W4096> {
14952    type Operand = Limbs<64>;
14953    #[inline]
14954    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14955        a.wrapping_mul(b)
14956    }
14957}
14958
14959impl RingOp<W4096> for Add<W4096> {
14960    type Operand = Limbs<64>;
14961    #[inline]
14962    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14963        a.wrapping_add(b)
14964    }
14965}
14966
14967impl RingOp<W4096> for Sub<W4096> {
14968    type Operand = Limbs<64>;
14969    #[inline]
14970    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14971        a.wrapping_sub(b)
14972    }
14973}
14974
14975impl RingOp<W4096> for Xor<W4096> {
14976    type Operand = Limbs<64>;
14977    #[inline]
14978    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14979        a.xor(b)
14980    }
14981}
14982
14983impl RingOp<W4096> for And<W4096> {
14984    type Operand = Limbs<64>;
14985    #[inline]
14986    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14987        a.and(b)
14988    }
14989}
14990
14991impl RingOp<W4096> for Or<W4096> {
14992    type Operand = Limbs<64>;
14993    #[inline]
14994    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
14995        a.or(b)
14996    }
14997}
14998
14999impl UnaryRingOp<W4096> for Neg<W4096> {
15000    type Operand = Limbs<64>;
15001    #[inline]
15002    fn apply(a: Limbs<64>) -> Limbs<64> {
15003        Limbs::<64>::zero().wrapping_sub(a)
15004    }
15005}
15006
15007impl UnaryRingOp<W4096> for BNot<W4096> {
15008    type Operand = Limbs<64>;
15009    #[inline]
15010    fn apply(a: Limbs<64>) -> Limbs<64> {
15011        a.not()
15012    }
15013}
15014
15015impl UnaryRingOp<W4096> for Succ<W4096> {
15016    type Operand = Limbs<64>;
15017    #[inline]
15018    fn apply(a: Limbs<64>) -> Limbs<64> {
15019        a.wrapping_add(Limbs::<64>::from_words([
15020            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15021            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15022            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15023            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15024            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15025        ]))
15026    }
15027}
15028
15029impl RingOp<W8192> for Mul<W8192> {
15030    type Operand = Limbs<128>;
15031    #[inline]
15032    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15033        a.wrapping_mul(b)
15034    }
15035}
15036
15037impl RingOp<W8192> for Add<W8192> {
15038    type Operand = Limbs<128>;
15039    #[inline]
15040    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15041        a.wrapping_add(b)
15042    }
15043}
15044
15045impl RingOp<W8192> for Sub<W8192> {
15046    type Operand = Limbs<128>;
15047    #[inline]
15048    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15049        a.wrapping_sub(b)
15050    }
15051}
15052
15053impl RingOp<W8192> for Xor<W8192> {
15054    type Operand = Limbs<128>;
15055    #[inline]
15056    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15057        a.xor(b)
15058    }
15059}
15060
15061impl RingOp<W8192> for And<W8192> {
15062    type Operand = Limbs<128>;
15063    #[inline]
15064    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15065        a.and(b)
15066    }
15067}
15068
15069impl RingOp<W8192> for Or<W8192> {
15070    type Operand = Limbs<128>;
15071    #[inline]
15072    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15073        a.or(b)
15074    }
15075}
15076
15077impl UnaryRingOp<W8192> for Neg<W8192> {
15078    type Operand = Limbs<128>;
15079    #[inline]
15080    fn apply(a: Limbs<128>) -> Limbs<128> {
15081        Limbs::<128>::zero().wrapping_sub(a)
15082    }
15083}
15084
15085impl UnaryRingOp<W8192> for BNot<W8192> {
15086    type Operand = Limbs<128>;
15087    #[inline]
15088    fn apply(a: Limbs<128>) -> Limbs<128> {
15089        a.not()
15090    }
15091}
15092
15093impl UnaryRingOp<W8192> for Succ<W8192> {
15094    type Operand = Limbs<128>;
15095    #[inline]
15096    fn apply(a: Limbs<128>) -> Limbs<128> {
15097        a.wrapping_add(Limbs::<128>::from_words([
15098            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15099            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15100            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15101            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15102            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15103            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15104            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15105            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15106            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15107            0u64, 0u64,
15108        ]))
15109    }
15110}
15111
15112impl RingOp<W12288> for Mul<W12288> {
15113    type Operand = Limbs<192>;
15114    #[inline]
15115    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15116        a.wrapping_mul(b)
15117    }
15118}
15119
15120impl RingOp<W12288> for Add<W12288> {
15121    type Operand = Limbs<192>;
15122    #[inline]
15123    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15124        a.wrapping_add(b)
15125    }
15126}
15127
15128impl RingOp<W12288> for Sub<W12288> {
15129    type Operand = Limbs<192>;
15130    #[inline]
15131    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15132        a.wrapping_sub(b)
15133    }
15134}
15135
15136impl RingOp<W12288> for Xor<W12288> {
15137    type Operand = Limbs<192>;
15138    #[inline]
15139    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15140        a.xor(b)
15141    }
15142}
15143
15144impl RingOp<W12288> for And<W12288> {
15145    type Operand = Limbs<192>;
15146    #[inline]
15147    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15148        a.and(b)
15149    }
15150}
15151
15152impl RingOp<W12288> for Or<W12288> {
15153    type Operand = Limbs<192>;
15154    #[inline]
15155    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15156        a.or(b)
15157    }
15158}
15159
15160impl UnaryRingOp<W12288> for Neg<W12288> {
15161    type Operand = Limbs<192>;
15162    #[inline]
15163    fn apply(a: Limbs<192>) -> Limbs<192> {
15164        Limbs::<192>::zero().wrapping_sub(a)
15165    }
15166}
15167
15168impl UnaryRingOp<W12288> for BNot<W12288> {
15169    type Operand = Limbs<192>;
15170    #[inline]
15171    fn apply(a: Limbs<192>) -> Limbs<192> {
15172        a.not()
15173    }
15174}
15175
15176impl UnaryRingOp<W12288> for Succ<W12288> {
15177    type Operand = Limbs<192>;
15178    #[inline]
15179    fn apply(a: Limbs<192>) -> Limbs<192> {
15180        a.wrapping_add(Limbs::<192>::from_words([
15181            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15182            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15183            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15184            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15185            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15186            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15187            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15188            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15189            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15190            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15191            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15192            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15193            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15194            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15195        ]))
15196    }
15197}
15198
15199impl RingOp<W16384> for Mul<W16384> {
15200    type Operand = Limbs<256>;
15201    #[inline]
15202    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15203        a.wrapping_mul(b)
15204    }
15205}
15206
15207impl RingOp<W16384> for Add<W16384> {
15208    type Operand = Limbs<256>;
15209    #[inline]
15210    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15211        a.wrapping_add(b)
15212    }
15213}
15214
15215impl RingOp<W16384> for Sub<W16384> {
15216    type Operand = Limbs<256>;
15217    #[inline]
15218    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15219        a.wrapping_sub(b)
15220    }
15221}
15222
15223impl RingOp<W16384> for Xor<W16384> {
15224    type Operand = Limbs<256>;
15225    #[inline]
15226    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15227        a.xor(b)
15228    }
15229}
15230
15231impl RingOp<W16384> for And<W16384> {
15232    type Operand = Limbs<256>;
15233    #[inline]
15234    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15235        a.and(b)
15236    }
15237}
15238
15239impl RingOp<W16384> for Or<W16384> {
15240    type Operand = Limbs<256>;
15241    #[inline]
15242    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15243        a.or(b)
15244    }
15245}
15246
15247impl UnaryRingOp<W16384> for Neg<W16384> {
15248    type Operand = Limbs<256>;
15249    #[inline]
15250    fn apply(a: Limbs<256>) -> Limbs<256> {
15251        Limbs::<256>::zero().wrapping_sub(a)
15252    }
15253}
15254
15255impl UnaryRingOp<W16384> for BNot<W16384> {
15256    type Operand = Limbs<256>;
15257    #[inline]
15258    fn apply(a: Limbs<256>) -> Limbs<256> {
15259        a.not()
15260    }
15261}
15262
15263impl UnaryRingOp<W16384> for Succ<W16384> {
15264    type Operand = Limbs<256>;
15265    #[inline]
15266    fn apply(a: Limbs<256>) -> Limbs<256> {
15267        a.wrapping_add(Limbs::<256>::from_words([
15268            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15269            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15270            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15271            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15272            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15273            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15274            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15275            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15276            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15277            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15278            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15279            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15280            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15281            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15282            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15283            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15284            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15285            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15286            0u64, 0u64, 0u64, 0u64,
15287        ]))
15288    }
15289}
15290
15291impl RingOp<W32768> for Mul<W32768> {
15292    type Operand = Limbs<512>;
15293    #[inline]
15294    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15295        a.wrapping_mul(b)
15296    }
15297}
15298
15299impl RingOp<W32768> for Add<W32768> {
15300    type Operand = Limbs<512>;
15301    #[inline]
15302    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15303        a.wrapping_add(b)
15304    }
15305}
15306
15307impl RingOp<W32768> for Sub<W32768> {
15308    type Operand = Limbs<512>;
15309    #[inline]
15310    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15311        a.wrapping_sub(b)
15312    }
15313}
15314
15315impl RingOp<W32768> for Xor<W32768> {
15316    type Operand = Limbs<512>;
15317    #[inline]
15318    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15319        a.xor(b)
15320    }
15321}
15322
15323impl RingOp<W32768> for And<W32768> {
15324    type Operand = Limbs<512>;
15325    #[inline]
15326    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15327        a.and(b)
15328    }
15329}
15330
15331impl RingOp<W32768> for Or<W32768> {
15332    type Operand = Limbs<512>;
15333    #[inline]
15334    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15335        a.or(b)
15336    }
15337}
15338
15339impl UnaryRingOp<W32768> for Neg<W32768> {
15340    type Operand = Limbs<512>;
15341    #[inline]
15342    fn apply(a: Limbs<512>) -> Limbs<512> {
15343        Limbs::<512>::zero().wrapping_sub(a)
15344    }
15345}
15346
15347impl UnaryRingOp<W32768> for BNot<W32768> {
15348    type Operand = Limbs<512>;
15349    #[inline]
15350    fn apply(a: Limbs<512>) -> Limbs<512> {
15351        a.not()
15352    }
15353}
15354
15355impl UnaryRingOp<W32768> for Succ<W32768> {
15356    type Operand = Limbs<512>;
15357    #[inline]
15358    fn apply(a: Limbs<512>) -> Limbs<512> {
15359        a.wrapping_add(Limbs::<512>::from_words([
15360            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15361            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15362            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15363            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15364            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15365            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15366            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15367            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15368            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15369            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15370            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15371            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15372            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15373            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15374            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15375            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15376            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15377            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15378            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15379            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15380            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15381            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15382            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15383            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15384            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15385            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15386            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15387            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15388            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15389            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15390            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15391            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15392            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15393            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15394            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15395            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15396            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15397        ]))
15398    }
15399}
15400
15401/// Phase L.2 (target §4.5): `const_ring_eval_w{n}` helpers for Limbs-backed
15402/// Witt levels. Each helper runs a `PrimitiveOp` over two `Limbs<N>` operands
15403/// and applies the level's bit-width mask to the result.
15404/// These helpers are always const-fn; whether `rustc` can complete a specific
15405/// compile-time evaluation within the developer's budget is a function of the
15406/// invocation (see target §4.5 Q2 practicality table).
15407#[inline]
15408#[must_use]
15409pub const fn const_ring_eval_w160(op: PrimitiveOp, a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
15410    let raw = match op {
15411        PrimitiveOp::Add => a.wrapping_add(b),
15412        PrimitiveOp::Sub => a.wrapping_sub(b),
15413        PrimitiveOp::Mul => a.wrapping_mul(b),
15414        PrimitiveOp::And => a.and(b),
15415        PrimitiveOp::Or => a.or(b),
15416        PrimitiveOp::Xor => a.xor(b),
15417        PrimitiveOp::Neg => Limbs::<3>::zero().wrapping_sub(a),
15418        PrimitiveOp::Bnot => a.not(),
15419        PrimitiveOp::Succ => a.wrapping_add(limbs_one_3()),
15420        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_3()),
15421        PrimitiveOp::Le => {
15422            if limbs_le_3(a, b) {
15423                limbs_one_3()
15424            } else {
15425                Limbs::<3>::zero()
15426            }
15427        }
15428        PrimitiveOp::Lt => {
15429            if limbs_lt_3(a, b) {
15430                limbs_one_3()
15431            } else {
15432                Limbs::<3>::zero()
15433            }
15434        }
15435        PrimitiveOp::Ge => {
15436            if limbs_le_3(b, a) {
15437                limbs_one_3()
15438            } else {
15439                Limbs::<3>::zero()
15440            }
15441        }
15442        PrimitiveOp::Gt => {
15443            if limbs_lt_3(b, a) {
15444                limbs_one_3()
15445            } else {
15446                Limbs::<3>::zero()
15447            }
15448        }
15449        PrimitiveOp::Concat => Limbs::<3>::zero(),
15450        PrimitiveOp::Div => {
15451            if limbs_is_zero_3(b) {
15452                Limbs::<3>::zero()
15453            } else {
15454                limbs_div_3(a, b)
15455            }
15456        }
15457        PrimitiveOp::Mod => {
15458            if limbs_is_zero_3(b) {
15459                Limbs::<3>::zero()
15460            } else {
15461                limbs_mod_3(a, b)
15462            }
15463        }
15464        PrimitiveOp::Pow => limbs_pow_3(a, b),
15465    };
15466    raw.mask_high_bits(160)
15467}
15468
15469#[inline]
15470#[must_use]
15471pub const fn const_ring_eval_w192(op: PrimitiveOp, a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
15472    match op {
15473        PrimitiveOp::Add => a.wrapping_add(b),
15474        PrimitiveOp::Sub => a.wrapping_sub(b),
15475        PrimitiveOp::Mul => a.wrapping_mul(b),
15476        PrimitiveOp::And => a.and(b),
15477        PrimitiveOp::Or => a.or(b),
15478        PrimitiveOp::Xor => a.xor(b),
15479        PrimitiveOp::Neg => Limbs::<3>::zero().wrapping_sub(a),
15480        PrimitiveOp::Bnot => a.not(),
15481        PrimitiveOp::Succ => a.wrapping_add(limbs_one_3()),
15482        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_3()),
15483        PrimitiveOp::Le => {
15484            if limbs_le_3(a, b) {
15485                limbs_one_3()
15486            } else {
15487                Limbs::<3>::zero()
15488            }
15489        }
15490        PrimitiveOp::Lt => {
15491            if limbs_lt_3(a, b) {
15492                limbs_one_3()
15493            } else {
15494                Limbs::<3>::zero()
15495            }
15496        }
15497        PrimitiveOp::Ge => {
15498            if limbs_le_3(b, a) {
15499                limbs_one_3()
15500            } else {
15501                Limbs::<3>::zero()
15502            }
15503        }
15504        PrimitiveOp::Gt => {
15505            if limbs_lt_3(b, a) {
15506                limbs_one_3()
15507            } else {
15508                Limbs::<3>::zero()
15509            }
15510        }
15511        PrimitiveOp::Concat => Limbs::<3>::zero(),
15512        PrimitiveOp::Div => {
15513            if limbs_is_zero_3(b) {
15514                Limbs::<3>::zero()
15515            } else {
15516                limbs_div_3(a, b)
15517            }
15518        }
15519        PrimitiveOp::Mod => {
15520            if limbs_is_zero_3(b) {
15521                Limbs::<3>::zero()
15522            } else {
15523                limbs_mod_3(a, b)
15524            }
15525        }
15526        PrimitiveOp::Pow => limbs_pow_3(a, b),
15527    }
15528}
15529
15530#[inline]
15531#[must_use]
15532pub const fn const_ring_eval_w224(op: PrimitiveOp, a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
15533    let raw = match op {
15534        PrimitiveOp::Add => a.wrapping_add(b),
15535        PrimitiveOp::Sub => a.wrapping_sub(b),
15536        PrimitiveOp::Mul => a.wrapping_mul(b),
15537        PrimitiveOp::And => a.and(b),
15538        PrimitiveOp::Or => a.or(b),
15539        PrimitiveOp::Xor => a.xor(b),
15540        PrimitiveOp::Neg => Limbs::<4>::zero().wrapping_sub(a),
15541        PrimitiveOp::Bnot => a.not(),
15542        PrimitiveOp::Succ => a.wrapping_add(limbs_one_4()),
15543        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_4()),
15544        PrimitiveOp::Le => {
15545            if limbs_le_4(a, b) {
15546                limbs_one_4()
15547            } else {
15548                Limbs::<4>::zero()
15549            }
15550        }
15551        PrimitiveOp::Lt => {
15552            if limbs_lt_4(a, b) {
15553                limbs_one_4()
15554            } else {
15555                Limbs::<4>::zero()
15556            }
15557        }
15558        PrimitiveOp::Ge => {
15559            if limbs_le_4(b, a) {
15560                limbs_one_4()
15561            } else {
15562                Limbs::<4>::zero()
15563            }
15564        }
15565        PrimitiveOp::Gt => {
15566            if limbs_lt_4(b, a) {
15567                limbs_one_4()
15568            } else {
15569                Limbs::<4>::zero()
15570            }
15571        }
15572        PrimitiveOp::Concat => Limbs::<4>::zero(),
15573        PrimitiveOp::Div => {
15574            if limbs_is_zero_4(b) {
15575                Limbs::<4>::zero()
15576            } else {
15577                limbs_div_4(a, b)
15578            }
15579        }
15580        PrimitiveOp::Mod => {
15581            if limbs_is_zero_4(b) {
15582                Limbs::<4>::zero()
15583            } else {
15584                limbs_mod_4(a, b)
15585            }
15586        }
15587        PrimitiveOp::Pow => limbs_pow_4(a, b),
15588    };
15589    raw.mask_high_bits(224)
15590}
15591
15592#[inline]
15593#[must_use]
15594pub const fn const_ring_eval_w256(op: PrimitiveOp, a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
15595    match op {
15596        PrimitiveOp::Add => a.wrapping_add(b),
15597        PrimitiveOp::Sub => a.wrapping_sub(b),
15598        PrimitiveOp::Mul => a.wrapping_mul(b),
15599        PrimitiveOp::And => a.and(b),
15600        PrimitiveOp::Or => a.or(b),
15601        PrimitiveOp::Xor => a.xor(b),
15602        PrimitiveOp::Neg => Limbs::<4>::zero().wrapping_sub(a),
15603        PrimitiveOp::Bnot => a.not(),
15604        PrimitiveOp::Succ => a.wrapping_add(limbs_one_4()),
15605        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_4()),
15606        PrimitiveOp::Le => {
15607            if limbs_le_4(a, b) {
15608                limbs_one_4()
15609            } else {
15610                Limbs::<4>::zero()
15611            }
15612        }
15613        PrimitiveOp::Lt => {
15614            if limbs_lt_4(a, b) {
15615                limbs_one_4()
15616            } else {
15617                Limbs::<4>::zero()
15618            }
15619        }
15620        PrimitiveOp::Ge => {
15621            if limbs_le_4(b, a) {
15622                limbs_one_4()
15623            } else {
15624                Limbs::<4>::zero()
15625            }
15626        }
15627        PrimitiveOp::Gt => {
15628            if limbs_lt_4(b, a) {
15629                limbs_one_4()
15630            } else {
15631                Limbs::<4>::zero()
15632            }
15633        }
15634        PrimitiveOp::Concat => Limbs::<4>::zero(),
15635        PrimitiveOp::Div => {
15636            if limbs_is_zero_4(b) {
15637                Limbs::<4>::zero()
15638            } else {
15639                limbs_div_4(a, b)
15640            }
15641        }
15642        PrimitiveOp::Mod => {
15643            if limbs_is_zero_4(b) {
15644                Limbs::<4>::zero()
15645            } else {
15646                limbs_mod_4(a, b)
15647            }
15648        }
15649        PrimitiveOp::Pow => limbs_pow_4(a, b),
15650    }
15651}
15652
15653#[inline]
15654#[must_use]
15655pub const fn const_ring_eval_w384(op: PrimitiveOp, a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
15656    match op {
15657        PrimitiveOp::Add => a.wrapping_add(b),
15658        PrimitiveOp::Sub => a.wrapping_sub(b),
15659        PrimitiveOp::Mul => a.wrapping_mul(b),
15660        PrimitiveOp::And => a.and(b),
15661        PrimitiveOp::Or => a.or(b),
15662        PrimitiveOp::Xor => a.xor(b),
15663        PrimitiveOp::Neg => Limbs::<6>::zero().wrapping_sub(a),
15664        PrimitiveOp::Bnot => a.not(),
15665        PrimitiveOp::Succ => a.wrapping_add(limbs_one_6()),
15666        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_6()),
15667        PrimitiveOp::Le => {
15668            if limbs_le_6(a, b) {
15669                limbs_one_6()
15670            } else {
15671                Limbs::<6>::zero()
15672            }
15673        }
15674        PrimitiveOp::Lt => {
15675            if limbs_lt_6(a, b) {
15676                limbs_one_6()
15677            } else {
15678                Limbs::<6>::zero()
15679            }
15680        }
15681        PrimitiveOp::Ge => {
15682            if limbs_le_6(b, a) {
15683                limbs_one_6()
15684            } else {
15685                Limbs::<6>::zero()
15686            }
15687        }
15688        PrimitiveOp::Gt => {
15689            if limbs_lt_6(b, a) {
15690                limbs_one_6()
15691            } else {
15692                Limbs::<6>::zero()
15693            }
15694        }
15695        PrimitiveOp::Concat => Limbs::<6>::zero(),
15696        PrimitiveOp::Div => {
15697            if limbs_is_zero_6(b) {
15698                Limbs::<6>::zero()
15699            } else {
15700                limbs_div_6(a, b)
15701            }
15702        }
15703        PrimitiveOp::Mod => {
15704            if limbs_is_zero_6(b) {
15705                Limbs::<6>::zero()
15706            } else {
15707                limbs_mod_6(a, b)
15708            }
15709        }
15710        PrimitiveOp::Pow => limbs_pow_6(a, b),
15711    }
15712}
15713
15714#[inline]
15715#[must_use]
15716pub const fn const_ring_eval_w448(op: PrimitiveOp, a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
15717    match op {
15718        PrimitiveOp::Add => a.wrapping_add(b),
15719        PrimitiveOp::Sub => a.wrapping_sub(b),
15720        PrimitiveOp::Mul => a.wrapping_mul(b),
15721        PrimitiveOp::And => a.and(b),
15722        PrimitiveOp::Or => a.or(b),
15723        PrimitiveOp::Xor => a.xor(b),
15724        PrimitiveOp::Neg => Limbs::<7>::zero().wrapping_sub(a),
15725        PrimitiveOp::Bnot => a.not(),
15726        PrimitiveOp::Succ => a.wrapping_add(limbs_one_7()),
15727        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_7()),
15728        PrimitiveOp::Le => {
15729            if limbs_le_7(a, b) {
15730                limbs_one_7()
15731            } else {
15732                Limbs::<7>::zero()
15733            }
15734        }
15735        PrimitiveOp::Lt => {
15736            if limbs_lt_7(a, b) {
15737                limbs_one_7()
15738            } else {
15739                Limbs::<7>::zero()
15740            }
15741        }
15742        PrimitiveOp::Ge => {
15743            if limbs_le_7(b, a) {
15744                limbs_one_7()
15745            } else {
15746                Limbs::<7>::zero()
15747            }
15748        }
15749        PrimitiveOp::Gt => {
15750            if limbs_lt_7(b, a) {
15751                limbs_one_7()
15752            } else {
15753                Limbs::<7>::zero()
15754            }
15755        }
15756        PrimitiveOp::Concat => Limbs::<7>::zero(),
15757        PrimitiveOp::Div => {
15758            if limbs_is_zero_7(b) {
15759                Limbs::<7>::zero()
15760            } else {
15761                limbs_div_7(a, b)
15762            }
15763        }
15764        PrimitiveOp::Mod => {
15765            if limbs_is_zero_7(b) {
15766                Limbs::<7>::zero()
15767            } else {
15768                limbs_mod_7(a, b)
15769            }
15770        }
15771        PrimitiveOp::Pow => limbs_pow_7(a, b),
15772    }
15773}
15774
15775#[inline]
15776#[must_use]
15777pub const fn const_ring_eval_w512(op: PrimitiveOp, a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
15778    match op {
15779        PrimitiveOp::Add => a.wrapping_add(b),
15780        PrimitiveOp::Sub => a.wrapping_sub(b),
15781        PrimitiveOp::Mul => a.wrapping_mul(b),
15782        PrimitiveOp::And => a.and(b),
15783        PrimitiveOp::Or => a.or(b),
15784        PrimitiveOp::Xor => a.xor(b),
15785        PrimitiveOp::Neg => Limbs::<8>::zero().wrapping_sub(a),
15786        PrimitiveOp::Bnot => a.not(),
15787        PrimitiveOp::Succ => a.wrapping_add(limbs_one_8()),
15788        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_8()),
15789        PrimitiveOp::Le => {
15790            if limbs_le_8(a, b) {
15791                limbs_one_8()
15792            } else {
15793                Limbs::<8>::zero()
15794            }
15795        }
15796        PrimitiveOp::Lt => {
15797            if limbs_lt_8(a, b) {
15798                limbs_one_8()
15799            } else {
15800                Limbs::<8>::zero()
15801            }
15802        }
15803        PrimitiveOp::Ge => {
15804            if limbs_le_8(b, a) {
15805                limbs_one_8()
15806            } else {
15807                Limbs::<8>::zero()
15808            }
15809        }
15810        PrimitiveOp::Gt => {
15811            if limbs_lt_8(b, a) {
15812                limbs_one_8()
15813            } else {
15814                Limbs::<8>::zero()
15815            }
15816        }
15817        PrimitiveOp::Concat => Limbs::<8>::zero(),
15818        PrimitiveOp::Div => {
15819            if limbs_is_zero_8(b) {
15820                Limbs::<8>::zero()
15821            } else {
15822                limbs_div_8(a, b)
15823            }
15824        }
15825        PrimitiveOp::Mod => {
15826            if limbs_is_zero_8(b) {
15827                Limbs::<8>::zero()
15828            } else {
15829                limbs_mod_8(a, b)
15830            }
15831        }
15832        PrimitiveOp::Pow => limbs_pow_8(a, b),
15833    }
15834}
15835
15836#[inline]
15837#[must_use]
15838pub const fn const_ring_eval_w520(op: PrimitiveOp, a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
15839    let raw = match op {
15840        PrimitiveOp::Add => a.wrapping_add(b),
15841        PrimitiveOp::Sub => a.wrapping_sub(b),
15842        PrimitiveOp::Mul => a.wrapping_mul(b),
15843        PrimitiveOp::And => a.and(b),
15844        PrimitiveOp::Or => a.or(b),
15845        PrimitiveOp::Xor => a.xor(b),
15846        PrimitiveOp::Neg => Limbs::<9>::zero().wrapping_sub(a),
15847        PrimitiveOp::Bnot => a.not(),
15848        PrimitiveOp::Succ => a.wrapping_add(limbs_one_9()),
15849        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_9()),
15850        PrimitiveOp::Le => {
15851            if limbs_le_9(a, b) {
15852                limbs_one_9()
15853            } else {
15854                Limbs::<9>::zero()
15855            }
15856        }
15857        PrimitiveOp::Lt => {
15858            if limbs_lt_9(a, b) {
15859                limbs_one_9()
15860            } else {
15861                Limbs::<9>::zero()
15862            }
15863        }
15864        PrimitiveOp::Ge => {
15865            if limbs_le_9(b, a) {
15866                limbs_one_9()
15867            } else {
15868                Limbs::<9>::zero()
15869            }
15870        }
15871        PrimitiveOp::Gt => {
15872            if limbs_lt_9(b, a) {
15873                limbs_one_9()
15874            } else {
15875                Limbs::<9>::zero()
15876            }
15877        }
15878        PrimitiveOp::Concat => Limbs::<9>::zero(),
15879        PrimitiveOp::Div => {
15880            if limbs_is_zero_9(b) {
15881                Limbs::<9>::zero()
15882            } else {
15883                limbs_div_9(a, b)
15884            }
15885        }
15886        PrimitiveOp::Mod => {
15887            if limbs_is_zero_9(b) {
15888                Limbs::<9>::zero()
15889            } else {
15890                limbs_mod_9(a, b)
15891            }
15892        }
15893        PrimitiveOp::Pow => limbs_pow_9(a, b),
15894    };
15895    raw.mask_high_bits(520)
15896}
15897
15898#[inline]
15899#[must_use]
15900pub const fn const_ring_eval_w528(op: PrimitiveOp, a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
15901    let raw = match op {
15902        PrimitiveOp::Add => a.wrapping_add(b),
15903        PrimitiveOp::Sub => a.wrapping_sub(b),
15904        PrimitiveOp::Mul => a.wrapping_mul(b),
15905        PrimitiveOp::And => a.and(b),
15906        PrimitiveOp::Or => a.or(b),
15907        PrimitiveOp::Xor => a.xor(b),
15908        PrimitiveOp::Neg => Limbs::<9>::zero().wrapping_sub(a),
15909        PrimitiveOp::Bnot => a.not(),
15910        PrimitiveOp::Succ => a.wrapping_add(limbs_one_9()),
15911        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_9()),
15912        PrimitiveOp::Le => {
15913            if limbs_le_9(a, b) {
15914                limbs_one_9()
15915            } else {
15916                Limbs::<9>::zero()
15917            }
15918        }
15919        PrimitiveOp::Lt => {
15920            if limbs_lt_9(a, b) {
15921                limbs_one_9()
15922            } else {
15923                Limbs::<9>::zero()
15924            }
15925        }
15926        PrimitiveOp::Ge => {
15927            if limbs_le_9(b, a) {
15928                limbs_one_9()
15929            } else {
15930                Limbs::<9>::zero()
15931            }
15932        }
15933        PrimitiveOp::Gt => {
15934            if limbs_lt_9(b, a) {
15935                limbs_one_9()
15936            } else {
15937                Limbs::<9>::zero()
15938            }
15939        }
15940        PrimitiveOp::Concat => Limbs::<9>::zero(),
15941        PrimitiveOp::Div => {
15942            if limbs_is_zero_9(b) {
15943                Limbs::<9>::zero()
15944            } else {
15945                limbs_div_9(a, b)
15946            }
15947        }
15948        PrimitiveOp::Mod => {
15949            if limbs_is_zero_9(b) {
15950                Limbs::<9>::zero()
15951            } else {
15952                limbs_mod_9(a, b)
15953            }
15954        }
15955        PrimitiveOp::Pow => limbs_pow_9(a, b),
15956    };
15957    raw.mask_high_bits(528)
15958}
15959
15960#[inline]
15961#[must_use]
15962pub const fn const_ring_eval_w1024(op: PrimitiveOp, a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
15963    match op {
15964        PrimitiveOp::Add => a.wrapping_add(b),
15965        PrimitiveOp::Sub => a.wrapping_sub(b),
15966        PrimitiveOp::Mul => a.wrapping_mul(b),
15967        PrimitiveOp::And => a.and(b),
15968        PrimitiveOp::Or => a.or(b),
15969        PrimitiveOp::Xor => a.xor(b),
15970        PrimitiveOp::Neg => Limbs::<16>::zero().wrapping_sub(a),
15971        PrimitiveOp::Bnot => a.not(),
15972        PrimitiveOp::Succ => a.wrapping_add(limbs_one_16()),
15973        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_16()),
15974        PrimitiveOp::Le => {
15975            if limbs_le_16(a, b) {
15976                limbs_one_16()
15977            } else {
15978                Limbs::<16>::zero()
15979            }
15980        }
15981        PrimitiveOp::Lt => {
15982            if limbs_lt_16(a, b) {
15983                limbs_one_16()
15984            } else {
15985                Limbs::<16>::zero()
15986            }
15987        }
15988        PrimitiveOp::Ge => {
15989            if limbs_le_16(b, a) {
15990                limbs_one_16()
15991            } else {
15992                Limbs::<16>::zero()
15993            }
15994        }
15995        PrimitiveOp::Gt => {
15996            if limbs_lt_16(b, a) {
15997                limbs_one_16()
15998            } else {
15999                Limbs::<16>::zero()
16000            }
16001        }
16002        PrimitiveOp::Concat => Limbs::<16>::zero(),
16003        PrimitiveOp::Div => {
16004            if limbs_is_zero_16(b) {
16005                Limbs::<16>::zero()
16006            } else {
16007                limbs_div_16(a, b)
16008            }
16009        }
16010        PrimitiveOp::Mod => {
16011            if limbs_is_zero_16(b) {
16012                Limbs::<16>::zero()
16013            } else {
16014                limbs_mod_16(a, b)
16015            }
16016        }
16017        PrimitiveOp::Pow => limbs_pow_16(a, b),
16018    }
16019}
16020
16021#[inline]
16022#[must_use]
16023pub const fn const_ring_eval_w2048(op: PrimitiveOp, a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
16024    match op {
16025        PrimitiveOp::Add => a.wrapping_add(b),
16026        PrimitiveOp::Sub => a.wrapping_sub(b),
16027        PrimitiveOp::Mul => a.wrapping_mul(b),
16028        PrimitiveOp::And => a.and(b),
16029        PrimitiveOp::Or => a.or(b),
16030        PrimitiveOp::Xor => a.xor(b),
16031        PrimitiveOp::Neg => Limbs::<32>::zero().wrapping_sub(a),
16032        PrimitiveOp::Bnot => a.not(),
16033        PrimitiveOp::Succ => a.wrapping_add(limbs_one_32()),
16034        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_32()),
16035        PrimitiveOp::Le => {
16036            if limbs_le_32(a, b) {
16037                limbs_one_32()
16038            } else {
16039                Limbs::<32>::zero()
16040            }
16041        }
16042        PrimitiveOp::Lt => {
16043            if limbs_lt_32(a, b) {
16044                limbs_one_32()
16045            } else {
16046                Limbs::<32>::zero()
16047            }
16048        }
16049        PrimitiveOp::Ge => {
16050            if limbs_le_32(b, a) {
16051                limbs_one_32()
16052            } else {
16053                Limbs::<32>::zero()
16054            }
16055        }
16056        PrimitiveOp::Gt => {
16057            if limbs_lt_32(b, a) {
16058                limbs_one_32()
16059            } else {
16060                Limbs::<32>::zero()
16061            }
16062        }
16063        PrimitiveOp::Concat => Limbs::<32>::zero(),
16064        PrimitiveOp::Div => {
16065            if limbs_is_zero_32(b) {
16066                Limbs::<32>::zero()
16067            } else {
16068                limbs_div_32(a, b)
16069            }
16070        }
16071        PrimitiveOp::Mod => {
16072            if limbs_is_zero_32(b) {
16073                Limbs::<32>::zero()
16074            } else {
16075                limbs_mod_32(a, b)
16076            }
16077        }
16078        PrimitiveOp::Pow => limbs_pow_32(a, b),
16079    }
16080}
16081
16082#[inline]
16083#[must_use]
16084pub const fn const_ring_eval_w4096(op: PrimitiveOp, a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
16085    match op {
16086        PrimitiveOp::Add => a.wrapping_add(b),
16087        PrimitiveOp::Sub => a.wrapping_sub(b),
16088        PrimitiveOp::Mul => a.wrapping_mul(b),
16089        PrimitiveOp::And => a.and(b),
16090        PrimitiveOp::Or => a.or(b),
16091        PrimitiveOp::Xor => a.xor(b),
16092        PrimitiveOp::Neg => Limbs::<64>::zero().wrapping_sub(a),
16093        PrimitiveOp::Bnot => a.not(),
16094        PrimitiveOp::Succ => a.wrapping_add(limbs_one_64()),
16095        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_64()),
16096        PrimitiveOp::Le => {
16097            if limbs_le_64(a, b) {
16098                limbs_one_64()
16099            } else {
16100                Limbs::<64>::zero()
16101            }
16102        }
16103        PrimitiveOp::Lt => {
16104            if limbs_lt_64(a, b) {
16105                limbs_one_64()
16106            } else {
16107                Limbs::<64>::zero()
16108            }
16109        }
16110        PrimitiveOp::Ge => {
16111            if limbs_le_64(b, a) {
16112                limbs_one_64()
16113            } else {
16114                Limbs::<64>::zero()
16115            }
16116        }
16117        PrimitiveOp::Gt => {
16118            if limbs_lt_64(b, a) {
16119                limbs_one_64()
16120            } else {
16121                Limbs::<64>::zero()
16122            }
16123        }
16124        PrimitiveOp::Concat => Limbs::<64>::zero(),
16125        PrimitiveOp::Div => {
16126            if limbs_is_zero_64(b) {
16127                Limbs::<64>::zero()
16128            } else {
16129                limbs_div_64(a, b)
16130            }
16131        }
16132        PrimitiveOp::Mod => {
16133            if limbs_is_zero_64(b) {
16134                Limbs::<64>::zero()
16135            } else {
16136                limbs_mod_64(a, b)
16137            }
16138        }
16139        PrimitiveOp::Pow => limbs_pow_64(a, b),
16140    }
16141}
16142
16143#[inline]
16144#[must_use]
16145pub const fn const_ring_eval_w8192(op: PrimitiveOp, a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
16146    match op {
16147        PrimitiveOp::Add => a.wrapping_add(b),
16148        PrimitiveOp::Sub => a.wrapping_sub(b),
16149        PrimitiveOp::Mul => a.wrapping_mul(b),
16150        PrimitiveOp::And => a.and(b),
16151        PrimitiveOp::Or => a.or(b),
16152        PrimitiveOp::Xor => a.xor(b),
16153        PrimitiveOp::Neg => Limbs::<128>::zero().wrapping_sub(a),
16154        PrimitiveOp::Bnot => a.not(),
16155        PrimitiveOp::Succ => a.wrapping_add(limbs_one_128()),
16156        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_128()),
16157        PrimitiveOp::Le => {
16158            if limbs_le_128(a, b) {
16159                limbs_one_128()
16160            } else {
16161                Limbs::<128>::zero()
16162            }
16163        }
16164        PrimitiveOp::Lt => {
16165            if limbs_lt_128(a, b) {
16166                limbs_one_128()
16167            } else {
16168                Limbs::<128>::zero()
16169            }
16170        }
16171        PrimitiveOp::Ge => {
16172            if limbs_le_128(b, a) {
16173                limbs_one_128()
16174            } else {
16175                Limbs::<128>::zero()
16176            }
16177        }
16178        PrimitiveOp::Gt => {
16179            if limbs_lt_128(b, a) {
16180                limbs_one_128()
16181            } else {
16182                Limbs::<128>::zero()
16183            }
16184        }
16185        PrimitiveOp::Concat => Limbs::<128>::zero(),
16186        PrimitiveOp::Div => {
16187            if limbs_is_zero_128(b) {
16188                Limbs::<128>::zero()
16189            } else {
16190                limbs_div_128(a, b)
16191            }
16192        }
16193        PrimitiveOp::Mod => {
16194            if limbs_is_zero_128(b) {
16195                Limbs::<128>::zero()
16196            } else {
16197                limbs_mod_128(a, b)
16198            }
16199        }
16200        PrimitiveOp::Pow => limbs_pow_128(a, b),
16201    }
16202}
16203
16204#[inline]
16205#[must_use]
16206pub const fn const_ring_eval_w12288(op: PrimitiveOp, a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
16207    match op {
16208        PrimitiveOp::Add => a.wrapping_add(b),
16209        PrimitiveOp::Sub => a.wrapping_sub(b),
16210        PrimitiveOp::Mul => a.wrapping_mul(b),
16211        PrimitiveOp::And => a.and(b),
16212        PrimitiveOp::Or => a.or(b),
16213        PrimitiveOp::Xor => a.xor(b),
16214        PrimitiveOp::Neg => Limbs::<192>::zero().wrapping_sub(a),
16215        PrimitiveOp::Bnot => a.not(),
16216        PrimitiveOp::Succ => a.wrapping_add(limbs_one_192()),
16217        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_192()),
16218        PrimitiveOp::Le => {
16219            if limbs_le_192(a, b) {
16220                limbs_one_192()
16221            } else {
16222                Limbs::<192>::zero()
16223            }
16224        }
16225        PrimitiveOp::Lt => {
16226            if limbs_lt_192(a, b) {
16227                limbs_one_192()
16228            } else {
16229                Limbs::<192>::zero()
16230            }
16231        }
16232        PrimitiveOp::Ge => {
16233            if limbs_le_192(b, a) {
16234                limbs_one_192()
16235            } else {
16236                Limbs::<192>::zero()
16237            }
16238        }
16239        PrimitiveOp::Gt => {
16240            if limbs_lt_192(b, a) {
16241                limbs_one_192()
16242            } else {
16243                Limbs::<192>::zero()
16244            }
16245        }
16246        PrimitiveOp::Concat => Limbs::<192>::zero(),
16247        PrimitiveOp::Div => {
16248            if limbs_is_zero_192(b) {
16249                Limbs::<192>::zero()
16250            } else {
16251                limbs_div_192(a, b)
16252            }
16253        }
16254        PrimitiveOp::Mod => {
16255            if limbs_is_zero_192(b) {
16256                Limbs::<192>::zero()
16257            } else {
16258                limbs_mod_192(a, b)
16259            }
16260        }
16261        PrimitiveOp::Pow => limbs_pow_192(a, b),
16262    }
16263}
16264
16265#[inline]
16266#[must_use]
16267pub const fn const_ring_eval_w16384(op: PrimitiveOp, a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
16268    match op {
16269        PrimitiveOp::Add => a.wrapping_add(b),
16270        PrimitiveOp::Sub => a.wrapping_sub(b),
16271        PrimitiveOp::Mul => a.wrapping_mul(b),
16272        PrimitiveOp::And => a.and(b),
16273        PrimitiveOp::Or => a.or(b),
16274        PrimitiveOp::Xor => a.xor(b),
16275        PrimitiveOp::Neg => Limbs::<256>::zero().wrapping_sub(a),
16276        PrimitiveOp::Bnot => a.not(),
16277        PrimitiveOp::Succ => a.wrapping_add(limbs_one_256()),
16278        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_256()),
16279        PrimitiveOp::Le => {
16280            if limbs_le_256(a, b) {
16281                limbs_one_256()
16282            } else {
16283                Limbs::<256>::zero()
16284            }
16285        }
16286        PrimitiveOp::Lt => {
16287            if limbs_lt_256(a, b) {
16288                limbs_one_256()
16289            } else {
16290                Limbs::<256>::zero()
16291            }
16292        }
16293        PrimitiveOp::Ge => {
16294            if limbs_le_256(b, a) {
16295                limbs_one_256()
16296            } else {
16297                Limbs::<256>::zero()
16298            }
16299        }
16300        PrimitiveOp::Gt => {
16301            if limbs_lt_256(b, a) {
16302                limbs_one_256()
16303            } else {
16304                Limbs::<256>::zero()
16305            }
16306        }
16307        PrimitiveOp::Concat => Limbs::<256>::zero(),
16308        PrimitiveOp::Div => {
16309            if limbs_is_zero_256(b) {
16310                Limbs::<256>::zero()
16311            } else {
16312                limbs_div_256(a, b)
16313            }
16314        }
16315        PrimitiveOp::Mod => {
16316            if limbs_is_zero_256(b) {
16317                Limbs::<256>::zero()
16318            } else {
16319                limbs_mod_256(a, b)
16320            }
16321        }
16322        PrimitiveOp::Pow => limbs_pow_256(a, b),
16323    }
16324}
16325
16326#[inline]
16327#[must_use]
16328pub const fn const_ring_eval_w32768(op: PrimitiveOp, a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
16329    match op {
16330        PrimitiveOp::Add => a.wrapping_add(b),
16331        PrimitiveOp::Sub => a.wrapping_sub(b),
16332        PrimitiveOp::Mul => a.wrapping_mul(b),
16333        PrimitiveOp::And => a.and(b),
16334        PrimitiveOp::Or => a.or(b),
16335        PrimitiveOp::Xor => a.xor(b),
16336        PrimitiveOp::Neg => Limbs::<512>::zero().wrapping_sub(a),
16337        PrimitiveOp::Bnot => a.not(),
16338        PrimitiveOp::Succ => a.wrapping_add(limbs_one_512()),
16339        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_512()),
16340        PrimitiveOp::Le => {
16341            if limbs_le_512(a, b) {
16342                limbs_one_512()
16343            } else {
16344                Limbs::<512>::zero()
16345            }
16346        }
16347        PrimitiveOp::Lt => {
16348            if limbs_lt_512(a, b) {
16349                limbs_one_512()
16350            } else {
16351                Limbs::<512>::zero()
16352            }
16353        }
16354        PrimitiveOp::Ge => {
16355            if limbs_le_512(b, a) {
16356                limbs_one_512()
16357            } else {
16358                Limbs::<512>::zero()
16359            }
16360        }
16361        PrimitiveOp::Gt => {
16362            if limbs_lt_512(b, a) {
16363                limbs_one_512()
16364            } else {
16365                Limbs::<512>::zero()
16366            }
16367        }
16368        PrimitiveOp::Concat => Limbs::<512>::zero(),
16369        PrimitiveOp::Div => {
16370            if limbs_is_zero_512(b) {
16371                Limbs::<512>::zero()
16372            } else {
16373                limbs_div_512(a, b)
16374            }
16375        }
16376        PrimitiveOp::Mod => {
16377            if limbs_is_zero_512(b) {
16378                Limbs::<512>::zero()
16379            } else {
16380                limbs_mod_512(a, b)
16381            }
16382        }
16383        PrimitiveOp::Pow => limbs_pow_512(a, b),
16384    }
16385}
16386
16387/// Phase L.2: one-constant helpers for `Limbs<N>::from_words([1, 0, ...])`.
16388#[inline]
16389#[must_use]
16390const fn limbs_one_3() -> Limbs<3> {
16391    Limbs::<3>::from_words([1u64, 0u64, 0u64])
16392}
16393
16394#[inline]
16395#[must_use]
16396const fn limbs_one_4() -> Limbs<4> {
16397    Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64])
16398}
16399
16400#[inline]
16401#[must_use]
16402const fn limbs_one_6() -> Limbs<6> {
16403    Limbs::<6>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16404}
16405
16406#[inline]
16407#[must_use]
16408const fn limbs_one_7() -> Limbs<7> {
16409    Limbs::<7>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16410}
16411
16412#[inline]
16413#[must_use]
16414const fn limbs_one_8() -> Limbs<8> {
16415    Limbs::<8>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16416}
16417
16418#[inline]
16419#[must_use]
16420const fn limbs_one_9() -> Limbs<9> {
16421    Limbs::<9>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16422}
16423
16424#[inline]
16425#[must_use]
16426const fn limbs_one_16() -> Limbs<16> {
16427    Limbs::<16>::from_words([
16428        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16429        0u64,
16430    ])
16431}
16432
16433#[inline]
16434#[must_use]
16435const fn limbs_one_32() -> Limbs<32> {
16436    Limbs::<32>::from_words([
16437        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16438        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16439        0u64, 0u64,
16440    ])
16441}
16442
16443#[inline]
16444#[must_use]
16445const fn limbs_one_64() -> Limbs<64> {
16446    Limbs::<64>::from_words([
16447        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16448        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16449        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16450        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16451        0u64, 0u64, 0u64, 0u64,
16452    ])
16453}
16454
16455#[inline]
16456#[must_use]
16457const fn limbs_one_128() -> Limbs<128> {
16458    Limbs::<128>::from_words([
16459        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16460        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16461        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16462        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16463        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16464        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16465        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16466        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16467        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16468    ])
16469}
16470
16471#[inline]
16472#[must_use]
16473const fn limbs_one_192() -> Limbs<192> {
16474    Limbs::<192>::from_words([
16475        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16476        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16477        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16478        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16479        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16480        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16481        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16482        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16483        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16484        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16485        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16486        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16487        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16488    ])
16489}
16490
16491#[inline]
16492#[must_use]
16493const fn limbs_one_256() -> Limbs<256> {
16494    Limbs::<256>::from_words([
16495        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16496        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16497        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16498        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16499        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16500        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16501        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16502        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16503        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16504        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16505        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16506        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16507        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16508        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16509        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16510        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16511        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16512        0u64,
16513    ])
16514}
16515
16516#[inline]
16517#[must_use]
16518const fn limbs_one_512() -> Limbs<512> {
16519    Limbs::<512>::from_words([
16520        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16521        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16522        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16523        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16524        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16525        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16526        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16527        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16528        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16529        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16530        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16531        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16532        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16533        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16534        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16535        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16536        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16537        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16538        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16539        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16540        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16541        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16542        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16543        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16544        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16545        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16546        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16547        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16548        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16549        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16550        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16551        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16552        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16553        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16554        0u64, 0u64,
16555    ])
16556}
16557
16558/// ADR-013/TR-08: const-fn limb comparisons used by `const_ring_eval_w{n}`
16559/// to lift the comparison primitives to 0/1-valued ring indicators.
16560#[inline]
16561#[must_use]
16562const fn limbs_lt_3(a: Limbs<3>, b: Limbs<3>) -> bool {
16563    let aw = a.words();
16564    let bw = b.words();
16565    let mut i = 3;
16566    while i > 0 {
16567        i -= 1;
16568        if aw[i] < bw[i] {
16569            return true;
16570        }
16571        if aw[i] > bw[i] {
16572            return false;
16573        }
16574    }
16575    false
16576}
16577
16578#[inline]
16579#[must_use]
16580const fn limbs_le_3(a: Limbs<3>, b: Limbs<3>) -> bool {
16581    let aw = a.words();
16582    let bw = b.words();
16583    let mut i = 3;
16584    while i > 0 {
16585        i -= 1;
16586        if aw[i] < bw[i] {
16587            return true;
16588        }
16589        if aw[i] > bw[i] {
16590            return false;
16591        }
16592    }
16593    true
16594}
16595
16596#[inline]
16597#[must_use]
16598const fn limbs_lt_4(a: Limbs<4>, b: Limbs<4>) -> bool {
16599    let aw = a.words();
16600    let bw = b.words();
16601    let mut i = 4;
16602    while i > 0 {
16603        i -= 1;
16604        if aw[i] < bw[i] {
16605            return true;
16606        }
16607        if aw[i] > bw[i] {
16608            return false;
16609        }
16610    }
16611    false
16612}
16613
16614#[inline]
16615#[must_use]
16616const fn limbs_le_4(a: Limbs<4>, b: Limbs<4>) -> bool {
16617    let aw = a.words();
16618    let bw = b.words();
16619    let mut i = 4;
16620    while i > 0 {
16621        i -= 1;
16622        if aw[i] < bw[i] {
16623            return true;
16624        }
16625        if aw[i] > bw[i] {
16626            return false;
16627        }
16628    }
16629    true
16630}
16631
16632#[inline]
16633#[must_use]
16634const fn limbs_lt_6(a: Limbs<6>, b: Limbs<6>) -> bool {
16635    let aw = a.words();
16636    let bw = b.words();
16637    let mut i = 6;
16638    while i > 0 {
16639        i -= 1;
16640        if aw[i] < bw[i] {
16641            return true;
16642        }
16643        if aw[i] > bw[i] {
16644            return false;
16645        }
16646    }
16647    false
16648}
16649
16650#[inline]
16651#[must_use]
16652const fn limbs_le_6(a: Limbs<6>, b: Limbs<6>) -> bool {
16653    let aw = a.words();
16654    let bw = b.words();
16655    let mut i = 6;
16656    while i > 0 {
16657        i -= 1;
16658        if aw[i] < bw[i] {
16659            return true;
16660        }
16661        if aw[i] > bw[i] {
16662            return false;
16663        }
16664    }
16665    true
16666}
16667
16668#[inline]
16669#[must_use]
16670const fn limbs_lt_7(a: Limbs<7>, b: Limbs<7>) -> bool {
16671    let aw = a.words();
16672    let bw = b.words();
16673    let mut i = 7;
16674    while i > 0 {
16675        i -= 1;
16676        if aw[i] < bw[i] {
16677            return true;
16678        }
16679        if aw[i] > bw[i] {
16680            return false;
16681        }
16682    }
16683    false
16684}
16685
16686#[inline]
16687#[must_use]
16688const fn limbs_le_7(a: Limbs<7>, b: Limbs<7>) -> bool {
16689    let aw = a.words();
16690    let bw = b.words();
16691    let mut i = 7;
16692    while i > 0 {
16693        i -= 1;
16694        if aw[i] < bw[i] {
16695            return true;
16696        }
16697        if aw[i] > bw[i] {
16698            return false;
16699        }
16700    }
16701    true
16702}
16703
16704#[inline]
16705#[must_use]
16706const fn limbs_lt_8(a: Limbs<8>, b: Limbs<8>) -> bool {
16707    let aw = a.words();
16708    let bw = b.words();
16709    let mut i = 8;
16710    while i > 0 {
16711        i -= 1;
16712        if aw[i] < bw[i] {
16713            return true;
16714        }
16715        if aw[i] > bw[i] {
16716            return false;
16717        }
16718    }
16719    false
16720}
16721
16722#[inline]
16723#[must_use]
16724const fn limbs_le_8(a: Limbs<8>, b: Limbs<8>) -> bool {
16725    let aw = a.words();
16726    let bw = b.words();
16727    let mut i = 8;
16728    while i > 0 {
16729        i -= 1;
16730        if aw[i] < bw[i] {
16731            return true;
16732        }
16733        if aw[i] > bw[i] {
16734            return false;
16735        }
16736    }
16737    true
16738}
16739
16740#[inline]
16741#[must_use]
16742const fn limbs_lt_9(a: Limbs<9>, b: Limbs<9>) -> bool {
16743    let aw = a.words();
16744    let bw = b.words();
16745    let mut i = 9;
16746    while i > 0 {
16747        i -= 1;
16748        if aw[i] < bw[i] {
16749            return true;
16750        }
16751        if aw[i] > bw[i] {
16752            return false;
16753        }
16754    }
16755    false
16756}
16757
16758#[inline]
16759#[must_use]
16760const fn limbs_le_9(a: Limbs<9>, b: Limbs<9>) -> bool {
16761    let aw = a.words();
16762    let bw = b.words();
16763    let mut i = 9;
16764    while i > 0 {
16765        i -= 1;
16766        if aw[i] < bw[i] {
16767            return true;
16768        }
16769        if aw[i] > bw[i] {
16770            return false;
16771        }
16772    }
16773    true
16774}
16775
16776#[inline]
16777#[must_use]
16778const fn limbs_lt_16(a: Limbs<16>, b: Limbs<16>) -> bool {
16779    let aw = a.words();
16780    let bw = b.words();
16781    let mut i = 16;
16782    while i > 0 {
16783        i -= 1;
16784        if aw[i] < bw[i] {
16785            return true;
16786        }
16787        if aw[i] > bw[i] {
16788            return false;
16789        }
16790    }
16791    false
16792}
16793
16794#[inline]
16795#[must_use]
16796const fn limbs_le_16(a: Limbs<16>, b: Limbs<16>) -> bool {
16797    let aw = a.words();
16798    let bw = b.words();
16799    let mut i = 16;
16800    while i > 0 {
16801        i -= 1;
16802        if aw[i] < bw[i] {
16803            return true;
16804        }
16805        if aw[i] > bw[i] {
16806            return false;
16807        }
16808    }
16809    true
16810}
16811
16812#[inline]
16813#[must_use]
16814const fn limbs_lt_32(a: Limbs<32>, b: Limbs<32>) -> bool {
16815    let aw = a.words();
16816    let bw = b.words();
16817    let mut i = 32;
16818    while i > 0 {
16819        i -= 1;
16820        if aw[i] < bw[i] {
16821            return true;
16822        }
16823        if aw[i] > bw[i] {
16824            return false;
16825        }
16826    }
16827    false
16828}
16829
16830#[inline]
16831#[must_use]
16832const fn limbs_le_32(a: Limbs<32>, b: Limbs<32>) -> bool {
16833    let aw = a.words();
16834    let bw = b.words();
16835    let mut i = 32;
16836    while i > 0 {
16837        i -= 1;
16838        if aw[i] < bw[i] {
16839            return true;
16840        }
16841        if aw[i] > bw[i] {
16842            return false;
16843        }
16844    }
16845    true
16846}
16847
16848#[inline]
16849#[must_use]
16850const fn limbs_lt_64(a: Limbs<64>, b: Limbs<64>) -> bool {
16851    let aw = a.words();
16852    let bw = b.words();
16853    let mut i = 64;
16854    while i > 0 {
16855        i -= 1;
16856        if aw[i] < bw[i] {
16857            return true;
16858        }
16859        if aw[i] > bw[i] {
16860            return false;
16861        }
16862    }
16863    false
16864}
16865
16866#[inline]
16867#[must_use]
16868const fn limbs_le_64(a: Limbs<64>, b: Limbs<64>) -> bool {
16869    let aw = a.words();
16870    let bw = b.words();
16871    let mut i = 64;
16872    while i > 0 {
16873        i -= 1;
16874        if aw[i] < bw[i] {
16875            return true;
16876        }
16877        if aw[i] > bw[i] {
16878            return false;
16879        }
16880    }
16881    true
16882}
16883
16884#[inline]
16885#[must_use]
16886const fn limbs_lt_128(a: Limbs<128>, b: Limbs<128>) -> bool {
16887    let aw = a.words();
16888    let bw = b.words();
16889    let mut i = 128;
16890    while i > 0 {
16891        i -= 1;
16892        if aw[i] < bw[i] {
16893            return true;
16894        }
16895        if aw[i] > bw[i] {
16896            return false;
16897        }
16898    }
16899    false
16900}
16901
16902#[inline]
16903#[must_use]
16904const fn limbs_le_128(a: Limbs<128>, b: Limbs<128>) -> bool {
16905    let aw = a.words();
16906    let bw = b.words();
16907    let mut i = 128;
16908    while i > 0 {
16909        i -= 1;
16910        if aw[i] < bw[i] {
16911            return true;
16912        }
16913        if aw[i] > bw[i] {
16914            return false;
16915        }
16916    }
16917    true
16918}
16919
16920#[inline]
16921#[must_use]
16922const fn limbs_lt_192(a: Limbs<192>, b: Limbs<192>) -> bool {
16923    let aw = a.words();
16924    let bw = b.words();
16925    let mut i = 192;
16926    while i > 0 {
16927        i -= 1;
16928        if aw[i] < bw[i] {
16929            return true;
16930        }
16931        if aw[i] > bw[i] {
16932            return false;
16933        }
16934    }
16935    false
16936}
16937
16938#[inline]
16939#[must_use]
16940const fn limbs_le_192(a: Limbs<192>, b: Limbs<192>) -> bool {
16941    let aw = a.words();
16942    let bw = b.words();
16943    let mut i = 192;
16944    while i > 0 {
16945        i -= 1;
16946        if aw[i] < bw[i] {
16947            return true;
16948        }
16949        if aw[i] > bw[i] {
16950            return false;
16951        }
16952    }
16953    true
16954}
16955
16956#[inline]
16957#[must_use]
16958const fn limbs_lt_256(a: Limbs<256>, b: Limbs<256>) -> bool {
16959    let aw = a.words();
16960    let bw = b.words();
16961    let mut i = 256;
16962    while i > 0 {
16963        i -= 1;
16964        if aw[i] < bw[i] {
16965            return true;
16966        }
16967        if aw[i] > bw[i] {
16968            return false;
16969        }
16970    }
16971    false
16972}
16973
16974#[inline]
16975#[must_use]
16976const fn limbs_le_256(a: Limbs<256>, b: Limbs<256>) -> bool {
16977    let aw = a.words();
16978    let bw = b.words();
16979    let mut i = 256;
16980    while i > 0 {
16981        i -= 1;
16982        if aw[i] < bw[i] {
16983            return true;
16984        }
16985        if aw[i] > bw[i] {
16986            return false;
16987        }
16988    }
16989    true
16990}
16991
16992#[inline]
16993#[must_use]
16994const fn limbs_lt_512(a: Limbs<512>, b: Limbs<512>) -> bool {
16995    let aw = a.words();
16996    let bw = b.words();
16997    let mut i = 512;
16998    while i > 0 {
16999        i -= 1;
17000        if aw[i] < bw[i] {
17001            return true;
17002        }
17003        if aw[i] > bw[i] {
17004            return false;
17005        }
17006    }
17007    false
17008}
17009
17010#[inline]
17011#[must_use]
17012const fn limbs_le_512(a: Limbs<512>, b: Limbs<512>) -> bool {
17013    let aw = a.words();
17014    let bw = b.words();
17015    let mut i = 512;
17016    while i > 0 {
17017        i -= 1;
17018        if aw[i] < bw[i] {
17019            return true;
17020        }
17021        if aw[i] > bw[i] {
17022            return false;
17023        }
17024    }
17025    true
17026}
17027
17028/// ADR-053: zero-check, binary-long-division, and square-and-multiply
17029/// helpers used by the const-fn `Div`/`Mod`/`Pow` arms of `const_ring_eval_w{n}`.
17030#[inline]
17031#[must_use]
17032const fn limbs_is_zero_3(a: Limbs<3>) -> bool {
17033    let aw = a.words();
17034    let mut i = 0usize;
17035    while i < 3 {
17036        if aw[i] != 0 {
17037            return false;
17038        }
17039        i += 1;
17040    }
17041    true
17042}
17043
17044#[inline]
17045#[must_use]
17046const fn limbs_shl1_3(a: Limbs<3>) -> Limbs<3> {
17047    let aw = a.words();
17048    let mut out = [0u64; 3];
17049    let mut carry: u64 = 0;
17050    let mut i = 0usize;
17051    while i < 3 {
17052        let v = aw[i];
17053        out[i] = (v << 1) | carry;
17054        carry = v >> 63;
17055        i += 1;
17056    }
17057    Limbs::<3>::from_words(out)
17058}
17059
17060#[inline]
17061#[must_use]
17062const fn limbs_set_bit0_3(a: Limbs<3>) -> Limbs<3> {
17063    let aw = a.words();
17064    let mut out = [0u64; 3];
17065    let mut i = 0usize;
17066    while i < 3 {
17067        out[i] = aw[i];
17068        i += 1;
17069    }
17070    out[0] |= 1u64;
17071    Limbs::<3>::from_words(out)
17072}
17073
17074#[inline]
17075#[must_use]
17076const fn limbs_bit_msb_3(a: Limbs<3>, msb_index: usize) -> u64 {
17077    let aw = a.words();
17078    let total_bits = 3 * 64;
17079    let lsb_index = total_bits - 1 - msb_index;
17080    let word = lsb_index / 64;
17081    let bit = lsb_index % 64;
17082    (aw[word] >> bit) & 1u64
17083}
17084
17085#[inline]
17086#[must_use]
17087const fn limbs_divmod_3(a: Limbs<3>, b: Limbs<3>) -> (Limbs<3>, Limbs<3>) {
17088    let mut q = Limbs::<3>::zero();
17089    let mut r = Limbs::<3>::zero();
17090    let total_bits = 3 * 64;
17091    let mut i = 0usize;
17092    while i < total_bits {
17093        r = limbs_shl1_3(r);
17094        if limbs_bit_msb_3(a, i) == 1 {
17095            r = limbs_set_bit0_3(r);
17096        }
17097        if limbs_le_3(b, r) {
17098            r = r.wrapping_sub(b);
17099            q = limbs_shl1_3(q);
17100            q = limbs_set_bit0_3(q);
17101        } else {
17102            q = limbs_shl1_3(q);
17103        }
17104        i += 1;
17105    }
17106    (q, r)
17107}
17108
17109#[inline]
17110#[must_use]
17111const fn limbs_div_3(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
17112    let (q, _) = limbs_divmod_3(a, b);
17113    q
17114}
17115
17116#[inline]
17117#[must_use]
17118const fn limbs_mod_3(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
17119    let (_, r) = limbs_divmod_3(a, b);
17120    r
17121}
17122
17123#[inline]
17124#[must_use]
17125const fn limbs_pow_3(base: Limbs<3>, exp: Limbs<3>) -> Limbs<3> {
17126    let mut result = limbs_one_3();
17127    let mut b = base;
17128    let ew = exp.words();
17129    let mut word = 0usize;
17130    while word < 3 {
17131        let mut bit = 0u32;
17132        while bit < 64 {
17133            if ((ew[word] >> bit) & 1u64) == 1u64 {
17134                result = result.wrapping_mul(b);
17135            }
17136            b = b.wrapping_mul(b);
17137            bit += 1;
17138        }
17139        word += 1;
17140    }
17141    result
17142}
17143
17144#[inline]
17145#[must_use]
17146const fn limbs_is_zero_4(a: Limbs<4>) -> bool {
17147    let aw = a.words();
17148    let mut i = 0usize;
17149    while i < 4 {
17150        if aw[i] != 0 {
17151            return false;
17152        }
17153        i += 1;
17154    }
17155    true
17156}
17157
17158#[inline]
17159#[must_use]
17160const fn limbs_shl1_4(a: Limbs<4>) -> Limbs<4> {
17161    let aw = a.words();
17162    let mut out = [0u64; 4];
17163    let mut carry: u64 = 0;
17164    let mut i = 0usize;
17165    while i < 4 {
17166        let v = aw[i];
17167        out[i] = (v << 1) | carry;
17168        carry = v >> 63;
17169        i += 1;
17170    }
17171    Limbs::<4>::from_words(out)
17172}
17173
17174#[inline]
17175#[must_use]
17176const fn limbs_set_bit0_4(a: Limbs<4>) -> Limbs<4> {
17177    let aw = a.words();
17178    let mut out = [0u64; 4];
17179    let mut i = 0usize;
17180    while i < 4 {
17181        out[i] = aw[i];
17182        i += 1;
17183    }
17184    out[0] |= 1u64;
17185    Limbs::<4>::from_words(out)
17186}
17187
17188#[inline]
17189#[must_use]
17190const fn limbs_bit_msb_4(a: Limbs<4>, msb_index: usize) -> u64 {
17191    let aw = a.words();
17192    let total_bits = 4 * 64;
17193    let lsb_index = total_bits - 1 - msb_index;
17194    let word = lsb_index / 64;
17195    let bit = lsb_index % 64;
17196    (aw[word] >> bit) & 1u64
17197}
17198
17199#[inline]
17200#[must_use]
17201const fn limbs_divmod_4(a: Limbs<4>, b: Limbs<4>) -> (Limbs<4>, Limbs<4>) {
17202    let mut q = Limbs::<4>::zero();
17203    let mut r = Limbs::<4>::zero();
17204    let total_bits = 4 * 64;
17205    let mut i = 0usize;
17206    while i < total_bits {
17207        r = limbs_shl1_4(r);
17208        if limbs_bit_msb_4(a, i) == 1 {
17209            r = limbs_set_bit0_4(r);
17210        }
17211        if limbs_le_4(b, r) {
17212            r = r.wrapping_sub(b);
17213            q = limbs_shl1_4(q);
17214            q = limbs_set_bit0_4(q);
17215        } else {
17216            q = limbs_shl1_4(q);
17217        }
17218        i += 1;
17219    }
17220    (q, r)
17221}
17222
17223#[inline]
17224#[must_use]
17225const fn limbs_div_4(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
17226    let (q, _) = limbs_divmod_4(a, b);
17227    q
17228}
17229
17230#[inline]
17231#[must_use]
17232const fn limbs_mod_4(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
17233    let (_, r) = limbs_divmod_4(a, b);
17234    r
17235}
17236
17237#[inline]
17238#[must_use]
17239const fn limbs_pow_4(base: Limbs<4>, exp: Limbs<4>) -> Limbs<4> {
17240    let mut result = limbs_one_4();
17241    let mut b = base;
17242    let ew = exp.words();
17243    let mut word = 0usize;
17244    while word < 4 {
17245        let mut bit = 0u32;
17246        while bit < 64 {
17247            if ((ew[word] >> bit) & 1u64) == 1u64 {
17248                result = result.wrapping_mul(b);
17249            }
17250            b = b.wrapping_mul(b);
17251            bit += 1;
17252        }
17253        word += 1;
17254    }
17255    result
17256}
17257
17258#[inline]
17259#[must_use]
17260const fn limbs_is_zero_6(a: Limbs<6>) -> bool {
17261    let aw = a.words();
17262    let mut i = 0usize;
17263    while i < 6 {
17264        if aw[i] != 0 {
17265            return false;
17266        }
17267        i += 1;
17268    }
17269    true
17270}
17271
17272#[inline]
17273#[must_use]
17274const fn limbs_shl1_6(a: Limbs<6>) -> Limbs<6> {
17275    let aw = a.words();
17276    let mut out = [0u64; 6];
17277    let mut carry: u64 = 0;
17278    let mut i = 0usize;
17279    while i < 6 {
17280        let v = aw[i];
17281        out[i] = (v << 1) | carry;
17282        carry = v >> 63;
17283        i += 1;
17284    }
17285    Limbs::<6>::from_words(out)
17286}
17287
17288#[inline]
17289#[must_use]
17290const fn limbs_set_bit0_6(a: Limbs<6>) -> Limbs<6> {
17291    let aw = a.words();
17292    let mut out = [0u64; 6];
17293    let mut i = 0usize;
17294    while i < 6 {
17295        out[i] = aw[i];
17296        i += 1;
17297    }
17298    out[0] |= 1u64;
17299    Limbs::<6>::from_words(out)
17300}
17301
17302#[inline]
17303#[must_use]
17304const fn limbs_bit_msb_6(a: Limbs<6>, msb_index: usize) -> u64 {
17305    let aw = a.words();
17306    let total_bits = 6 * 64;
17307    let lsb_index = total_bits - 1 - msb_index;
17308    let word = lsb_index / 64;
17309    let bit = lsb_index % 64;
17310    (aw[word] >> bit) & 1u64
17311}
17312
17313#[inline]
17314#[must_use]
17315const fn limbs_divmod_6(a: Limbs<6>, b: Limbs<6>) -> (Limbs<6>, Limbs<6>) {
17316    let mut q = Limbs::<6>::zero();
17317    let mut r = Limbs::<6>::zero();
17318    let total_bits = 6 * 64;
17319    let mut i = 0usize;
17320    while i < total_bits {
17321        r = limbs_shl1_6(r);
17322        if limbs_bit_msb_6(a, i) == 1 {
17323            r = limbs_set_bit0_6(r);
17324        }
17325        if limbs_le_6(b, r) {
17326            r = r.wrapping_sub(b);
17327            q = limbs_shl1_6(q);
17328            q = limbs_set_bit0_6(q);
17329        } else {
17330            q = limbs_shl1_6(q);
17331        }
17332        i += 1;
17333    }
17334    (q, r)
17335}
17336
17337#[inline]
17338#[must_use]
17339const fn limbs_div_6(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
17340    let (q, _) = limbs_divmod_6(a, b);
17341    q
17342}
17343
17344#[inline]
17345#[must_use]
17346const fn limbs_mod_6(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
17347    let (_, r) = limbs_divmod_6(a, b);
17348    r
17349}
17350
17351#[inline]
17352#[must_use]
17353const fn limbs_pow_6(base: Limbs<6>, exp: Limbs<6>) -> Limbs<6> {
17354    let mut result = limbs_one_6();
17355    let mut b = base;
17356    let ew = exp.words();
17357    let mut word = 0usize;
17358    while word < 6 {
17359        let mut bit = 0u32;
17360        while bit < 64 {
17361            if ((ew[word] >> bit) & 1u64) == 1u64 {
17362                result = result.wrapping_mul(b);
17363            }
17364            b = b.wrapping_mul(b);
17365            bit += 1;
17366        }
17367        word += 1;
17368    }
17369    result
17370}
17371
17372#[inline]
17373#[must_use]
17374const fn limbs_is_zero_7(a: Limbs<7>) -> bool {
17375    let aw = a.words();
17376    let mut i = 0usize;
17377    while i < 7 {
17378        if aw[i] != 0 {
17379            return false;
17380        }
17381        i += 1;
17382    }
17383    true
17384}
17385
17386#[inline]
17387#[must_use]
17388const fn limbs_shl1_7(a: Limbs<7>) -> Limbs<7> {
17389    let aw = a.words();
17390    let mut out = [0u64; 7];
17391    let mut carry: u64 = 0;
17392    let mut i = 0usize;
17393    while i < 7 {
17394        let v = aw[i];
17395        out[i] = (v << 1) | carry;
17396        carry = v >> 63;
17397        i += 1;
17398    }
17399    Limbs::<7>::from_words(out)
17400}
17401
17402#[inline]
17403#[must_use]
17404const fn limbs_set_bit0_7(a: Limbs<7>) -> Limbs<7> {
17405    let aw = a.words();
17406    let mut out = [0u64; 7];
17407    let mut i = 0usize;
17408    while i < 7 {
17409        out[i] = aw[i];
17410        i += 1;
17411    }
17412    out[0] |= 1u64;
17413    Limbs::<7>::from_words(out)
17414}
17415
17416#[inline]
17417#[must_use]
17418const fn limbs_bit_msb_7(a: Limbs<7>, msb_index: usize) -> u64 {
17419    let aw = a.words();
17420    let total_bits = 7 * 64;
17421    let lsb_index = total_bits - 1 - msb_index;
17422    let word = lsb_index / 64;
17423    let bit = lsb_index % 64;
17424    (aw[word] >> bit) & 1u64
17425}
17426
17427#[inline]
17428#[must_use]
17429const fn limbs_divmod_7(a: Limbs<7>, b: Limbs<7>) -> (Limbs<7>, Limbs<7>) {
17430    let mut q = Limbs::<7>::zero();
17431    let mut r = Limbs::<7>::zero();
17432    let total_bits = 7 * 64;
17433    let mut i = 0usize;
17434    while i < total_bits {
17435        r = limbs_shl1_7(r);
17436        if limbs_bit_msb_7(a, i) == 1 {
17437            r = limbs_set_bit0_7(r);
17438        }
17439        if limbs_le_7(b, r) {
17440            r = r.wrapping_sub(b);
17441            q = limbs_shl1_7(q);
17442            q = limbs_set_bit0_7(q);
17443        } else {
17444            q = limbs_shl1_7(q);
17445        }
17446        i += 1;
17447    }
17448    (q, r)
17449}
17450
17451#[inline]
17452#[must_use]
17453const fn limbs_div_7(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
17454    let (q, _) = limbs_divmod_7(a, b);
17455    q
17456}
17457
17458#[inline]
17459#[must_use]
17460const fn limbs_mod_7(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
17461    let (_, r) = limbs_divmod_7(a, b);
17462    r
17463}
17464
17465#[inline]
17466#[must_use]
17467const fn limbs_pow_7(base: Limbs<7>, exp: Limbs<7>) -> Limbs<7> {
17468    let mut result = limbs_one_7();
17469    let mut b = base;
17470    let ew = exp.words();
17471    let mut word = 0usize;
17472    while word < 7 {
17473        let mut bit = 0u32;
17474        while bit < 64 {
17475            if ((ew[word] >> bit) & 1u64) == 1u64 {
17476                result = result.wrapping_mul(b);
17477            }
17478            b = b.wrapping_mul(b);
17479            bit += 1;
17480        }
17481        word += 1;
17482    }
17483    result
17484}
17485
17486#[inline]
17487#[must_use]
17488const fn limbs_is_zero_8(a: Limbs<8>) -> bool {
17489    let aw = a.words();
17490    let mut i = 0usize;
17491    while i < 8 {
17492        if aw[i] != 0 {
17493            return false;
17494        }
17495        i += 1;
17496    }
17497    true
17498}
17499
17500#[inline]
17501#[must_use]
17502const fn limbs_shl1_8(a: Limbs<8>) -> Limbs<8> {
17503    let aw = a.words();
17504    let mut out = [0u64; 8];
17505    let mut carry: u64 = 0;
17506    let mut i = 0usize;
17507    while i < 8 {
17508        let v = aw[i];
17509        out[i] = (v << 1) | carry;
17510        carry = v >> 63;
17511        i += 1;
17512    }
17513    Limbs::<8>::from_words(out)
17514}
17515
17516#[inline]
17517#[must_use]
17518const fn limbs_set_bit0_8(a: Limbs<8>) -> Limbs<8> {
17519    let aw = a.words();
17520    let mut out = [0u64; 8];
17521    let mut i = 0usize;
17522    while i < 8 {
17523        out[i] = aw[i];
17524        i += 1;
17525    }
17526    out[0] |= 1u64;
17527    Limbs::<8>::from_words(out)
17528}
17529
17530#[inline]
17531#[must_use]
17532const fn limbs_bit_msb_8(a: Limbs<8>, msb_index: usize) -> u64 {
17533    let aw = a.words();
17534    let total_bits = 8 * 64;
17535    let lsb_index = total_bits - 1 - msb_index;
17536    let word = lsb_index / 64;
17537    let bit = lsb_index % 64;
17538    (aw[word] >> bit) & 1u64
17539}
17540
17541#[inline]
17542#[must_use]
17543const fn limbs_divmod_8(a: Limbs<8>, b: Limbs<8>) -> (Limbs<8>, Limbs<8>) {
17544    let mut q = Limbs::<8>::zero();
17545    let mut r = Limbs::<8>::zero();
17546    let total_bits = 8 * 64;
17547    let mut i = 0usize;
17548    while i < total_bits {
17549        r = limbs_shl1_8(r);
17550        if limbs_bit_msb_8(a, i) == 1 {
17551            r = limbs_set_bit0_8(r);
17552        }
17553        if limbs_le_8(b, r) {
17554            r = r.wrapping_sub(b);
17555            q = limbs_shl1_8(q);
17556            q = limbs_set_bit0_8(q);
17557        } else {
17558            q = limbs_shl1_8(q);
17559        }
17560        i += 1;
17561    }
17562    (q, r)
17563}
17564
17565#[inline]
17566#[must_use]
17567const fn limbs_div_8(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
17568    let (q, _) = limbs_divmod_8(a, b);
17569    q
17570}
17571
17572#[inline]
17573#[must_use]
17574const fn limbs_mod_8(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
17575    let (_, r) = limbs_divmod_8(a, b);
17576    r
17577}
17578
17579#[inline]
17580#[must_use]
17581const fn limbs_pow_8(base: Limbs<8>, exp: Limbs<8>) -> Limbs<8> {
17582    let mut result = limbs_one_8();
17583    let mut b = base;
17584    let ew = exp.words();
17585    let mut word = 0usize;
17586    while word < 8 {
17587        let mut bit = 0u32;
17588        while bit < 64 {
17589            if ((ew[word] >> bit) & 1u64) == 1u64 {
17590                result = result.wrapping_mul(b);
17591            }
17592            b = b.wrapping_mul(b);
17593            bit += 1;
17594        }
17595        word += 1;
17596    }
17597    result
17598}
17599
17600#[inline]
17601#[must_use]
17602const fn limbs_is_zero_9(a: Limbs<9>) -> bool {
17603    let aw = a.words();
17604    let mut i = 0usize;
17605    while i < 9 {
17606        if aw[i] != 0 {
17607            return false;
17608        }
17609        i += 1;
17610    }
17611    true
17612}
17613
17614#[inline]
17615#[must_use]
17616const fn limbs_shl1_9(a: Limbs<9>) -> Limbs<9> {
17617    let aw = a.words();
17618    let mut out = [0u64; 9];
17619    let mut carry: u64 = 0;
17620    let mut i = 0usize;
17621    while i < 9 {
17622        let v = aw[i];
17623        out[i] = (v << 1) | carry;
17624        carry = v >> 63;
17625        i += 1;
17626    }
17627    Limbs::<9>::from_words(out)
17628}
17629
17630#[inline]
17631#[must_use]
17632const fn limbs_set_bit0_9(a: Limbs<9>) -> Limbs<9> {
17633    let aw = a.words();
17634    let mut out = [0u64; 9];
17635    let mut i = 0usize;
17636    while i < 9 {
17637        out[i] = aw[i];
17638        i += 1;
17639    }
17640    out[0] |= 1u64;
17641    Limbs::<9>::from_words(out)
17642}
17643
17644#[inline]
17645#[must_use]
17646const fn limbs_bit_msb_9(a: Limbs<9>, msb_index: usize) -> u64 {
17647    let aw = a.words();
17648    let total_bits = 9 * 64;
17649    let lsb_index = total_bits - 1 - msb_index;
17650    let word = lsb_index / 64;
17651    let bit = lsb_index % 64;
17652    (aw[word] >> bit) & 1u64
17653}
17654
17655#[inline]
17656#[must_use]
17657const fn limbs_divmod_9(a: Limbs<9>, b: Limbs<9>) -> (Limbs<9>, Limbs<9>) {
17658    let mut q = Limbs::<9>::zero();
17659    let mut r = Limbs::<9>::zero();
17660    let total_bits = 9 * 64;
17661    let mut i = 0usize;
17662    while i < total_bits {
17663        r = limbs_shl1_9(r);
17664        if limbs_bit_msb_9(a, i) == 1 {
17665            r = limbs_set_bit0_9(r);
17666        }
17667        if limbs_le_9(b, r) {
17668            r = r.wrapping_sub(b);
17669            q = limbs_shl1_9(q);
17670            q = limbs_set_bit0_9(q);
17671        } else {
17672            q = limbs_shl1_9(q);
17673        }
17674        i += 1;
17675    }
17676    (q, r)
17677}
17678
17679#[inline]
17680#[must_use]
17681const fn limbs_div_9(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
17682    let (q, _) = limbs_divmod_9(a, b);
17683    q
17684}
17685
17686#[inline]
17687#[must_use]
17688const fn limbs_mod_9(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
17689    let (_, r) = limbs_divmod_9(a, b);
17690    r
17691}
17692
17693#[inline]
17694#[must_use]
17695const fn limbs_pow_9(base: Limbs<9>, exp: Limbs<9>) -> Limbs<9> {
17696    let mut result = limbs_one_9();
17697    let mut b = base;
17698    let ew = exp.words();
17699    let mut word = 0usize;
17700    while word < 9 {
17701        let mut bit = 0u32;
17702        while bit < 64 {
17703            if ((ew[word] >> bit) & 1u64) == 1u64 {
17704                result = result.wrapping_mul(b);
17705            }
17706            b = b.wrapping_mul(b);
17707            bit += 1;
17708        }
17709        word += 1;
17710    }
17711    result
17712}
17713
17714#[inline]
17715#[must_use]
17716const fn limbs_is_zero_16(a: Limbs<16>) -> bool {
17717    let aw = a.words();
17718    let mut i = 0usize;
17719    while i < 16 {
17720        if aw[i] != 0 {
17721            return false;
17722        }
17723        i += 1;
17724    }
17725    true
17726}
17727
17728#[inline]
17729#[must_use]
17730const fn limbs_shl1_16(a: Limbs<16>) -> Limbs<16> {
17731    let aw = a.words();
17732    let mut out = [0u64; 16];
17733    let mut carry: u64 = 0;
17734    let mut i = 0usize;
17735    while i < 16 {
17736        let v = aw[i];
17737        out[i] = (v << 1) | carry;
17738        carry = v >> 63;
17739        i += 1;
17740    }
17741    Limbs::<16>::from_words(out)
17742}
17743
17744#[inline]
17745#[must_use]
17746const fn limbs_set_bit0_16(a: Limbs<16>) -> Limbs<16> {
17747    let aw = a.words();
17748    let mut out = [0u64; 16];
17749    let mut i = 0usize;
17750    while i < 16 {
17751        out[i] = aw[i];
17752        i += 1;
17753    }
17754    out[0] |= 1u64;
17755    Limbs::<16>::from_words(out)
17756}
17757
17758#[inline]
17759#[must_use]
17760const fn limbs_bit_msb_16(a: Limbs<16>, msb_index: usize) -> u64 {
17761    let aw = a.words();
17762    let total_bits = 16 * 64;
17763    let lsb_index = total_bits - 1 - msb_index;
17764    let word = lsb_index / 64;
17765    let bit = lsb_index % 64;
17766    (aw[word] >> bit) & 1u64
17767}
17768
17769#[inline]
17770#[must_use]
17771const fn limbs_divmod_16(a: Limbs<16>, b: Limbs<16>) -> (Limbs<16>, Limbs<16>) {
17772    let mut q = Limbs::<16>::zero();
17773    let mut r = Limbs::<16>::zero();
17774    let total_bits = 16 * 64;
17775    let mut i = 0usize;
17776    while i < total_bits {
17777        r = limbs_shl1_16(r);
17778        if limbs_bit_msb_16(a, i) == 1 {
17779            r = limbs_set_bit0_16(r);
17780        }
17781        if limbs_le_16(b, r) {
17782            r = r.wrapping_sub(b);
17783            q = limbs_shl1_16(q);
17784            q = limbs_set_bit0_16(q);
17785        } else {
17786            q = limbs_shl1_16(q);
17787        }
17788        i += 1;
17789    }
17790    (q, r)
17791}
17792
17793#[inline]
17794#[must_use]
17795const fn limbs_div_16(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
17796    let (q, _) = limbs_divmod_16(a, b);
17797    q
17798}
17799
17800#[inline]
17801#[must_use]
17802const fn limbs_mod_16(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
17803    let (_, r) = limbs_divmod_16(a, b);
17804    r
17805}
17806
17807#[inline]
17808#[must_use]
17809const fn limbs_pow_16(base: Limbs<16>, exp: Limbs<16>) -> Limbs<16> {
17810    let mut result = limbs_one_16();
17811    let mut b = base;
17812    let ew = exp.words();
17813    let mut word = 0usize;
17814    while word < 16 {
17815        let mut bit = 0u32;
17816        while bit < 64 {
17817            if ((ew[word] >> bit) & 1u64) == 1u64 {
17818                result = result.wrapping_mul(b);
17819            }
17820            b = b.wrapping_mul(b);
17821            bit += 1;
17822        }
17823        word += 1;
17824    }
17825    result
17826}
17827
17828#[inline]
17829#[must_use]
17830const fn limbs_is_zero_32(a: Limbs<32>) -> bool {
17831    let aw = a.words();
17832    let mut i = 0usize;
17833    while i < 32 {
17834        if aw[i] != 0 {
17835            return false;
17836        }
17837        i += 1;
17838    }
17839    true
17840}
17841
17842#[inline]
17843#[must_use]
17844const fn limbs_shl1_32(a: Limbs<32>) -> Limbs<32> {
17845    let aw = a.words();
17846    let mut out = [0u64; 32];
17847    let mut carry: u64 = 0;
17848    let mut i = 0usize;
17849    while i < 32 {
17850        let v = aw[i];
17851        out[i] = (v << 1) | carry;
17852        carry = v >> 63;
17853        i += 1;
17854    }
17855    Limbs::<32>::from_words(out)
17856}
17857
17858#[inline]
17859#[must_use]
17860const fn limbs_set_bit0_32(a: Limbs<32>) -> Limbs<32> {
17861    let aw = a.words();
17862    let mut out = [0u64; 32];
17863    let mut i = 0usize;
17864    while i < 32 {
17865        out[i] = aw[i];
17866        i += 1;
17867    }
17868    out[0] |= 1u64;
17869    Limbs::<32>::from_words(out)
17870}
17871
17872#[inline]
17873#[must_use]
17874const fn limbs_bit_msb_32(a: Limbs<32>, msb_index: usize) -> u64 {
17875    let aw = a.words();
17876    let total_bits = 32 * 64;
17877    let lsb_index = total_bits - 1 - msb_index;
17878    let word = lsb_index / 64;
17879    let bit = lsb_index % 64;
17880    (aw[word] >> bit) & 1u64
17881}
17882
17883#[inline]
17884#[must_use]
17885const fn limbs_divmod_32(a: Limbs<32>, b: Limbs<32>) -> (Limbs<32>, Limbs<32>) {
17886    let mut q = Limbs::<32>::zero();
17887    let mut r = Limbs::<32>::zero();
17888    let total_bits = 32 * 64;
17889    let mut i = 0usize;
17890    while i < total_bits {
17891        r = limbs_shl1_32(r);
17892        if limbs_bit_msb_32(a, i) == 1 {
17893            r = limbs_set_bit0_32(r);
17894        }
17895        if limbs_le_32(b, r) {
17896            r = r.wrapping_sub(b);
17897            q = limbs_shl1_32(q);
17898            q = limbs_set_bit0_32(q);
17899        } else {
17900            q = limbs_shl1_32(q);
17901        }
17902        i += 1;
17903    }
17904    (q, r)
17905}
17906
17907#[inline]
17908#[must_use]
17909const fn limbs_div_32(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
17910    let (q, _) = limbs_divmod_32(a, b);
17911    q
17912}
17913
17914#[inline]
17915#[must_use]
17916const fn limbs_mod_32(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
17917    let (_, r) = limbs_divmod_32(a, b);
17918    r
17919}
17920
17921#[inline]
17922#[must_use]
17923const fn limbs_pow_32(base: Limbs<32>, exp: Limbs<32>) -> Limbs<32> {
17924    let mut result = limbs_one_32();
17925    let mut b = base;
17926    let ew = exp.words();
17927    let mut word = 0usize;
17928    while word < 32 {
17929        let mut bit = 0u32;
17930        while bit < 64 {
17931            if ((ew[word] >> bit) & 1u64) == 1u64 {
17932                result = result.wrapping_mul(b);
17933            }
17934            b = b.wrapping_mul(b);
17935            bit += 1;
17936        }
17937        word += 1;
17938    }
17939    result
17940}
17941
17942#[inline]
17943#[must_use]
17944const fn limbs_is_zero_64(a: Limbs<64>) -> bool {
17945    let aw = a.words();
17946    let mut i = 0usize;
17947    while i < 64 {
17948        if aw[i] != 0 {
17949            return false;
17950        }
17951        i += 1;
17952    }
17953    true
17954}
17955
17956#[inline]
17957#[must_use]
17958const fn limbs_shl1_64(a: Limbs<64>) -> Limbs<64> {
17959    let aw = a.words();
17960    let mut out = [0u64; 64];
17961    let mut carry: u64 = 0;
17962    let mut i = 0usize;
17963    while i < 64 {
17964        let v = aw[i];
17965        out[i] = (v << 1) | carry;
17966        carry = v >> 63;
17967        i += 1;
17968    }
17969    Limbs::<64>::from_words(out)
17970}
17971
17972#[inline]
17973#[must_use]
17974const fn limbs_set_bit0_64(a: Limbs<64>) -> Limbs<64> {
17975    let aw = a.words();
17976    let mut out = [0u64; 64];
17977    let mut i = 0usize;
17978    while i < 64 {
17979        out[i] = aw[i];
17980        i += 1;
17981    }
17982    out[0] |= 1u64;
17983    Limbs::<64>::from_words(out)
17984}
17985
17986#[inline]
17987#[must_use]
17988const fn limbs_bit_msb_64(a: Limbs<64>, msb_index: usize) -> u64 {
17989    let aw = a.words();
17990    let total_bits = 64 * 64;
17991    let lsb_index = total_bits - 1 - msb_index;
17992    let word = lsb_index / 64;
17993    let bit = lsb_index % 64;
17994    (aw[word] >> bit) & 1u64
17995}
17996
17997#[inline]
17998#[must_use]
17999const fn limbs_divmod_64(a: Limbs<64>, b: Limbs<64>) -> (Limbs<64>, Limbs<64>) {
18000    let mut q = Limbs::<64>::zero();
18001    let mut r = Limbs::<64>::zero();
18002    let total_bits = 64 * 64;
18003    let mut i = 0usize;
18004    while i < total_bits {
18005        r = limbs_shl1_64(r);
18006        if limbs_bit_msb_64(a, i) == 1 {
18007            r = limbs_set_bit0_64(r);
18008        }
18009        if limbs_le_64(b, r) {
18010            r = r.wrapping_sub(b);
18011            q = limbs_shl1_64(q);
18012            q = limbs_set_bit0_64(q);
18013        } else {
18014            q = limbs_shl1_64(q);
18015        }
18016        i += 1;
18017    }
18018    (q, r)
18019}
18020
18021#[inline]
18022#[must_use]
18023const fn limbs_div_64(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
18024    let (q, _) = limbs_divmod_64(a, b);
18025    q
18026}
18027
18028#[inline]
18029#[must_use]
18030const fn limbs_mod_64(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
18031    let (_, r) = limbs_divmod_64(a, b);
18032    r
18033}
18034
18035#[inline]
18036#[must_use]
18037const fn limbs_pow_64(base: Limbs<64>, exp: Limbs<64>) -> Limbs<64> {
18038    let mut result = limbs_one_64();
18039    let mut b = base;
18040    let ew = exp.words();
18041    let mut word = 0usize;
18042    while word < 64 {
18043        let mut bit = 0u32;
18044        while bit < 64 {
18045            if ((ew[word] >> bit) & 1u64) == 1u64 {
18046                result = result.wrapping_mul(b);
18047            }
18048            b = b.wrapping_mul(b);
18049            bit += 1;
18050        }
18051        word += 1;
18052    }
18053    result
18054}
18055
18056#[inline]
18057#[must_use]
18058const fn limbs_is_zero_128(a: Limbs<128>) -> bool {
18059    let aw = a.words();
18060    let mut i = 0usize;
18061    while i < 128 {
18062        if aw[i] != 0 {
18063            return false;
18064        }
18065        i += 1;
18066    }
18067    true
18068}
18069
18070#[inline]
18071#[must_use]
18072const fn limbs_shl1_128(a: Limbs<128>) -> Limbs<128> {
18073    let aw = a.words();
18074    let mut out = [0u64; 128];
18075    let mut carry: u64 = 0;
18076    let mut i = 0usize;
18077    while i < 128 {
18078        let v = aw[i];
18079        out[i] = (v << 1) | carry;
18080        carry = v >> 63;
18081        i += 1;
18082    }
18083    Limbs::<128>::from_words(out)
18084}
18085
18086#[inline]
18087#[must_use]
18088const fn limbs_set_bit0_128(a: Limbs<128>) -> Limbs<128> {
18089    let aw = a.words();
18090    let mut out = [0u64; 128];
18091    let mut i = 0usize;
18092    while i < 128 {
18093        out[i] = aw[i];
18094        i += 1;
18095    }
18096    out[0] |= 1u64;
18097    Limbs::<128>::from_words(out)
18098}
18099
18100#[inline]
18101#[must_use]
18102const fn limbs_bit_msb_128(a: Limbs<128>, msb_index: usize) -> u64 {
18103    let aw = a.words();
18104    let total_bits = 128 * 64;
18105    let lsb_index = total_bits - 1 - msb_index;
18106    let word = lsb_index / 64;
18107    let bit = lsb_index % 64;
18108    (aw[word] >> bit) & 1u64
18109}
18110
18111#[inline]
18112#[must_use]
18113const fn limbs_divmod_128(a: Limbs<128>, b: Limbs<128>) -> (Limbs<128>, Limbs<128>) {
18114    let mut q = Limbs::<128>::zero();
18115    let mut r = Limbs::<128>::zero();
18116    let total_bits = 128 * 64;
18117    let mut i = 0usize;
18118    while i < total_bits {
18119        r = limbs_shl1_128(r);
18120        if limbs_bit_msb_128(a, i) == 1 {
18121            r = limbs_set_bit0_128(r);
18122        }
18123        if limbs_le_128(b, r) {
18124            r = r.wrapping_sub(b);
18125            q = limbs_shl1_128(q);
18126            q = limbs_set_bit0_128(q);
18127        } else {
18128            q = limbs_shl1_128(q);
18129        }
18130        i += 1;
18131    }
18132    (q, r)
18133}
18134
18135#[inline]
18136#[must_use]
18137const fn limbs_div_128(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
18138    let (q, _) = limbs_divmod_128(a, b);
18139    q
18140}
18141
18142#[inline]
18143#[must_use]
18144const fn limbs_mod_128(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
18145    let (_, r) = limbs_divmod_128(a, b);
18146    r
18147}
18148
18149#[inline]
18150#[must_use]
18151const fn limbs_pow_128(base: Limbs<128>, exp: Limbs<128>) -> Limbs<128> {
18152    let mut result = limbs_one_128();
18153    let mut b = base;
18154    let ew = exp.words();
18155    let mut word = 0usize;
18156    while word < 128 {
18157        let mut bit = 0u32;
18158        while bit < 64 {
18159            if ((ew[word] >> bit) & 1u64) == 1u64 {
18160                result = result.wrapping_mul(b);
18161            }
18162            b = b.wrapping_mul(b);
18163            bit += 1;
18164        }
18165        word += 1;
18166    }
18167    result
18168}
18169
18170#[inline]
18171#[must_use]
18172const fn limbs_is_zero_192(a: Limbs<192>) -> bool {
18173    let aw = a.words();
18174    let mut i = 0usize;
18175    while i < 192 {
18176        if aw[i] != 0 {
18177            return false;
18178        }
18179        i += 1;
18180    }
18181    true
18182}
18183
18184#[inline]
18185#[must_use]
18186const fn limbs_shl1_192(a: Limbs<192>) -> Limbs<192> {
18187    let aw = a.words();
18188    let mut out = [0u64; 192];
18189    let mut carry: u64 = 0;
18190    let mut i = 0usize;
18191    while i < 192 {
18192        let v = aw[i];
18193        out[i] = (v << 1) | carry;
18194        carry = v >> 63;
18195        i += 1;
18196    }
18197    Limbs::<192>::from_words(out)
18198}
18199
18200#[inline]
18201#[must_use]
18202const fn limbs_set_bit0_192(a: Limbs<192>) -> Limbs<192> {
18203    let aw = a.words();
18204    let mut out = [0u64; 192];
18205    let mut i = 0usize;
18206    while i < 192 {
18207        out[i] = aw[i];
18208        i += 1;
18209    }
18210    out[0] |= 1u64;
18211    Limbs::<192>::from_words(out)
18212}
18213
18214#[inline]
18215#[must_use]
18216const fn limbs_bit_msb_192(a: Limbs<192>, msb_index: usize) -> u64 {
18217    let aw = a.words();
18218    let total_bits = 192 * 64;
18219    let lsb_index = total_bits - 1 - msb_index;
18220    let word = lsb_index / 64;
18221    let bit = lsb_index % 64;
18222    (aw[word] >> bit) & 1u64
18223}
18224
18225#[inline]
18226#[must_use]
18227const fn limbs_divmod_192(a: Limbs<192>, b: Limbs<192>) -> (Limbs<192>, Limbs<192>) {
18228    let mut q = Limbs::<192>::zero();
18229    let mut r = Limbs::<192>::zero();
18230    let total_bits = 192 * 64;
18231    let mut i = 0usize;
18232    while i < total_bits {
18233        r = limbs_shl1_192(r);
18234        if limbs_bit_msb_192(a, i) == 1 {
18235            r = limbs_set_bit0_192(r);
18236        }
18237        if limbs_le_192(b, r) {
18238            r = r.wrapping_sub(b);
18239            q = limbs_shl1_192(q);
18240            q = limbs_set_bit0_192(q);
18241        } else {
18242            q = limbs_shl1_192(q);
18243        }
18244        i += 1;
18245    }
18246    (q, r)
18247}
18248
18249#[inline]
18250#[must_use]
18251const fn limbs_div_192(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
18252    let (q, _) = limbs_divmod_192(a, b);
18253    q
18254}
18255
18256#[inline]
18257#[must_use]
18258const fn limbs_mod_192(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
18259    let (_, r) = limbs_divmod_192(a, b);
18260    r
18261}
18262
18263#[inline]
18264#[must_use]
18265const fn limbs_pow_192(base: Limbs<192>, exp: Limbs<192>) -> Limbs<192> {
18266    let mut result = limbs_one_192();
18267    let mut b = base;
18268    let ew = exp.words();
18269    let mut word = 0usize;
18270    while word < 192 {
18271        let mut bit = 0u32;
18272        while bit < 64 {
18273            if ((ew[word] >> bit) & 1u64) == 1u64 {
18274                result = result.wrapping_mul(b);
18275            }
18276            b = b.wrapping_mul(b);
18277            bit += 1;
18278        }
18279        word += 1;
18280    }
18281    result
18282}
18283
18284#[inline]
18285#[must_use]
18286const fn limbs_is_zero_256(a: Limbs<256>) -> bool {
18287    let aw = a.words();
18288    let mut i = 0usize;
18289    while i < 256 {
18290        if aw[i] != 0 {
18291            return false;
18292        }
18293        i += 1;
18294    }
18295    true
18296}
18297
18298#[inline]
18299#[must_use]
18300const fn limbs_shl1_256(a: Limbs<256>) -> Limbs<256> {
18301    let aw = a.words();
18302    let mut out = [0u64; 256];
18303    let mut carry: u64 = 0;
18304    let mut i = 0usize;
18305    while i < 256 {
18306        let v = aw[i];
18307        out[i] = (v << 1) | carry;
18308        carry = v >> 63;
18309        i += 1;
18310    }
18311    Limbs::<256>::from_words(out)
18312}
18313
18314#[inline]
18315#[must_use]
18316const fn limbs_set_bit0_256(a: Limbs<256>) -> Limbs<256> {
18317    let aw = a.words();
18318    let mut out = [0u64; 256];
18319    let mut i = 0usize;
18320    while i < 256 {
18321        out[i] = aw[i];
18322        i += 1;
18323    }
18324    out[0] |= 1u64;
18325    Limbs::<256>::from_words(out)
18326}
18327
18328#[inline]
18329#[must_use]
18330const fn limbs_bit_msb_256(a: Limbs<256>, msb_index: usize) -> u64 {
18331    let aw = a.words();
18332    let total_bits = 256 * 64;
18333    let lsb_index = total_bits - 1 - msb_index;
18334    let word = lsb_index / 64;
18335    let bit = lsb_index % 64;
18336    (aw[word] >> bit) & 1u64
18337}
18338
18339#[inline]
18340#[must_use]
18341const fn limbs_divmod_256(a: Limbs<256>, b: Limbs<256>) -> (Limbs<256>, Limbs<256>) {
18342    let mut q = Limbs::<256>::zero();
18343    let mut r = Limbs::<256>::zero();
18344    let total_bits = 256 * 64;
18345    let mut i = 0usize;
18346    while i < total_bits {
18347        r = limbs_shl1_256(r);
18348        if limbs_bit_msb_256(a, i) == 1 {
18349            r = limbs_set_bit0_256(r);
18350        }
18351        if limbs_le_256(b, r) {
18352            r = r.wrapping_sub(b);
18353            q = limbs_shl1_256(q);
18354            q = limbs_set_bit0_256(q);
18355        } else {
18356            q = limbs_shl1_256(q);
18357        }
18358        i += 1;
18359    }
18360    (q, r)
18361}
18362
18363#[inline]
18364#[must_use]
18365const fn limbs_div_256(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
18366    let (q, _) = limbs_divmod_256(a, b);
18367    q
18368}
18369
18370#[inline]
18371#[must_use]
18372const fn limbs_mod_256(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
18373    let (_, r) = limbs_divmod_256(a, b);
18374    r
18375}
18376
18377#[inline]
18378#[must_use]
18379const fn limbs_pow_256(base: Limbs<256>, exp: Limbs<256>) -> Limbs<256> {
18380    let mut result = limbs_one_256();
18381    let mut b = base;
18382    let ew = exp.words();
18383    let mut word = 0usize;
18384    while word < 256 {
18385        let mut bit = 0u32;
18386        while bit < 64 {
18387            if ((ew[word] >> bit) & 1u64) == 1u64 {
18388                result = result.wrapping_mul(b);
18389            }
18390            b = b.wrapping_mul(b);
18391            bit += 1;
18392        }
18393        word += 1;
18394    }
18395    result
18396}
18397
18398#[inline]
18399#[must_use]
18400const fn limbs_is_zero_512(a: Limbs<512>) -> bool {
18401    let aw = a.words();
18402    let mut i = 0usize;
18403    while i < 512 {
18404        if aw[i] != 0 {
18405            return false;
18406        }
18407        i += 1;
18408    }
18409    true
18410}
18411
18412#[inline]
18413#[must_use]
18414const fn limbs_shl1_512(a: Limbs<512>) -> Limbs<512> {
18415    let aw = a.words();
18416    let mut out = [0u64; 512];
18417    let mut carry: u64 = 0;
18418    let mut i = 0usize;
18419    while i < 512 {
18420        let v = aw[i];
18421        out[i] = (v << 1) | carry;
18422        carry = v >> 63;
18423        i += 1;
18424    }
18425    Limbs::<512>::from_words(out)
18426}
18427
18428#[inline]
18429#[must_use]
18430const fn limbs_set_bit0_512(a: Limbs<512>) -> Limbs<512> {
18431    let aw = a.words();
18432    let mut out = [0u64; 512];
18433    let mut i = 0usize;
18434    while i < 512 {
18435        out[i] = aw[i];
18436        i += 1;
18437    }
18438    out[0] |= 1u64;
18439    Limbs::<512>::from_words(out)
18440}
18441
18442#[inline]
18443#[must_use]
18444const fn limbs_bit_msb_512(a: Limbs<512>, msb_index: usize) -> u64 {
18445    let aw = a.words();
18446    let total_bits = 512 * 64;
18447    let lsb_index = total_bits - 1 - msb_index;
18448    let word = lsb_index / 64;
18449    let bit = lsb_index % 64;
18450    (aw[word] >> bit) & 1u64
18451}
18452
18453#[inline]
18454#[must_use]
18455const fn limbs_divmod_512(a: Limbs<512>, b: Limbs<512>) -> (Limbs<512>, Limbs<512>) {
18456    let mut q = Limbs::<512>::zero();
18457    let mut r = Limbs::<512>::zero();
18458    let total_bits = 512 * 64;
18459    let mut i = 0usize;
18460    while i < total_bits {
18461        r = limbs_shl1_512(r);
18462        if limbs_bit_msb_512(a, i) == 1 {
18463            r = limbs_set_bit0_512(r);
18464        }
18465        if limbs_le_512(b, r) {
18466            r = r.wrapping_sub(b);
18467            q = limbs_shl1_512(q);
18468            q = limbs_set_bit0_512(q);
18469        } else {
18470            q = limbs_shl1_512(q);
18471        }
18472        i += 1;
18473    }
18474    (q, r)
18475}
18476
18477#[inline]
18478#[must_use]
18479const fn limbs_div_512(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
18480    let (q, _) = limbs_divmod_512(a, b);
18481    q
18482}
18483
18484#[inline]
18485#[must_use]
18486const fn limbs_mod_512(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
18487    let (_, r) = limbs_divmod_512(a, b);
18488    r
18489}
18490
18491#[inline]
18492#[must_use]
18493const fn limbs_pow_512(base: Limbs<512>, exp: Limbs<512>) -> Limbs<512> {
18494    let mut result = limbs_one_512();
18495    let mut b = base;
18496    let ew = exp.words();
18497    let mut word = 0usize;
18498    while word < 512 {
18499        let mut bit = 0u32;
18500        while bit < 64 {
18501            if ((ew[word] >> bit) & 1u64) == 1u64 {
18502                result = result.wrapping_mul(b);
18503            }
18504            b = b.wrapping_mul(b);
18505            bit += 1;
18506        }
18507        word += 1;
18508    }
18509    result
18510}
18511
18512/// Sealed marker trait for fragment classifiers (Is2SatShape, IsHornShape,
18513/// IsResidualFragment) emitted parametrically from the predicate individuals
18514/// referenced by `predicate:InhabitanceDispatchTable`.
18515pub trait FragmentMarker: fragment_sealed::Sealed {}
18516
18517mod fragment_sealed {
18518    /// Private supertrait.
18519    pub trait Sealed {}
18520    impl Sealed for super::Is2SatShape {}
18521    impl Sealed for super::IsHornShape {}
18522    impl Sealed for super::IsResidualFragment {}
18523}
18524
18525/// Fragment marker for `predicate:Is2SatShape`. Zero-sized.
18526#[derive(Debug, Default, Clone, Copy)]
18527pub struct Is2SatShape;
18528impl FragmentMarker for Is2SatShape {}
18529
18530/// Fragment marker for `predicate:IsHornShape`. Zero-sized.
18531#[derive(Debug, Default, Clone, Copy)]
18532pub struct IsHornShape;
18533impl FragmentMarker for IsHornShape {}
18534
18535/// Fragment marker for `predicate:IsResidualFragment`. Zero-sized.
18536#[derive(Debug, Default, Clone, Copy)]
18537pub struct IsResidualFragment;
18538impl FragmentMarker for IsResidualFragment {}
18539
18540/// A single dispatch rule entry pairing a predicate IRI, a target resolver
18541/// name, and an evaluation priority.
18542#[derive(Debug, Clone, Copy)]
18543pub struct DispatchRule {
18544    /// IRI of the predicate that selects this rule.
18545    pub predicate_iri: &'static str,
18546    /// IRI of the target resolver class invoked when the predicate holds.
18547    pub target_resolver_iri: &'static str,
18548    /// Evaluation order; lower values evaluate first.
18549    pub priority: u32,
18550}
18551
18552/// A static dispatch table — an ordered slice of `DispatchRule` entries.
18553pub type DispatchTable = &'static [DispatchRule];
18554
18555/// v0.2.1 dispatch table generated from `predicate:InhabitanceDispatchTable`.
18556pub const INHABITANCE_DISPATCH_TABLE: DispatchTable = &[
18557    DispatchRule {
18558        predicate_iri: "https://uor.foundation/predicate/Is2SatShape",
18559        target_resolver_iri: "https://uor.foundation/resolver/TwoSatDecider",
18560        priority: 0,
18561    },
18562    DispatchRule {
18563        predicate_iri: "https://uor.foundation/predicate/IsHornShape",
18564        target_resolver_iri: "https://uor.foundation/resolver/HornSatDecider",
18565        priority: 1,
18566    },
18567    DispatchRule {
18568        predicate_iri: "https://uor.foundation/predicate/IsResidualFragment",
18569        target_resolver_iri: "https://uor.foundation/resolver/ResidualVerdictResolver",
18570        priority: 2,
18571    },
18572];
18573
18574/// v0.2.1 `Deref` impl for `Validated<T: OntologyTarget>` so consumers can call
18575/// certificate methods directly: `cert.target_level()` rather than
18576/// `cert.inner().target_level()`. The bound `T: OntologyTarget` keeps the
18577/// auto-deref scoped to foundation-produced types.
18578impl<T: OntologyTarget> core::ops::Deref for Validated<T> {
18579    type Target = T;
18580    #[inline]
18581    fn deref(&self) -> &T {
18582        &self.inner
18583    }
18584}
18585
18586mod bound_constraint_sealed {
18587    /// Sealed supertrait for the closed Observable catalogue.
18588    pub trait ObservableSealed {}
18589    /// Sealed supertrait for the closed BoundShape catalogue.
18590    pub trait BoundShapeSealed {}
18591}
18592
18593/// Sealed marker trait identifying the closed catalogue of observables
18594/// admissible in BoundConstraint. Implemented by unit structs emitted
18595/// below per `observable:Observable` subclass referenced by a
18596/// BoundConstraint kind individual.
18597pub trait Observable: bound_constraint_sealed::ObservableSealed {
18598    /// Ontology IRI of this observable class.
18599    const IRI: &'static str;
18600}
18601
18602/// Sealed marker trait identifying the closed catalogue of bound shapes.
18603/// Exactly six individuals: EqualBound, LessEqBound, GreaterEqBound,
18604/// RangeContainBound, ResidueClassBound, AffineEqualBound.
18605pub trait BoundShape: bound_constraint_sealed::BoundShapeSealed {
18606    /// Ontology IRI of this bound shape individual.
18607    const IRI: &'static str;
18608}
18609
18610/// Observes a Datum's value modulo a configurable modulus.
18611#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18612pub struct ValueModObservable;
18613impl bound_constraint_sealed::ObservableSealed for ValueModObservable {}
18614impl Observable for ValueModObservable {
18615    const IRI: &'static str = "https://uor.foundation/observable/ValueModObservable";
18616}
18617
18618/// Distance between two ring elements under the Hamming metric.
18619#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18620pub struct HammingMetric;
18621impl bound_constraint_sealed::ObservableSealed for HammingMetric {}
18622impl Observable for HammingMetric {
18623    const IRI: &'static str = "https://uor.foundation/observable/HammingMetric";
18624}
18625
18626/// Observes the derivation depth of a Datum.
18627#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18628pub struct DerivationDepthObservable;
18629impl bound_constraint_sealed::ObservableSealed for DerivationDepthObservable {}
18630impl Observable for DerivationDepthObservable {
18631    const IRI: &'static str = "https://uor.foundation/derivation/DerivationDepthObservable";
18632}
18633
18634/// Observes the carry depth of a Datum in the W₂ tower.
18635#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18636pub struct CarryDepthObservable;
18637impl bound_constraint_sealed::ObservableSealed for CarryDepthObservable {}
18638impl Observable for CarryDepthObservable {
18639    const IRI: &'static str = "https://uor.foundation/carry/CarryDepthObservable";
18640}
18641
18642/// Observes the free-rank of the partition associated with a Datum.
18643#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18644pub struct FreeRankObservable;
18645impl bound_constraint_sealed::ObservableSealed for FreeRankObservable {}
18646impl Observable for FreeRankObservable {
18647    const IRI: &'static str = "https://uor.foundation/partition/FreeRankObservable";
18648}
18649
18650/// Predicate form: `observable(datum) == target`.
18651#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18652pub struct EqualBound;
18653impl bound_constraint_sealed::BoundShapeSealed for EqualBound {}
18654impl BoundShape for EqualBound {
18655    const IRI: &'static str = "https://uor.foundation/type/EqualBound";
18656}
18657
18658/// Predicate form: `observable(datum) <= bound`.
18659#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18660pub struct LessEqBound;
18661impl bound_constraint_sealed::BoundShapeSealed for LessEqBound {}
18662impl BoundShape for LessEqBound {
18663    const IRI: &'static str = "https://uor.foundation/type/LessEqBound";
18664}
18665
18666/// Predicate form: `observable(datum) >= bound`.
18667#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18668pub struct GreaterEqBound;
18669impl bound_constraint_sealed::BoundShapeSealed for GreaterEqBound {}
18670impl BoundShape for GreaterEqBound {
18671    const IRI: &'static str = "https://uor.foundation/type/GreaterEqBound";
18672}
18673
18674/// Predicate form: `lo <= observable(datum) <= hi`.
18675#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18676pub struct RangeContainBound;
18677impl bound_constraint_sealed::BoundShapeSealed for RangeContainBound {}
18678impl BoundShape for RangeContainBound {
18679    const IRI: &'static str = "https://uor.foundation/type/RangeContainBound";
18680}
18681
18682/// Predicate form: `observable(datum) ≡ residue (mod modulus)`.
18683#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18684pub struct ResidueClassBound;
18685impl bound_constraint_sealed::BoundShapeSealed for ResidueClassBound {}
18686impl BoundShape for ResidueClassBound {
18687    const IRI: &'static str = "https://uor.foundation/type/ResidueClassBound";
18688}
18689
18690/// Predicate form: `observable(datum) == offset + affine combination`.
18691#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18692pub struct AffineEqualBound;
18693impl bound_constraint_sealed::BoundShapeSealed for AffineEqualBound {}
18694impl BoundShape for AffineEqualBound {
18695    const IRI: &'static str = "https://uor.foundation/type/AffineEqualBound";
18696}
18697
18698/// Parameter value type for `BoundConstraint` arguments.
18699/// Sealed enum over the closed set of primitive kinds the bound-shape
18700/// catalogue requires. No heap, no `String`.
18701#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18702pub enum BoundArgValue {
18703    /// Unsigned 64-bit integer.
18704    U64(u64),
18705    /// Signed 64-bit integer.
18706    I64(i64),
18707    /// Fixed 32-byte content-addressed value.
18708    Bytes32([u8; 32]),
18709}
18710
18711/// Fixed-size arguments carrier for a `BoundConstraint`.
18712/// Holds up to eight `(name, value)` pairs inline. The closed
18713/// bound-shape catalogue requires at most three parameters per kind;
18714/// the extra slots are reserved for future kind additions without
18715/// changing the carrier layout.
18716#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18717pub struct BoundArguments {
18718    entries: [Option<BoundArgEntry>; 8],
18719}
18720
18721/// A single named parameter in a `BoundArguments` table.
18722#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18723pub struct BoundArgEntry {
18724    /// Parameter name (a `&'static str` intentional over heap-owned).
18725    pub name: &'static str,
18726    /// Parameter value.
18727    pub value: BoundArgValue,
18728}
18729
18730impl BoundArguments {
18731    /// Construct an empty argument table.
18732    #[inline]
18733    #[must_use]
18734    pub const fn empty() -> Self {
18735        Self { entries: [None; 8] }
18736    }
18737
18738    /// Construct a table with a single `(name, value)` pair.
18739    #[inline]
18740    #[must_use]
18741    pub const fn single(name: &'static str, value: BoundArgValue) -> Self {
18742        let mut entries = [None; 8];
18743        entries[0] = Some(BoundArgEntry { name, value });
18744        Self { entries }
18745    }
18746
18747    /// Construct a table with two `(name, value)` pairs.
18748    #[inline]
18749    #[must_use]
18750    pub const fn pair(
18751        first: (&'static str, BoundArgValue),
18752        second: (&'static str, BoundArgValue),
18753    ) -> Self {
18754        let mut entries = [None; 8];
18755        entries[0] = Some(BoundArgEntry {
18756            name: first.0,
18757            value: first.1,
18758        });
18759        entries[1] = Some(BoundArgEntry {
18760            name: second.0,
18761            value: second.1,
18762        });
18763        Self { entries }
18764    }
18765
18766    /// Access the stored entries.
18767    #[inline]
18768    #[must_use]
18769    pub const fn entries(&self) -> &[Option<BoundArgEntry>; 8] {
18770        &self.entries
18771    }
18772}
18773
18774/// Parametric constraint carrier (v0.2.2 Phase D).
18775/// Generic over `O: Observable` and `B: BoundShape`. The seven
18776/// legacy constraint kinds are preserved as type aliases over this
18777/// carrier; see `ResidueConstraint`, `HammingConstraint`, etc. below.
18778#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18779pub struct BoundConstraint<O: Observable, B: BoundShape> {
18780    observable: O,
18781    bound: B,
18782    args: BoundArguments,
18783    _sealed: (),
18784}
18785
18786impl<O: Observable, B: BoundShape> BoundConstraint<O, B> {
18787    /// Crate-internal constructor. Downstream obtains values through
18788    /// the per-type-alias `pub const fn new` constructors.
18789    #[inline]
18790    #[must_use]
18791    pub(crate) const fn from_parts(observable: O, bound: B, args: BoundArguments) -> Self {
18792        Self {
18793            observable,
18794            bound,
18795            args,
18796            _sealed: (),
18797        }
18798    }
18799
18800    /// Access the bound observable.
18801    #[inline]
18802    #[must_use]
18803    pub const fn observable(&self) -> &O {
18804        &self.observable
18805    }
18806
18807    /// Access the bound shape.
18808    #[inline]
18809    #[must_use]
18810    pub const fn bound(&self) -> &B {
18811        &self.bound
18812    }
18813
18814    /// Access the bound arguments.
18815    #[inline]
18816    #[must_use]
18817    pub const fn args(&self) -> &BoundArguments {
18818        &self.args
18819    }
18820}
18821
18822/// Parametric conjunction of `BoundConstraint` kinds (v0.2.2 Phase D).
18823/// Replaces the v0.2.1 `CompositeConstraint` enumeration; the legacy
18824/// name survives as the type alias `CompositeConstraint<N>` below.
18825#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18826pub struct Conjunction<const N: usize> {
18827    len: usize,
18828    _sealed: (),
18829}
18830
18831impl<const N: usize> Conjunction<N> {
18832    /// Construct a new Conjunction with `len` conjuncts.
18833    #[inline]
18834    #[must_use]
18835    pub const fn new(len: usize) -> Self {
18836        Self { len, _sealed: () }
18837    }
18838
18839    /// The number of conjuncts in this Conjunction.
18840    #[inline]
18841    #[must_use]
18842    pub const fn len(&self) -> usize {
18843        self.len
18844    }
18845
18846    /// Whether the Conjunction is empty.
18847    #[inline]
18848    #[must_use]
18849    pub const fn is_empty(&self) -> bool {
18850        self.len == 0
18851    }
18852}
18853
18854/// v0.2.1 legacy type alias: a `BoundConstraint` kind asserting
18855/// residue-class membership (`value mod m == r`).
18856pub type ResidueConstraint = BoundConstraint<ValueModObservable, ResidueClassBound>;
18857
18858impl ResidueConstraint {
18859    /// Construct a residue constraint with the given modulus and residue.
18860    #[inline]
18861    #[must_use]
18862    pub const fn new(modulus: u64, residue: u64) -> Self {
18863        let args = BoundArguments::pair(
18864            ("modulus", BoundArgValue::U64(modulus)),
18865            ("residue", BoundArgValue::U64(residue)),
18866        );
18867        BoundConstraint::from_parts(ValueModObservable, ResidueClassBound, args)
18868    }
18869}
18870
18871/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
18872/// Hamming weight of the Datum (`weight <= bound`).
18873pub type HammingConstraint = BoundConstraint<HammingMetric, LessEqBound>;
18874
18875impl HammingConstraint {
18876    /// Construct a Hamming constraint with the given upper bound.
18877    #[inline]
18878    #[must_use]
18879    pub const fn new(bound: u64) -> Self {
18880        let args = BoundArguments::single("bound", BoundArgValue::U64(bound));
18881        BoundConstraint::from_parts(HammingMetric, LessEqBound, args)
18882    }
18883}
18884
18885/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
18886/// derivation depth of the Datum.
18887pub type DepthConstraint = BoundConstraint<DerivationDepthObservable, LessEqBound>;
18888
18889impl DepthConstraint {
18890    /// Construct a depth constraint with min and max depths.
18891    #[inline]
18892    #[must_use]
18893    pub const fn new(min_depth: u64, max_depth: u64) -> Self {
18894        let args = BoundArguments::pair(
18895            ("min_depth", BoundArgValue::U64(min_depth)),
18896            ("max_depth", BoundArgValue::U64(max_depth)),
18897        );
18898        BoundConstraint::from_parts(DerivationDepthObservable, LessEqBound, args)
18899    }
18900}
18901
18902/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
18903/// carry depth of the Datum in the W₂ tower.
18904pub type CarryConstraint = BoundConstraint<CarryDepthObservable, LessEqBound>;
18905
18906impl CarryConstraint {
18907    /// Construct a carry constraint with the given upper bound.
18908    #[inline]
18909    #[must_use]
18910    pub const fn new(bound: u64) -> Self {
18911        let args = BoundArguments::single("bound", BoundArgValue::U64(bound));
18912        BoundConstraint::from_parts(CarryDepthObservable, LessEqBound, args)
18913    }
18914}
18915
18916/// v0.2.1 legacy type alias: a `BoundConstraint` kind pinning a
18917/// single site coordinate.
18918pub type SiteConstraint = BoundConstraint<FreeRankObservable, LessEqBound>;
18919
18920impl SiteConstraint {
18921    /// Construct a site constraint with the given site index.
18922    #[inline]
18923    #[must_use]
18924    pub const fn new(site_index: u64) -> Self {
18925        let args = BoundArguments::single("site_index", BoundArgValue::U64(site_index));
18926        BoundConstraint::from_parts(FreeRankObservable, LessEqBound, args)
18927    }
18928}
18929
18930/// v0.2.1 legacy type alias: a `BoundConstraint` kind pinning an
18931/// affine relationship on the Datum's value projection.
18932pub type AffineConstraint = BoundConstraint<ValueModObservable, AffineEqualBound>;
18933
18934impl AffineConstraint {
18935    /// Construct an affine constraint with the given offset.
18936    #[inline]
18937    #[must_use]
18938    pub const fn new(offset: u64) -> Self {
18939        let args = BoundArguments::single("offset", BoundArgValue::U64(offset));
18940        BoundConstraint::from_parts(ValueModObservable, AffineEqualBound, args)
18941    }
18942}
18943
18944/// v0.2.1 legacy type alias: a `Conjunction` over `N` BoundConstraint
18945/// kinds (`CompositeConstraint<3>` = 3-way conjunction).
18946pub type CompositeConstraint<const N: usize> = Conjunction<N>;
18947
18948/// v0.2.2 Phase E: sealed query handle.
18949#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18950pub struct Query {
18951    address: ContentAddress,
18952    _sealed: (),
18953}
18954
18955impl Query {
18956    /// Returns the content-hashed query address.
18957    #[inline]
18958    #[must_use]
18959    pub const fn address(&self) -> ContentAddress {
18960        self.address
18961    }
18962
18963    /// Crate-internal constructor.
18964    #[inline]
18965    #[must_use]
18966    #[allow(dead_code)]
18967    pub(crate) const fn new(address: ContentAddress) -> Self {
18968        Self {
18969            address,
18970            _sealed: (),
18971        }
18972    }
18973}
18974
18975/// v0.2.2 Phase E: typed query coordinate parametric over WittLevel.
18976#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18977pub struct Coordinate<L> {
18978    stratum: u64,
18979    spectrum: u64,
18980    address: u64,
18981    _level: PhantomData<L>,
18982    _sealed: (),
18983}
18984
18985impl<L> Coordinate<L> {
18986    /// Returns the stratum coordinate.
18987    #[inline]
18988    #[must_use]
18989    pub const fn stratum(&self) -> u64 {
18990        self.stratum
18991    }
18992
18993    /// Returns the spectrum coordinate.
18994    #[inline]
18995    #[must_use]
18996    pub const fn spectrum(&self) -> u64 {
18997        self.spectrum
18998    }
18999
19000    /// Returns the address coordinate.
19001    #[inline]
19002    #[must_use]
19003    pub const fn address(&self) -> u64 {
19004        self.address
19005    }
19006
19007    /// Crate-internal constructor.
19008    #[inline]
19009    #[must_use]
19010    #[allow(dead_code)]
19011    pub(crate) const fn new(stratum: u64, spectrum: u64, address: u64) -> Self {
19012        Self {
19013            stratum,
19014            spectrum,
19015            address,
19016            _level: PhantomData,
19017            _sealed: (),
19018        }
19019    }
19020}
19021
19022/// v0.2.2 Phase E: sealed binding query handle.
19023#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19024pub struct BindingQuery {
19025    address: ContentAddress,
19026    _sealed: (),
19027}
19028
19029impl BindingQuery {
19030    /// Returns the content-hashed binding query address.
19031    #[inline]
19032    #[must_use]
19033    pub const fn address(&self) -> ContentAddress {
19034        self.address
19035    }
19036
19037    /// Crate-internal constructor.
19038    #[inline]
19039    #[must_use]
19040    #[allow(dead_code)]
19041    pub(crate) const fn new(address: ContentAddress) -> Self {
19042        Self {
19043            address,
19044            _sealed: (),
19045        }
19046    }
19047}
19048
19049/// v0.2.2 Phase E: sealed Partition handle over the bridge:partition
19050/// component classification produced during grounding.
19051#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19052pub struct Partition {
19053    component: PartitionComponent,
19054    _sealed: (),
19055}
19056
19057impl Partition {
19058    /// Returns the component classification.
19059    #[inline]
19060    #[must_use]
19061    pub const fn component(&self) -> PartitionComponent {
19062        self.component
19063    }
19064
19065    /// Crate-internal constructor.
19066    #[inline]
19067    #[must_use]
19068    #[allow(dead_code)]
19069    pub(crate) const fn new(component: PartitionComponent) -> Self {
19070        Self {
19071            component,
19072            _sealed: (),
19073        }
19074    }
19075}
19076
19077/// v0.2.2 Phase E: a single event in a derivation Trace.
19078/// Fixed-size event; content-addressed so Trace replays are stable
19079/// across builds. The verifier in `uor-foundation-verify` (Phase H)
19080/// reconstructs the witness chain by walking a `Trace` iterator.
19081#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19082pub struct TraceEvent {
19083    /// Step index in the derivation.
19084    step_index: u32,
19085    /// Primitive op applied at this step.
19086    op: PrimitiveOp,
19087    /// Content-hashed target address the op produced.
19088    target: ContentAddress,
19089    /// Sealing marker.
19090    _sealed: (),
19091}
19092
19093impl TraceEvent {
19094    /// Returns the step index.
19095    #[inline]
19096    #[must_use]
19097    pub const fn step_index(&self) -> u32 {
19098        self.step_index
19099    }
19100
19101    /// Returns the primitive op applied at this step.
19102    #[inline]
19103    #[must_use]
19104    pub const fn op(&self) -> PrimitiveOp {
19105        self.op
19106    }
19107
19108    /// Returns the content-hashed target address.
19109    #[inline]
19110    #[must_use]
19111    pub const fn target(&self) -> ContentAddress {
19112        self.target
19113    }
19114
19115    /// Crate-internal constructor.
19116    #[inline]
19117    #[must_use]
19118    #[allow(dead_code)]
19119    pub(crate) const fn new(step_index: u32, op: PrimitiveOp, target: ContentAddress) -> Self {
19120        Self {
19121            step_index,
19122            op,
19123            target,
19124            _sealed: (),
19125        }
19126    }
19127}
19128
19129/// Fixed-capacity derivation trace. Holds up to `TR_MAX` events inline;
19130/// no heap. Produced by `Derivation::replay()` and consumed by
19131/// `uor-foundation-verify`. `TR_MAX` is the const-generic that carries
19132/// the application's selected `<MyBounds as HostBounds>::TRACE_MAX_EVENTS`;
19133/// the default const-generic resolves to `DefaultHostBounds`'s 256.
19134/// Carries `witt_level_bits` and `content_fingerprint` so `verify_trace`
19135/// can reconstruct the source `GroundingCertificate` via structural-
19136/// validation + fingerprint passthrough (no hash recomputation).
19137#[derive(Debug, Clone, Copy)]
19138pub struct Trace<const TR_MAX: usize = 256> {
19139    events: [Option<TraceEvent>; TR_MAX],
19140    len: u16,
19141    /// Witt level the source grounding was minted at, packed
19142    /// by `Derivation::replay` from the parent `Grounded::witt_level_bits`.
19143    /// `verify_trace` reads this back to populate the certificate.
19144    witt_level_bits: u16,
19145    /// Parametric content fingerprint of the source unit's full state,
19146    /// computed at grounding time by the consumer-supplied `Hasher` and
19147    /// packed in by `Derivation::replay`. `verify_trace` passes it through
19148    /// unchanged. The fingerprint's `FP_MAX` follows the application's
19149    /// selected `<MyBounds as HostBounds>::FINGERPRINT_MAX_BYTES`; this
19150    /// field uses the default-bound `ContentFingerprint`.
19151    content_fingerprint: ContentFingerprint,
19152    _sealed: (),
19153}
19154
19155impl<const TR_MAX: usize> Trace<TR_MAX> {
19156    /// An empty Trace.
19157    #[inline]
19158    #[must_use]
19159    pub const fn empty() -> Self {
19160        Self {
19161            events: [None; TR_MAX],
19162            len: 0,
19163            witt_level_bits: 0,
19164            content_fingerprint: ContentFingerprint::zero(),
19165            _sealed: (),
19166        }
19167    }
19168
19169    /// Crate-internal ctor for `Derivation::replay()` only.
19170    /// Bypasses validation because `replay()` constructs events from
19171    /// foundation-guaranteed-valid state (monotonic, contiguous, non-zero
19172    /// seed). No public path reaches this constructor; downstream uses the
19173    /// validating `try_from_events` instead.
19174    #[inline]
19175    #[must_use]
19176    #[allow(dead_code)]
19177    pub(crate) const fn from_replay_events_const(
19178        events: [Option<TraceEvent>; TR_MAX],
19179        len: u16,
19180        witt_level_bits: u16,
19181        content_fingerprint: ContentFingerprint,
19182    ) -> Self {
19183        Self {
19184            events,
19185            len,
19186            witt_level_bits,
19187            content_fingerprint,
19188            _sealed: (),
19189        }
19190    }
19191
19192    /// Number of events recorded.
19193    #[inline]
19194    #[must_use]
19195    pub const fn len(&self) -> u16 {
19196        self.len
19197    }
19198
19199    /// Whether the Trace is empty.
19200    #[inline]
19201    #[must_use]
19202    pub const fn is_empty(&self) -> bool {
19203        self.len == 0
19204    }
19205
19206    /// Access the event at the given index, or `None` if out of range.
19207    #[inline]
19208    #[must_use]
19209    pub fn event(&self, index: usize) -> Option<&TraceEvent> {
19210        self.events.get(index).and_then(|e| e.as_ref())
19211    }
19212
19213    /// v0.2.2 T5: returns the Witt level the source grounding was minted at.
19214    /// Carried through replay so `verify_trace` can populate the certificate.
19215    #[inline]
19216    #[must_use]
19217    pub const fn witt_level_bits(&self) -> u16 {
19218        self.witt_level_bits
19219    }
19220
19221    /// v0.2.2 T5: returns the parametric content fingerprint of the source
19222    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
19223    /// `verify_trace` passes this through unchanged into the re-derived
19224    /// certificate, upholding the round-trip property.
19225    #[inline]
19226    #[must_use]
19227    pub const fn content_fingerprint(&self) -> ContentFingerprint {
19228        self.content_fingerprint
19229    }
19230
19231    /// Validating constructor. Checks every invariant the verify path
19232    /// relies on: events are contiguous from index 0, no event has a zero
19233    /// target, and the slice fits within `TR_MAX` events.
19234    /// # Errors
19235    /// - `ReplayError::EmptyTrace` if `events.is_empty()`.
19236    /// - `ReplayError::CapacityExceeded { declared, provided }` if the
19237    ///   slice exceeds `TR_MAX`.
19238    /// - `ReplayError::OutOfOrderEvent { index }` if the event at `index`
19239    ///   has a `step_index` not equal to `index` (strict contiguity).
19240    /// - `ReplayError::ZeroTarget { index }` if any event carries a zero
19241    ///   `ContentAddress` target.
19242    pub fn try_from_events(
19243        events: &[TraceEvent],
19244        witt_level_bits: u16,
19245        content_fingerprint: ContentFingerprint,
19246    ) -> Result<Self, ReplayError> {
19247        if events.is_empty() {
19248            return Err(ReplayError::EmptyTrace);
19249        }
19250        if events.len() > TR_MAX {
19251            return Err(ReplayError::CapacityExceeded {
19252                declared: TR_MAX as u16,
19253                provided: events.len() as u32,
19254            });
19255        }
19256        let mut i = 0usize;
19257        while i < events.len() {
19258            let e = &events[i];
19259            if e.step_index() as usize != i {
19260                return Err(ReplayError::OutOfOrderEvent { index: i });
19261            }
19262            if e.target().is_zero() {
19263                return Err(ReplayError::ZeroTarget { index: i });
19264            }
19265            i += 1;
19266        }
19267        let mut arr = [None; TR_MAX];
19268        let mut j = 0usize;
19269        while j < events.len() {
19270            arr[j] = Some(events[j]);
19271            j += 1;
19272        }
19273        Ok(Self {
19274            events: arr,
19275            len: events.len() as u16,
19276            witt_level_bits,
19277            content_fingerprint,
19278            _sealed: (),
19279        })
19280    }
19281}
19282
19283impl<const TR_MAX: usize> Default for Trace<TR_MAX> {
19284    #[inline]
19285    fn default() -> Self {
19286        Self::empty()
19287    }
19288}
19289
19290/// v0.2.2 Phase E / T2.6: `Derivation::replay()` produces a content-addressed
19291/// Trace the verifier can re-walk without invoking the deciders. The trace
19292/// length matches the derivation's `step_count()`, and each event's
19293/// `step_index` reflects its position in the derivation.
19294impl Derivation {
19295    /// Replay this derivation as a fixed-size `Trace<TR_MAX>` whose length matches
19296    /// `self.step_count()` (capped at the application's `<HostBounds>::TRACE_MAX_EVENTS`).
19297    /// Callers either annotate the binding (`let trace: Trace = ...;` picks
19298    /// `DefaultHostBounds`'s 256) or use turbofish (`derivation.replay::<1024>()`).
19299    /// # Example
19300    /// ```no_run
19301    /// use uor_foundation::enforcement::{
19302    ///     replay, CompileUnitBuilder, ConstrainedTypeInput, Grounded, Term, Trace,
19303    /// };
19304    /// use uor_foundation::pipeline::run;
19305    /// use uor_foundation::{VerificationDomain, WittLevel};
19306    /// # use uor_foundation::enforcement::Hasher;
19307    /// # struct H; impl Hasher for H {
19308    /// #     const OUTPUT_BYTES: usize = 16;
19309    /// #     fn initial() -> Self { Self }
19310    /// #     fn fold_byte(self, _: u8) -> Self { self }
19311    /// #     fn finalize(self) -> [u8; 32] { [0; 32] } }
19312    /// static TERMS: &[Term] = &[uor_foundation::pipeline::literal_u64(7, WittLevel::W8)];
19313    /// static DOMS: &[VerificationDomain] = &[VerificationDomain::Enumerative];
19314    /// let unit = CompileUnitBuilder::new()
19315    ///     .root_term(TERMS).witt_level_ceiling(WittLevel::W32)
19316    ///     .thermodynamic_budget(1024).target_domains(DOMS)
19317    ///     .result_type::<ConstrainedTypeInput>()
19318    ///     .validate().expect("unit well-formed");
19319    /// let grounded: Grounded<ConstrainedTypeInput> =
19320    ///     run::<ConstrainedTypeInput, _, H>(unit).expect("grounds");
19321    /// // Replay → round-trip verification. The trace's event-count
19322    /// // capacity comes from the application's `HostBounds`; here the
19323    /// // type-annotated binding inherits `DefaultHostBounds`'s 256.
19324    /// let trace: Trace = grounded.derivation().replay();
19325    /// let recert = replay::certify_from_trace(&trace).expect("valid trace");
19326    /// assert_eq!(recert.certificate().content_fingerprint(),
19327    ///            grounded.content_fingerprint());
19328    /// ```
19329    #[inline]
19330    #[must_use]
19331    pub fn replay<const TR_MAX: usize>(&self) -> Trace<TR_MAX> {
19332        let steps = self.step_count() as usize;
19333        let len = if steps > TR_MAX { TR_MAX } else { steps };
19334        let mut events = [None; TR_MAX];
19335        // Seed targets from the leading 8 bytes of the source
19336        // `content_fingerprint` (substrate-computed). Combined with `| 1` so
19337        // the first event's target is guaranteed nonzero even when the
19338        // leading bytes are all zero, and XOR with `(i + 1)` keeps the
19339        // sequence non-degenerate.
19340        let fp = self.content_fingerprint.as_bytes();
19341        let seed =
19342            u64::from_be_bytes([fp[0], fp[1], fp[2], fp[3], fp[4], fp[5], fp[6], fp[7]]) as u128;
19343        let nonzero_seed = seed | 1u128;
19344        let mut i = 0usize;
19345        while i < len {
19346            let target_raw = nonzero_seed ^ ((i as u128) + 1u128);
19347            events[i] = Some(TraceEvent::new(
19348                i as u32,
19349                crate::PrimitiveOp::Add,
19350                ContentAddress::from_u128(target_raw),
19351            ));
19352            i += 1;
19353        }
19354        // Pack the source `witt_level_bits` and `content_fingerprint`
19355        // into the Trace so `verify_trace` can reproduce the source certificate
19356        // via passthrough. The fingerprint was computed at grounding time by the
19357        // consumer-supplied Hasher and stored on the parent Grounded; the
19358        // Derivation accessor read it through.
19359        Trace::from_replay_events_const(
19360            events,
19361            len as u16,
19362            self.witt_level_bits,
19363            self.content_fingerprint,
19364        )
19365    }
19366}
19367
19368/// v0.2.2 T5: errors emitted by the trace-replay re-derivation path.
19369#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19370#[non_exhaustive]
19371pub enum ReplayError {
19372    /// The trace was empty; nothing to replay.
19373    EmptyTrace,
19374    /// Event at `index` has a non-monotonic step_index.
19375    OutOfOrderEvent {
19376        /// The event index that was out of order.
19377        index: usize,
19378    },
19379    /// Event at `index` carries a zero ContentAddress (forbidden in well-formed traces).
19380    ZeroTarget {
19381        /// The event index that carried a zero target.
19382        index: usize,
19383    },
19384    /// v0.2.2 T5.8: event step indices do not form a contiguous sequence
19385    /// `[0, 1, ..., len-1]`. Replaces the misleadingly-named v0.2.1
19386    /// `LengthMismatch` variant. The trace has the right number of
19387    /// events, but their step indices skip values (e.g., `[0, 2, 5]`
19388    /// with `len = 3`).
19389    NonContiguousSteps {
19390        /// The trace's declared length (number of events).
19391        declared: u16,
19392        /// The largest step_index observed in the event sequence.
19393        /// Always strictly greater than `declared - 1` when this
19394        /// variant fires.
19395        last_step: u32,
19396    },
19397    /// A caller attempted to construct a `Trace<TR_MAX>` whose event count
19398    /// exceeds `TR_MAX` (the application's `<HostBounds>::TRACE_MAX_EVENTS`).
19399    /// Distinct from `NonContiguousSteps` because the recovery is different
19400    /// (truncate vs. close gaps). Returned by `Trace::try_from_events`,
19401    /// never by `verify_trace` (the verifier reads from an existing `Trace`
19402    /// whose capacity is already enforced by the type's storage).
19403    CapacityExceeded {
19404        /// The trace's hard capacity (`TR_MAX`).
19405        declared: u16,
19406        /// The actual event count the caller attempted to pack in.
19407        provided: u32,
19408    },
19409}
19410
19411impl core::fmt::Display for ReplayError {
19412    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19413        match self {
19414            Self::EmptyTrace => f.write_str("trace was empty; nothing to replay"),
19415            Self::OutOfOrderEvent { index } => write!(
19416                f,
19417                "event at index {index} has out-of-order step index",
19418            ),
19419            Self::ZeroTarget { index } => write!(
19420                f,
19421                "event at index {index} has a zero ContentAddress target",
19422            ),
19423            Self::NonContiguousSteps { declared, last_step } => write!(
19424                f,
19425                "trace declares {declared} events but step indices skip values \
19426                 (last step {last_step})",
19427            ),
19428            Self::CapacityExceeded { declared, provided } => write!(
19429                f,
19430                "trace capacity exceeded: tried to pack {provided} events into a buffer of {declared}",
19431            ),
19432        }
19433    }
19434}
19435
19436impl core::error::Error for ReplayError {}
19437
19438/// v0.2.2 T5: trace-replay re-derivation module.
19439/// The foundation owns the certificate-construction boundary; the
19440/// `uor-foundation-verify` crate is a thin facade that delegates to
19441/// `replay::certify_from_trace`. This preserves sealing discipline:
19442/// `Certified::new` stays `pub(crate)` and no external crate can mint a
19443/// certificate.
19444pub mod replay {
19445    use super::{Certified, GroundingCertificate, ReplayError, Trace};
19446
19447    /// Re-derive the `Certified<GroundingCertificate>` that the foundation
19448    /// grounding path produced for the source unit.
19449    /// Validates the trace's structural invariants (monotonic, contiguous
19450    /// step indices; no zero targets; no None slots in the populated
19451    /// prefix) and re-packages the trace's stored `ContentFingerprint` and
19452    /// `witt_level_bits` into a fresh certificate. The verifier does NOT
19453    /// invoke a hash function: the fingerprint is *data carried by the
19454    /// Trace*, computed at mint time by the consumer-supplied `Hasher` and
19455    /// passed through unchanged.
19456    /// # Round-trip property
19457    /// For every `Grounded<T>` produced by `pipeline::run::<T, _, H>` with
19458    /// a conforming substrate `H: Hasher`:
19459    /// ```text
19460    /// verify_trace(&grounded.derivation().replay()).certificate()
19461    ///     == grounded.certificate()
19462    /// ```
19463    /// holds bit-identically. The contract is orthogonal to the substrate
19464    /// hasher choice and to the chosen `OUTPUT_BYTES` width.
19465    /// # Errors
19466    /// Returns:
19467    /// - `ReplayError::EmptyTrace` if `trace.is_empty()`.
19468    /// - `ReplayError::OutOfOrderEvent { index }` if step indices are not
19469    ///   strictly monotonic at position `index`.
19470    /// - `ReplayError::ZeroTarget { index }` if any event carries
19471    ///   `ContentAddress::zero()`.
19472    /// - `ReplayError::NonContiguousSteps { declared, last_step }` if
19473    ///   the event step indices skip values.
19474    pub fn certify_from_trace<const TR_MAX: usize>(
19475        trace: &Trace<TR_MAX>,
19476    ) -> Result<Certified<GroundingCertificate>, ReplayError> {
19477        let len = trace.len() as usize;
19478        if len == 0 {
19479            return Err(ReplayError::EmptyTrace);
19480        }
19481        // Structural validation: monotonic step indices, contiguous from 0,
19482        // no zero targets, no None slots in the populated prefix.
19483        let mut last_step: i64 = -1;
19484        let mut max_step_index: u32 = 0;
19485        let mut i = 0usize;
19486        while i < len {
19487            let event = match trace.event(i) {
19488                Some(e) => e,
19489                None => return Err(ReplayError::OutOfOrderEvent { index: i }),
19490            };
19491            let step_index = event.step_index();
19492            if (step_index as i64) <= last_step {
19493                return Err(ReplayError::OutOfOrderEvent { index: i });
19494            }
19495            if event.target().is_zero() {
19496                return Err(ReplayError::ZeroTarget { index: i });
19497            }
19498            if step_index > max_step_index {
19499                max_step_index = step_index;
19500            }
19501            last_step = step_index as i64;
19502            i += 1;
19503        }
19504        if (max_step_index as u16).saturating_add(1) != trace.len() {
19505            return Err(ReplayError::NonContiguousSteps {
19506                declared: trace.len(),
19507                last_step: max_step_index,
19508            });
19509        }
19510        // v0.2.2 T5: fingerprint passthrough. The trace was minted by the
19511        // foundation pipeline with a `ContentFingerprint` already computed by
19512        // the consumer-supplied `Hasher`. The verifier does not invoke any
19513        // hash function; it copies the fingerprint through unchanged. The
19514        // round-trip property holds by construction. v0.2.2 T6.5: the
19515        // FingerprintMissing variant is removed because under T6.3 / T6.10,
19516        // no public path can produce a Trace with a zero fingerprint.
19517        Ok(Certified::new(
19518            GroundingCertificate::with_level_and_fingerprint_const(
19519                trace.witt_level_bits(),
19520                trace.content_fingerprint(),
19521            ),
19522        ))
19523    }
19524}
19525
19526/// v0.2.2 Phase E: sealed builder for an InteractionDeclaration.
19527/// Validates the peer protocol, convergence predicate, and
19528/// commutator state class required by `conformance:InteractionShape`.
19529/// Phase F wires the full `InteractionDriver` on top of this builder.
19530#[derive(Debug, Clone, Copy, Default)]
19531pub struct InteractionDeclarationBuilder {
19532    peer_protocol: Option<u128>,
19533    convergence_predicate: Option<u128>,
19534    commutator_state_class: Option<u128>,
19535}
19536
19537impl InteractionDeclarationBuilder {
19538    /// Construct a new builder.
19539    #[inline]
19540    #[must_use]
19541    pub const fn new() -> Self {
19542        Self {
19543            peer_protocol: None,
19544            convergence_predicate: None,
19545            commutator_state_class: None,
19546        }
19547    }
19548
19549    /// Set the peer protocol content address.
19550    #[inline]
19551    #[must_use]
19552    pub const fn peer_protocol(mut self, address: u128) -> Self {
19553        self.peer_protocol = Some(address);
19554        self
19555    }
19556
19557    /// Set the convergence predicate content address.
19558    #[inline]
19559    #[must_use]
19560    pub const fn convergence_predicate(mut self, address: u128) -> Self {
19561        self.convergence_predicate = Some(address);
19562        self
19563    }
19564
19565    /// Set the commutator state class content address.
19566    #[inline]
19567    #[must_use]
19568    pub const fn commutator_state_class(mut self, address: u128) -> Self {
19569        self.commutator_state_class = Some(address);
19570        self
19571    }
19572
19573    /// Phase E.6: validate against `conformance:InteractionShape`.
19574    /// # Errors
19575    /// Returns `ShapeViolation` if any of the three required fields is missing.
19576    pub fn validate(&self) -> Result<Validated<InteractionShape>, ShapeViolation> {
19577        self.validate_common().map(|_| {
19578            Validated::new(InteractionShape {
19579                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19580            })
19581        })
19582    }
19583
19584    /// Phase E.6 + C.1: const-fn companion.
19585    /// # Errors
19586    /// Returns `ShapeViolation` if any required field is missing.
19587    pub const fn validate_const(
19588        &self,
19589    ) -> Result<Validated<InteractionShape, CompileTime>, ShapeViolation> {
19590        if self.peer_protocol.is_none() {
19591            return Err(ShapeViolation {
19592                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19593                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19594                property_iri: "https://uor.foundation/interaction/peerProtocol",
19595                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19596                min_count: 1,
19597                max_count: 1,
19598                kind: ViolationKind::Missing,
19599            });
19600        }
19601        if self.convergence_predicate.is_none() {
19602            return Err(ShapeViolation {
19603                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19604                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19605                property_iri: "https://uor.foundation/interaction/convergencePredicate",
19606                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19607                min_count: 1,
19608                max_count: 1,
19609                kind: ViolationKind::Missing,
19610            });
19611        }
19612        if self.commutator_state_class.is_none() {
19613            return Err(ShapeViolation {
19614                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19615                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19616                property_iri: "https://uor.foundation/interaction/commutatorStateClass",
19617                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19618                min_count: 1,
19619                max_count: 1,
19620                kind: ViolationKind::Missing,
19621            });
19622        }
19623        Ok(Validated::new(InteractionShape {
19624            shape_iri: "https://uor.foundation/conformance/InteractionShape",
19625        }))
19626    }
19627
19628    fn validate_common(&self) -> Result<(), ShapeViolation> {
19629        self.validate_const().map(|_| ())
19630    }
19631}
19632
19633/// Phase E.6: validated InteractionDeclaration per `conformance:InteractionShape`.
19634#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19635pub struct InteractionShape {
19636    /// Shape IRI this declaration was validated against.
19637    pub shape_iri: &'static str,
19638}
19639
19640/// Phase E.5 (target §7.4): observability subscribe API.
19641/// When the `observability` feature is enabled, downstream may call
19642/// `subscribe_trace_events` with a handler closure that receives each
19643/// `TraceEvent` as the pipeline emits it. When the feature is off, this
19644/// function is entirely absent from the public API.
19645#[cfg(feature = "observability")]
19646pub fn subscribe_trace_events<F>(handler: F) -> ObservabilitySubscription<F>
19647where
19648    F: FnMut(&TraceEvent),
19649{
19650    ObservabilitySubscription {
19651        handler,
19652        _sealed: (),
19653    }
19654}
19655
19656#[cfg(feature = "observability")]
19657/// Phase E.5: sealed subscription handle returned by `subscribe_trace_events`.
19658#[cfg(feature = "observability")]
19659pub struct ObservabilitySubscription<F: FnMut(&TraceEvent)> {
19660    handler: F,
19661    _sealed: (),
19662}
19663
19664#[cfg(feature = "observability")]
19665impl<F: FnMut(&TraceEvent)> ObservabilitySubscription<F> {
19666    /// Dispatch a TraceEvent through the subscribed handler.
19667    pub fn emit(&mut self, event: &TraceEvent) {
19668        (self.handler)(event);
19669    }
19670}
19671
19672/// Phase F.2 (target §4.7): closed enumeration of the six constraint kinds.
19673/// `type-decl` bodies enumerate exactly these six kinds per `uor_term.ebnf`'s
19674/// `constraint-decl` production. `CompositeConstraint` — the implicit shape of
19675/// a multi-decl body — has no syntactic constructor and is therefore not a
19676/// variant of this enum.
19677#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19678#[non_exhaustive]
19679pub enum ConstraintKind {
19680    /// `type:ResidueConstraint` — value is congruent to `r (mod m)`.
19681    Residue,
19682    /// `type:CarryConstraint` — bounded carry depth.
19683    Carry,
19684    /// `type:DepthConstraint` — bounded derivation depth.
19685    Depth,
19686    /// `type:HammingConstraint` — bounded Hamming distance from a reference.
19687    Hamming,
19688    /// `type:SiteConstraint` — per-site cardinality or containment.
19689    Site,
19690    /// `type:AffineConstraint` — linear inequality over site values.
19691    Affine,
19692}
19693
19694/// Phase F.3 (target §4.7 carry): sealed per-ring-op carry profile.
19695#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19696pub struct CarryProfile {
19697    chain_length: u32,
19698    max_depth: u32,
19699    _sealed: (),
19700}
19701
19702impl CarryProfile {
19703    /// Length of the longest carry chain observed.
19704    #[inline]
19705    #[must_use]
19706    pub const fn chain_length(&self) -> u32 {
19707        self.chain_length
19708    }
19709
19710    /// Maximum carry depth across the op.
19711    #[inline]
19712    #[must_use]
19713    pub const fn max_depth(&self) -> u32 {
19714        self.max_depth
19715    }
19716
19717    /// Crate-internal constructor.
19718    #[inline]
19719    #[must_use]
19720    #[allow(dead_code)]
19721    pub(crate) const fn new(chain_length: u32, max_depth: u32) -> Self {
19722        Self {
19723            chain_length,
19724            max_depth,
19725            _sealed: (),
19726        }
19727    }
19728}
19729
19730/// Phase F.3 (target §4.7 carry): sealed carry-event witness — records the ring op
19731/// and two `Datum<L>` witt widths involved.
19732#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19733pub struct CarryEvent {
19734    left_bits: u16,
19735    right_bits: u16,
19736    _sealed: (),
19737}
19738
19739impl CarryEvent {
19740    /// Witt bit-width of the left operand.
19741    #[inline]
19742    #[must_use]
19743    pub const fn left_bits(&self) -> u16 {
19744        self.left_bits
19745    }
19746
19747    /// Witt bit-width of the right operand.
19748    #[inline]
19749    #[must_use]
19750    pub const fn right_bits(&self) -> u16 {
19751        self.right_bits
19752    }
19753
19754    /// Crate-internal constructor.
19755    #[inline]
19756    #[must_use]
19757    #[allow(dead_code)]
19758    pub(crate) const fn new(left_bits: u16, right_bits: u16) -> Self {
19759        Self {
19760            left_bits,
19761            right_bits,
19762            _sealed: (),
19763        }
19764    }
19765}
19766
19767/// Phase F.3 (target §4.7 convergence): sealed convergence-level witness at `L`.
19768#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19769pub struct ConvergenceLevel<L> {
19770    valuation: u32,
19771    _level: PhantomData<L>,
19772    _sealed: (),
19773}
19774
19775impl<L> ConvergenceLevel<L> {
19776    /// The v₂ valuation of the datum at this convergence level.
19777    #[inline]
19778    #[must_use]
19779    pub const fn valuation(&self) -> u32 {
19780        self.valuation
19781    }
19782
19783    /// Crate-internal constructor.
19784    #[inline]
19785    #[must_use]
19786    #[allow(dead_code)]
19787    pub(crate) const fn new(valuation: u32) -> Self {
19788        Self {
19789            valuation,
19790            _level: PhantomData,
19791            _sealed: (),
19792        }
19793    }
19794}
19795
19796/// Phase F.3 (target §4.7 division): sealed enum over the four normed division
19797/// algebras from Cayley-Dickson. No other admissible algebra exists (Hurwitz's theorem).
19798#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19799#[non_exhaustive]
19800pub enum DivisionAlgebraWitness {
19801    /// Real numbers ℝ (dimension 1).
19802    Real,
19803    /// Complex numbers ℂ (dimension 2).
19804    Complex,
19805    /// Quaternions ℍ (dimension 4, non-commutative).
19806    Quaternion,
19807    /// Octonions 𝕆 (dimension 8, non-commutative, non-associative).
19808    Octonion,
19809}
19810
19811/// Phase F.3 (target §4.7 monoidal): sealed monoidal-product witness.
19812#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19813pub struct MonoidalProduct<L, R> {
19814    _left: PhantomData<L>,
19815    _right: PhantomData<R>,
19816    _sealed: (),
19817}
19818
19819impl<L, R> MonoidalProduct<L, R> {
19820    /// Crate-internal constructor.
19821    #[inline]
19822    #[must_use]
19823    #[allow(dead_code)]
19824    pub(crate) const fn new() -> Self {
19825        Self {
19826            _left: PhantomData,
19827            _right: PhantomData,
19828            _sealed: (),
19829        }
19830    }
19831}
19832
19833/// Phase F.3 (target §4.7 monoidal): sealed monoidal-unit witness at `L`.
19834#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19835pub struct MonoidalUnit<L> {
19836    _level: PhantomData<L>,
19837    _sealed: (),
19838}
19839
19840impl<L> MonoidalUnit<L> {
19841    /// Crate-internal constructor.
19842    #[inline]
19843    #[must_use]
19844    #[allow(dead_code)]
19845    pub(crate) const fn new() -> Self {
19846        Self {
19847            _level: PhantomData,
19848            _sealed: (),
19849        }
19850    }
19851}
19852
19853/// Phase F.1 (target §4.7 operad): sealed operad-composition witness.
19854/// Every `type-app` form in the term grammar materializes a fresh `OperadComposition`
19855/// carrying the outer/inner type IRIs and composed site count, per `operad:` ontology.
19856#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19857pub struct OperadComposition {
19858    outer_type_iri: &'static str,
19859    inner_type_iri: &'static str,
19860    composed_site_count: u32,
19861    _sealed: (),
19862}
19863
19864impl OperadComposition {
19865    /// IRI of the outer `type:TypeDefinition`.
19866    #[inline]
19867    #[must_use]
19868    pub const fn outer_type_iri(&self) -> &'static str {
19869        self.outer_type_iri
19870    }
19871
19872    /// IRI of the inner `type:TypeDefinition`.
19873    #[inline]
19874    #[must_use]
19875    pub const fn inner_type_iri(&self) -> &'static str {
19876        self.inner_type_iri
19877    }
19878
19879    /// Site count of the composed type.
19880    #[inline]
19881    #[must_use]
19882    pub const fn composed_site_count(&self) -> u32 {
19883        self.composed_site_count
19884    }
19885
19886    /// Crate-internal constructor.
19887    #[inline]
19888    #[must_use]
19889    #[allow(dead_code)]
19890    pub(crate) const fn new(
19891        outer_type_iri: &'static str,
19892        inner_type_iri: &'static str,
19893        composed_site_count: u32,
19894    ) -> Self {
19895        Self {
19896            outer_type_iri,
19897            inner_type_iri,
19898            composed_site_count,
19899            _sealed: (),
19900        }
19901    }
19902}
19903
19904/// Phase F.3 (target §4.7 recursion): maximum depth of the recursion trace
19905/// witness. Bounded by the declared descent budget at builder-validate time;
19906/// the constant is a size-budget cap matching other foundation arenas.
19907/// Wiki ADR-037: alias of [`crate::HostBounds::RECURSION_TRACE_DEPTH_MAX`] via
19908/// [`crate::DefaultHostBounds`].
19909pub const RECURSION_TRACE_MAX_DEPTH: usize =
19910    <crate::DefaultHostBounds as crate::HostBounds>::RECURSION_TRACE_DEPTH_MAX;
19911
19912/// Phase F.3 (target §4.7 recursion): sealed recursion trace with fixed-capacity
19913/// descent-measure sequence.
19914#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19915pub struct RecursionTrace {
19916    depth: u32,
19917    measure: [u32; RECURSION_TRACE_MAX_DEPTH],
19918    _sealed: (),
19919}
19920
19921impl RecursionTrace {
19922    /// Number of recursive descents in this trace.
19923    #[inline]
19924    #[must_use]
19925    pub const fn depth(&self) -> u32 {
19926        self.depth
19927    }
19928
19929    /// Descent-measure sequence.
19930    #[inline]
19931    #[must_use]
19932    pub const fn measure(&self) -> &[u32; RECURSION_TRACE_MAX_DEPTH] {
19933        &self.measure
19934    }
19935
19936    /// Crate-internal constructor.
19937    #[inline]
19938    #[must_use]
19939    #[allow(dead_code)]
19940    pub(crate) const fn new(depth: u32, measure: [u32; RECURSION_TRACE_MAX_DEPTH]) -> Self {
19941        Self {
19942            depth,
19943            measure,
19944            _sealed: (),
19945        }
19946    }
19947}
19948
19949/// Phase F.3 (target §4.7 region): sealed address-region witness.
19950#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19951pub struct AddressRegion {
19952    base: u128,
19953    extent: u64,
19954    _sealed: (),
19955}
19956
19957impl AddressRegion {
19958    /// Base address of the region.
19959    #[inline]
19960    #[must_use]
19961    pub const fn base(&self) -> u128 {
19962        self.base
19963    }
19964
19965    /// Extent (number of addressable cells).
19966    #[inline]
19967    #[must_use]
19968    pub const fn extent(&self) -> u64 {
19969        self.extent
19970    }
19971
19972    /// Crate-internal constructor.
19973    #[inline]
19974    #[must_use]
19975    #[allow(dead_code)]
19976    pub(crate) const fn new(base: u128, extent: u64) -> Self {
19977        Self {
19978            base,
19979            extent,
19980            _sealed: (),
19981        }
19982    }
19983}
19984
19985/// Phase F.3 (target §4.7 linear): sealed linear-resource budget.
19986#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19987pub struct LinearBudget {
19988    sites_remaining: u64,
19989    _sealed: (),
19990}
19991
19992impl LinearBudget {
19993    /// Number of linear sites still available for allocation.
19994    #[inline]
19995    #[must_use]
19996    pub const fn sites_remaining(&self) -> u64 {
19997        self.sites_remaining
19998    }
19999
20000    /// Crate-internal constructor.
20001    #[inline]
20002    #[must_use]
20003    #[allow(dead_code)]
20004    pub(crate) const fn new(sites_remaining: u64) -> Self {
20005        Self {
20006            sites_remaining,
20007            _sealed: (),
20008        }
20009    }
20010}
20011
20012/// Phase F.3 (target §4.7 linear): sealed lease-allocation witness.
20013#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20014pub struct LeaseAllocation {
20015    site_count: u32,
20016    scope_hash: u128,
20017    _sealed: (),
20018}
20019
20020impl LeaseAllocation {
20021    /// Number of linear sites taken by this allocation.
20022    #[inline]
20023    #[must_use]
20024    pub const fn site_count(&self) -> u32 {
20025        self.site_count
20026    }
20027
20028    /// Content-hash of the lease scope identifier.
20029    #[inline]
20030    #[must_use]
20031    pub const fn scope_hash(&self) -> u128 {
20032        self.scope_hash
20033    }
20034
20035    /// Crate-internal constructor.
20036    #[inline]
20037    #[must_use]
20038    #[allow(dead_code)]
20039    pub(crate) const fn new(site_count: u32, scope_hash: u128) -> Self {
20040        Self {
20041            site_count,
20042            scope_hash,
20043            _sealed: (),
20044        }
20045    }
20046}
20047
20048/// v0.2.2 Phase J: zero-sized token identifying the `Total` marker.
20049#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
20050pub struct TotalMarker;
20051
20052/// v0.2.2 Phase J: zero-sized token identifying the `Invertible` marker.
20053#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
20054pub struct InvertibleMarker;
20055
20056/// v0.2.2 Phase J: zero-sized token identifying the `PreservesStructure` marker.
20057#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
20058pub struct PreservesStructureMarker;
20059
20060mod marker_tuple_sealed {
20061    /// Private supertrait. Not implementable outside this crate.
20062    pub trait Sealed {}
20063}
20064
20065/// v0.2.2 Phase J: sealed marker-tuple trait. Implemented exhaustively by
20066/// the closed catalogue of six admissible marker tuples in canonical order
20067/// (Total, Invertible, PreservesStructure). Downstream cannot add new
20068/// marker tuples; the seal anchors Phase J's compile-time correctness claim.
20069pub trait MarkerTuple: marker_tuple_sealed::Sealed {}
20070
20071impl marker_tuple_sealed::Sealed for () {}
20072impl MarkerTuple for () {}
20073impl marker_tuple_sealed::Sealed for (TotalMarker,) {}
20074impl MarkerTuple for (TotalMarker,) {}
20075impl marker_tuple_sealed::Sealed for (TotalMarker, InvertibleMarker) {}
20076impl MarkerTuple for (TotalMarker, InvertibleMarker) {}
20077impl marker_tuple_sealed::Sealed for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {}
20078impl MarkerTuple for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {}
20079impl marker_tuple_sealed::Sealed for (InvertibleMarker,) {}
20080impl MarkerTuple for (InvertibleMarker,) {}
20081impl marker_tuple_sealed::Sealed for (InvertibleMarker, PreservesStructureMarker) {}
20082impl MarkerTuple for (InvertibleMarker, PreservesStructureMarker) {}
20083
20084/// v0.2.2 Phase J: type-level set intersection of two marker tuples.
20085/// Implemented exhaustively for every ordered pair in the closed catalogue.
20086/// Composition combinators (`then`, `and_then`) use this trait to compute
20087/// the output marker tuple of a composed primitive as the intersection of
20088/// its two inputs' tuples. Because the catalogue is closed, the result is
20089/// always another tuple in the catalogue — no open-world hazards.
20090pub trait MarkerIntersection<Other: MarkerTuple>: MarkerTuple {
20091    /// The intersection of `Self` and `Other` in the closed catalogue.
20092    type Output: MarkerTuple;
20093}
20094
20095impl MarkerIntersection<()> for () {
20096    type Output = ();
20097}
20098impl MarkerIntersection<(TotalMarker,)> for () {
20099    type Output = ();
20100}
20101impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for () {
20102    type Output = ();
20103}
20104impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)> for () {
20105    type Output = ();
20106}
20107impl MarkerIntersection<(InvertibleMarker,)> for () {
20108    type Output = ();
20109}
20110impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for () {
20111    type Output = ();
20112}
20113impl MarkerIntersection<()> for (TotalMarker,) {
20114    type Output = ();
20115}
20116impl MarkerIntersection<(TotalMarker,)> for (TotalMarker,) {
20117    type Output = (TotalMarker,);
20118}
20119impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (TotalMarker,) {
20120    type Output = (TotalMarker,);
20121}
20122impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20123    for (TotalMarker,)
20124{
20125    type Output = (TotalMarker,);
20126}
20127impl MarkerIntersection<(InvertibleMarker,)> for (TotalMarker,) {
20128    type Output = ();
20129}
20130impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for (TotalMarker,) {
20131    type Output = ();
20132}
20133impl MarkerIntersection<()> for (TotalMarker, InvertibleMarker) {
20134    type Output = ();
20135}
20136impl MarkerIntersection<(TotalMarker,)> for (TotalMarker, InvertibleMarker) {
20137    type Output = (TotalMarker,);
20138}
20139impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (TotalMarker, InvertibleMarker) {
20140    type Output = (TotalMarker, InvertibleMarker);
20141}
20142impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20143    for (TotalMarker, InvertibleMarker)
20144{
20145    type Output = (TotalMarker, InvertibleMarker);
20146}
20147impl MarkerIntersection<(InvertibleMarker,)> for (TotalMarker, InvertibleMarker) {
20148    type Output = (InvertibleMarker,);
20149}
20150impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20151    for (TotalMarker, InvertibleMarker)
20152{
20153    type Output = (InvertibleMarker,);
20154}
20155impl MarkerIntersection<()> for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {
20156    type Output = ();
20157}
20158impl MarkerIntersection<(TotalMarker,)>
20159    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20160{
20161    type Output = (TotalMarker,);
20162}
20163impl MarkerIntersection<(TotalMarker, InvertibleMarker)>
20164    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20165{
20166    type Output = (TotalMarker, InvertibleMarker);
20167}
20168impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20169    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20170{
20171    type Output = (TotalMarker, InvertibleMarker, PreservesStructureMarker);
20172}
20173impl MarkerIntersection<(InvertibleMarker,)>
20174    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20175{
20176    type Output = (InvertibleMarker,);
20177}
20178impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20179    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20180{
20181    type Output = (InvertibleMarker, PreservesStructureMarker);
20182}
20183impl MarkerIntersection<()> for (InvertibleMarker,) {
20184    type Output = ();
20185}
20186impl MarkerIntersection<(TotalMarker,)> for (InvertibleMarker,) {
20187    type Output = ();
20188}
20189impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (InvertibleMarker,) {
20190    type Output = (InvertibleMarker,);
20191}
20192impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20193    for (InvertibleMarker,)
20194{
20195    type Output = (InvertibleMarker,);
20196}
20197impl MarkerIntersection<(InvertibleMarker,)> for (InvertibleMarker,) {
20198    type Output = (InvertibleMarker,);
20199}
20200impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for (InvertibleMarker,) {
20201    type Output = (InvertibleMarker,);
20202}
20203impl MarkerIntersection<()> for (InvertibleMarker, PreservesStructureMarker) {
20204    type Output = ();
20205}
20206impl MarkerIntersection<(TotalMarker,)> for (InvertibleMarker, PreservesStructureMarker) {
20207    type Output = ();
20208}
20209impl MarkerIntersection<(TotalMarker, InvertibleMarker)>
20210    for (InvertibleMarker, PreservesStructureMarker)
20211{
20212    type Output = (InvertibleMarker,);
20213}
20214impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20215    for (InvertibleMarker, PreservesStructureMarker)
20216{
20217    type Output = (InvertibleMarker, PreservesStructureMarker);
20218}
20219impl MarkerIntersection<(InvertibleMarker,)> for (InvertibleMarker, PreservesStructureMarker) {
20220    type Output = (InvertibleMarker,);
20221}
20222impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20223    for (InvertibleMarker, PreservesStructureMarker)
20224{
20225    type Output = (InvertibleMarker, PreservesStructureMarker);
20226}
20227
20228/// v0.2.2 Phase J: compile-time check that a combinator's marker tuple
20229/// carries every property declared by the `GroundingMapKind` a program
20230/// claims. Implemented exhaustively by codegen for every valid `(tuple,
20231/// map)` pair; absent impls reject the mismatched declaration at the
20232/// `GroundingProgram::from_primitive` call site.
20233pub trait MarkersImpliedBy<Map: GroundingMapKind>: MarkerTuple {}
20234
20235/// v0.2.2 Phase J: bitmask encoding of a combinator's marker set.
20236/// Bit 0 = Total, bit 1 = Invertible, bit 2 = PreservesStructure.
20237#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20238pub struct MarkerBits(u8);
20239
20240impl MarkerBits {
20241    /// The `Total` marker bit.
20242    pub const TOTAL: Self = Self(1);
20243    /// The `Invertible` marker bit.
20244    pub const INVERTIBLE: Self = Self(2);
20245    /// The `PreservesStructure` marker bit.
20246    pub const PRESERVES_STRUCTURE: Self = Self(4);
20247    /// An empty marker set.
20248    pub const NONE: Self = Self(0);
20249
20250    /// Construct a marker bitmask from raw u8.
20251    #[inline]
20252    #[must_use]
20253    pub const fn from_u8(bits: u8) -> Self {
20254        Self(bits)
20255    }
20256
20257    /// Access the raw bitmask.
20258    #[inline]
20259    #[must_use]
20260    pub const fn as_u8(&self) -> u8 {
20261        self.0
20262    }
20263
20264    /// Bitwise OR of two marker bitmasks.
20265    #[inline]
20266    #[must_use]
20267    pub const fn union(self, other: Self) -> Self {
20268        Self(self.0 | other.0)
20269    }
20270
20271    /// Bitwise AND of two marker bitmasks (marker intersection).
20272    #[inline]
20273    #[must_use]
20274    pub const fn intersection(self, other: Self) -> Self {
20275        Self(self.0 & other.0)
20276    }
20277
20278    /// Whether this set contains all marker bits of `other`.
20279    #[inline]
20280    #[must_use]
20281    pub const fn contains(&self, other: Self) -> bool {
20282        (self.0 & other.0) == other.0
20283    }
20284}
20285
20286/// v0.2.2 Phase J: closed catalogue of grounding primitives.
20287/// Exactly 12 operations — read_bytes, interpret_le_integer,
20288/// interpret_be_integer, digest, decode_utf8, decode_json, select_field,
20289/// select_index, const_value, then, map_err, and_then. Adding a new
20290/// primitive is an ontology+grammar+codegen edit, not a Rust patch.
20291#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20292#[non_exhaustive]
20293pub enum GroundingPrimitiveOp {
20294    /// Read a fixed-size byte slice from the input.
20295    ReadBytes,
20296    /// Interpret bytes as a little-endian integer at the target WittLevel.
20297    InterpretLeInteger,
20298    /// Interpret bytes as a big-endian integer.
20299    InterpretBeInteger,
20300    /// Hash bytes via blake3 → 32-byte digest → `Datum<W256>`.
20301    /// # Scope
20302    /// `interpret_leaf_op` returns the first byte of the blake3 32-byte digest.
20303    /// The full digest is produced by `Datum<W256>` composition of 32 `Digest` leaves —
20304    /// the leaf-level output is the single-byte projection.
20305    Digest,
20306    /// Decode UTF-8 bytes; rejects malformed input.
20307    /// # Scope
20308    /// Only single-byte ASCII (`b < 0x80`) is decoded by `interpret_leaf_op`.
20309    /// Multi-byte UTF-8 is not decoded by this leaf; multi-byte sequences traverse the
20310    /// foundation via `GroundedTuple<N>` composition of single-byte leaves.
20311    DecodeUtf8,
20312    /// Decode JSON bytes; rejects malformed input.
20313    /// # Scope
20314    /// Only the leading byte of a JSON number scalar (`-` or ASCII digit) is parsed
20315    /// by `interpret_leaf_op`. Structured JSON values (objects, arrays, strings,
20316    /// multi-byte numbers) are not parsed by this leaf.
20317    DecodeJson,
20318    /// Select a field from a structured value.
20319    SelectField,
20320    /// Select an indexed element.
20321    SelectIndex,
20322    /// Inject a foundation-known constant.
20323    /// # Scope
20324    /// `interpret_leaf_op` returns `GroundedCoord::w8(0)` — the foundation-canonical
20325    /// zero constant. Non-zero constants are materialized through the const-fn frontier
20326    /// (`validate_const` paths) rather than through this leaf.
20327    ConstValue,
20328    /// Compose two combinators sequentially.
20329    Then,
20330    /// Map the error variant of a fallible combinator.
20331    MapErr,
20332    /// Conditional composition (and_then).
20333    AndThen,
20334}
20335
20336/// Max depth of a composed op chain retained inline inside
20337/// `GroundingPrimitive`. Depth-2 composites (`Then(leaf, leaf)`,
20338/// `AndThen(leaf, leaf)`) are the exercised shape today; 8 gives headroom
20339/// for nested composition while keeping `Copy` and `no_std` without alloc.
20340/// Wiki ADR-037: alias of [`crate::HostBounds::OP_CHAIN_DEPTH_MAX`] via
20341/// [`crate::DefaultHostBounds`].
20342pub const MAX_OP_CHAIN_DEPTH: usize =
20343    <crate::DefaultHostBounds as crate::HostBounds>::OP_CHAIN_DEPTH_MAX;
20344
20345/// v0.2.2 Phase J: a single grounding primitive parametric over its output
20346/// type `Out` and its type-level marker tuple `Markers`.
20347/// Constructed only by the 12 enumerated combinator functions below;
20348/// downstream cannot construct one directly. The `Markers` parameter
20349/// defaults to `()` for backwards-compatible call sites, but each
20350/// combinator returns a specific tuple — see `combinators::digest` etc.
20351/// For leaf primitives `chain_len == 0`. For `Then`/`AndThen`/`MapErr`
20352/// composites, `chain[..chain_len as usize]` is the linearized post-order
20353/// sequence of leaf primitive ops the interpreter walks.
20354#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20355pub struct GroundingPrimitive<Out, Markers: MarkerTuple = ()> {
20356    op: GroundingPrimitiveOp,
20357    markers: MarkerBits,
20358    chain: [GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH],
20359    chain_len: u8,
20360    _out: PhantomData<Out>,
20361    _markers: PhantomData<Markers>,
20362    _sealed: (),
20363}
20364
20365impl<Out, Markers: MarkerTuple> GroundingPrimitive<Out, Markers> {
20366    /// Access the primitive op.
20367    #[inline]
20368    #[must_use]
20369    pub const fn op(&self) -> GroundingPrimitiveOp {
20370        self.op
20371    }
20372
20373    /// Access the runtime marker bitmask (mirrors the type-level tuple).
20374    #[inline]
20375    #[must_use]
20376    pub const fn markers(&self) -> MarkerBits {
20377        self.markers
20378    }
20379
20380    /// Access the recorded composition chain. Empty for leaf primitives;
20381    /// the post-order leaf-op sequence for `Then`/`AndThen`/`MapErr`.
20382    #[inline]
20383    #[must_use]
20384    pub fn chain(&self) -> &[GroundingPrimitiveOp] {
20385        &self.chain[..self.chain_len as usize]
20386    }
20387
20388    /// Crate-internal constructor for a leaf primitive (no recorded chain).
20389    /// The type-level `Markers` tuple is selected via turbofish at call
20390    /// sites inside the combinator functions.
20391    #[inline]
20392    #[must_use]
20393    #[allow(dead_code)]
20394    pub(crate) const fn from_parts(op: GroundingPrimitiveOp, markers: MarkerBits) -> Self {
20395        Self {
20396            op,
20397            markers,
20398            chain: [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH],
20399            chain_len: 0,
20400            _out: PhantomData,
20401            _markers: PhantomData,
20402            _sealed: (),
20403        }
20404    }
20405
20406    /// Crate-internal constructor for a composite primitive. Stores
20407    /// `chain[..chain_len]` inline; accessors expose only the prefix.
20408    #[inline]
20409    #[must_use]
20410    #[allow(dead_code)]
20411    pub(crate) const fn from_parts_with_chain(
20412        op: GroundingPrimitiveOp,
20413        markers: MarkerBits,
20414        chain: [GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH],
20415        chain_len: u8,
20416    ) -> Self {
20417        Self {
20418            op,
20419            markers,
20420            chain,
20421            chain_len,
20422            _out: PhantomData,
20423            _markers: PhantomData,
20424            _sealed: (),
20425        }
20426    }
20427}
20428
20429/// v0.2.2 Phase J: closed 12-combinator surface for building grounding
20430/// programs. See `GroundingProgram` for composition. Each leaf combinator
20431/// returns a `GroundingPrimitive<Out, M>` carrying a specific marker tuple;
20432/// the type parameter is what `GroundingProgram::from_primitive`'s
20433/// `MarkersImpliedBy<Map>` bound checks at compile time.
20434pub mod combinators {
20435    use super::{
20436        GroundingPrimitive, GroundingPrimitiveOp, InvertibleMarker, MarkerBits, MarkerIntersection,
20437        MarkerTuple, PreservesStructureMarker, TotalMarker, MAX_OP_CHAIN_DEPTH,
20438    };
20439
20440    /// Build the post-order leaf-op chain for a sequential composite:
20441    /// `first.chain ++ [first.op] ++ second.chain ++ [second.op]`.
20442    /// Saturated to `MAX_OP_CHAIN_DEPTH`.
20443    fn compose_chain<A, B, MA: MarkerTuple, MB: MarkerTuple>(
20444        first: &GroundingPrimitive<A, MA>,
20445        second: &GroundingPrimitive<B, MB>,
20446    ) -> ([GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH], u8) {
20447        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20448        let mut len: usize = 0;
20449        for &op in first.chain() {
20450            if len >= MAX_OP_CHAIN_DEPTH {
20451                return (chain, len as u8);
20452            }
20453            chain[len] = op;
20454            len += 1;
20455        }
20456        if len < MAX_OP_CHAIN_DEPTH {
20457            chain[len] = first.op();
20458            len += 1;
20459        }
20460        for &op in second.chain() {
20461            if len >= MAX_OP_CHAIN_DEPTH {
20462                return (chain, len as u8);
20463            }
20464            chain[len] = op;
20465            len += 1;
20466        }
20467        if len < MAX_OP_CHAIN_DEPTH {
20468            chain[len] = second.op();
20469            len += 1;
20470        }
20471        (chain, len as u8)
20472    }
20473
20474    /// Build the chain for `map_err(first)`: `first.chain ++ [first.op]`.
20475    fn map_err_chain<A, M: MarkerTuple>(
20476        first: &GroundingPrimitive<A, M>,
20477    ) -> ([GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH], u8) {
20478        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20479        let mut len: usize = 0;
20480        for &op in first.chain() {
20481            if len >= MAX_OP_CHAIN_DEPTH {
20482                return (chain, len as u8);
20483            }
20484            chain[len] = op;
20485            len += 1;
20486        }
20487        if len < MAX_OP_CHAIN_DEPTH {
20488            chain[len] = first.op();
20489            len += 1;
20490        }
20491        (chain, len as u8)
20492    }
20493
20494    /// Read a fixed-size byte slice from the input. `(Total, Invertible)`.
20495    #[inline]
20496    #[must_use]
20497    pub const fn read_bytes<Out>() -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker)> {
20498        GroundingPrimitive::from_parts(
20499            GroundingPrimitiveOp::ReadBytes,
20500            MarkerBits::TOTAL.union(MarkerBits::INVERTIBLE),
20501        )
20502    }
20503
20504    /// Interpret bytes as a little-endian integer at the target WittLevel.
20505    #[inline]
20506    #[must_use]
20507    pub const fn interpret_le_integer<Out>(
20508    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20509        GroundingPrimitive::from_parts(
20510            GroundingPrimitiveOp::InterpretLeInteger,
20511            MarkerBits::TOTAL
20512                .union(MarkerBits::INVERTIBLE)
20513                .union(MarkerBits::PRESERVES_STRUCTURE),
20514        )
20515    }
20516
20517    /// Interpret bytes as a big-endian integer.
20518    #[inline]
20519    #[must_use]
20520    pub const fn interpret_be_integer<Out>(
20521    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20522        GroundingPrimitive::from_parts(
20523            GroundingPrimitiveOp::InterpretBeInteger,
20524            MarkerBits::TOTAL
20525                .union(MarkerBits::INVERTIBLE)
20526                .union(MarkerBits::PRESERVES_STRUCTURE),
20527        )
20528    }
20529
20530    /// Hash bytes via blake3 → 32-byte digest → `Datum<W256>`. `(Total,)` only.
20531    #[inline]
20532    #[must_use]
20533    pub const fn digest<Out>() -> GroundingPrimitive<Out, (TotalMarker,)> {
20534        GroundingPrimitive::from_parts(GroundingPrimitiveOp::Digest, MarkerBits::TOTAL)
20535    }
20536
20537    /// Decode UTF-8 bytes. `(Invertible, PreservesStructure)` — not Total.
20538    #[inline]
20539    #[must_use]
20540    pub const fn decode_utf8<Out>(
20541    ) -> GroundingPrimitive<Out, (InvertibleMarker, PreservesStructureMarker)> {
20542        GroundingPrimitive::from_parts(
20543            GroundingPrimitiveOp::DecodeUtf8,
20544            MarkerBits::INVERTIBLE.union(MarkerBits::PRESERVES_STRUCTURE),
20545        )
20546    }
20547
20548    /// Decode JSON bytes. `(Invertible, PreservesStructure)` — not Total.
20549    #[inline]
20550    #[must_use]
20551    pub const fn decode_json<Out>(
20552    ) -> GroundingPrimitive<Out, (InvertibleMarker, PreservesStructureMarker)> {
20553        GroundingPrimitive::from_parts(
20554            GroundingPrimitiveOp::DecodeJson,
20555            MarkerBits::INVERTIBLE.union(MarkerBits::PRESERVES_STRUCTURE),
20556        )
20557    }
20558
20559    /// Select a field from a structured value. `(Invertible,)` — not Total.
20560    #[inline]
20561    #[must_use]
20562    pub const fn select_field<Out>() -> GroundingPrimitive<Out, (InvertibleMarker,)> {
20563        GroundingPrimitive::from_parts(GroundingPrimitiveOp::SelectField, MarkerBits::INVERTIBLE)
20564    }
20565
20566    /// Select an indexed element. `(Invertible,)` — not Total.
20567    #[inline]
20568    #[must_use]
20569    pub const fn select_index<Out>() -> GroundingPrimitive<Out, (InvertibleMarker,)> {
20570        GroundingPrimitive::from_parts(GroundingPrimitiveOp::SelectIndex, MarkerBits::INVERTIBLE)
20571    }
20572
20573    /// Inject a foundation-known constant. `(Total, Invertible, PreservesStructure)`.
20574    #[inline]
20575    #[must_use]
20576    pub const fn const_value<Out>(
20577    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20578        GroundingPrimitive::from_parts(
20579            GroundingPrimitiveOp::ConstValue,
20580            MarkerBits::TOTAL
20581                .union(MarkerBits::INVERTIBLE)
20582                .union(MarkerBits::PRESERVES_STRUCTURE),
20583        )
20584    }
20585
20586    /// Compose two combinators sequentially. Markers are intersected at
20587    /// the type level via the `MarkerIntersection` trait. The recorded
20588    /// leaf-op chain lets the foundation's interpreter walk the operands
20589    /// at runtime.
20590    #[inline]
20591    #[must_use]
20592    pub fn then<A, B, MA, MB>(
20593        first: GroundingPrimitive<A, MA>,
20594        second: GroundingPrimitive<B, MB>,
20595    ) -> GroundingPrimitive<B, <MA as MarkerIntersection<MB>>::Output>
20596    where
20597        MA: MarkerTuple + MarkerIntersection<MB>,
20598        MB: MarkerTuple,
20599    {
20600        let (chain, chain_len) = compose_chain(&first, &second);
20601        GroundingPrimitive::from_parts_with_chain(
20602            GroundingPrimitiveOp::Then,
20603            first.markers().intersection(second.markers()),
20604            chain,
20605            chain_len,
20606        )
20607    }
20608
20609    /// Map an error variant of a fallible combinator. Marker tuple
20610    /// is preserved. The operand's op is recorded so the interpreter's
20611    /// `MapErr` arm can forward the success value.
20612    #[inline]
20613    #[must_use]
20614    pub fn map_err<A, M: MarkerTuple>(first: GroundingPrimitive<A, M>) -> GroundingPrimitive<A, M> {
20615        let (chain, chain_len) = map_err_chain(&first);
20616        GroundingPrimitive::from_parts_with_chain(
20617            GroundingPrimitiveOp::MapErr,
20618            first.markers(),
20619            chain,
20620            chain_len,
20621        )
20622    }
20623
20624    /// Conditional composition (and_then). Markers are intersected; the
20625    /// recorded chain mirrors `then` so the interpreter walks operands.
20626    #[inline]
20627    #[must_use]
20628    pub fn and_then<A, B, MA, MB>(
20629        first: GroundingPrimitive<A, MA>,
20630        second: GroundingPrimitive<B, MB>,
20631    ) -> GroundingPrimitive<B, <MA as MarkerIntersection<MB>>::Output>
20632    where
20633        MA: MarkerTuple + MarkerIntersection<MB>,
20634        MB: MarkerTuple,
20635    {
20636        let (chain, chain_len) = compose_chain(&first, &second);
20637        GroundingPrimitive::from_parts_with_chain(
20638            GroundingPrimitiveOp::AndThen,
20639            first.markers().intersection(second.markers()),
20640            chain,
20641            chain_len,
20642        )
20643    }
20644}
20645
20646/// v0.2.2 Phase J: sealed grounding program.
20647/// A composition of combinators with a statically tracked marker tuple.
20648/// Constructed only via `GroundingProgram::from_primitive`, which requires
20649/// via the `MarkersImpliedBy<Map>` trait bound that the primitive's marker
20650/// tuple carries every property declared by `Map: GroundingMapKind`.
20651#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20652pub struct GroundingProgram<Out, Map: GroundingMapKind> {
20653    primitive: GroundingPrimitive<Out>,
20654    _map: PhantomData<Map>,
20655    _sealed: (),
20656}
20657
20658impl<Out, Map: GroundingMapKind> GroundingProgram<Out, Map> {
20659    /// Foundation-verified constructor. Accepts a primitive whose marker
20660    /// tuple satisfies `MarkersImpliedBy<Map>`. Programs built from
20661    /// combinators whose marker tuple lacks a property `Map` requires are
20662    /// rejected at compile time — this is Phase J's marquee correctness
20663    /// claim: misdeclarations fail to compile.
20664    /// # Example: valid program
20665    /// ```
20666    /// use uor_foundation::enforcement::{GroundingProgram, IntegerGroundingMap, combinators};
20667    /// let prog: GroundingProgram<u64, IntegerGroundingMap> =
20668    ///     GroundingProgram::from_primitive(combinators::interpret_le_integer::<u64>());
20669    /// let _ = prog;
20670    /// ```
20671    /// # Example: rejected misdeclaration
20672    /// ```compile_fail
20673    /// use uor_foundation::enforcement::{GroundingProgram, IntegerGroundingMap, combinators};
20674    /// // digest returns (TotalMarker,) which does NOT satisfy
20675    /// // MarkersImpliedBy<IntegerGroundingMap> — the line below fails to compile.
20676    /// let prog: GroundingProgram<[u8; 32], IntegerGroundingMap> =
20677    ///     GroundingProgram::from_primitive(combinators::digest::<[u8; 32]>());
20678    /// let _ = prog;
20679    /// ```
20680    #[inline]
20681    #[must_use]
20682    pub fn from_primitive<Markers>(primitive: GroundingPrimitive<Out, Markers>) -> Self
20683    where
20684        Markers: MarkerTuple + MarkersImpliedBy<Map>,
20685    {
20686        // Preserve the composition chain so the interpreter can walk
20687        // operands of Then/AndThen/MapErr composites.
20688        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20689        let src = primitive.chain();
20690        let mut i = 0;
20691        while i < src.len() && i < MAX_OP_CHAIN_DEPTH {
20692            chain[i] = src[i];
20693            i += 1;
20694        }
20695        let erased = GroundingPrimitive::<Out, ()>::from_parts_with_chain(
20696            primitive.op(),
20697            primitive.markers(),
20698            chain,
20699            i as u8,
20700        );
20701        Self {
20702            primitive: erased,
20703            _map: PhantomData,
20704            _sealed: (),
20705        }
20706    }
20707
20708    /// Access the underlying primitive (erased marker tuple).
20709    #[inline]
20710    #[must_use]
20711    pub const fn primitive(&self) -> &GroundingPrimitive<Out> {
20712        &self.primitive
20713    }
20714}
20715
20716/// Phase K (target §4.3 / §9 criterion 1): foundation-supplied interpreter for
20717/// grounding programs whose `Out` is `GroundedCoord`. Handles every op in
20718/// the closed 12-combinator catalogue: leaf ops (`ReadBytes`,
20719/// `InterpretLeInteger`, `InterpretBeInteger`, `Digest`, `DecodeUtf8`,
20720/// `DecodeJson`, `ConstValue`, `SelectField`, `SelectIndex`) call
20721/// `interpret_leaf_op` directly; composition ops (`Then`, `AndThen`,
20722/// `MapErr`) walk the chain recorded in the primitive and thread
20723/// `external` through each leaf step. The interpreter surfaces
20724/// `GroundedCoord::w8(byte)` values; richer outputs compose through
20725/// combinator chains producing `GroundedTuple<N>`. No `ground()`
20726/// override exists after W4 closure — downstream provides only
20727/// `program()`, and `GroundingExt::ground` is foundation-authored.
20728impl<Map: GroundingMapKind> GroundingProgram<GroundedCoord, Map> {
20729    /// Run this program on external bytes, producing a `GroundedCoord`.
20730    /// Returns `None` if the input is malformed/undersized for the
20731    /// program's op chain.
20732    #[inline]
20733    #[must_use]
20734    pub fn run(&self, external: &[u8]) -> Option<GroundedCoord> {
20735        match self.primitive.op() {
20736            GroundingPrimitiveOp::Then | GroundingPrimitiveOp::AndThen => {
20737                let chain = self.primitive.chain();
20738                if chain.is_empty() {
20739                    return None;
20740                }
20741                let mut last: Option<GroundedCoord> = None;
20742                for &op in chain {
20743                    match interpret_leaf_op(op, external) {
20744                        Some(c) => last = Some(c),
20745                        None => return None,
20746                    }
20747                }
20748                last
20749            }
20750            GroundingPrimitiveOp::MapErr => self
20751                .primitive
20752                .chain()
20753                .first()
20754                .and_then(|&op| interpret_leaf_op(op, external)),
20755            leaf => interpret_leaf_op(leaf, external),
20756        }
20757    }
20758}
20759
20760/// W4 closure (target §4.3 + §9 criterion 1): foundation-supplied
20761/// interpreter for programs producing `GroundedTuple<N>`. Splits
20762/// `external` into `N` equal windows and runs the same dispatch
20763/// that `GroundingProgram<GroundedCoord, Map>::run` performs on
20764/// each window. Returns `None` if `N == 0`, the input is empty,
20765/// the input length isn't divisible by `N`, or any window fails.
20766impl<const N: usize, Map: GroundingMapKind> GroundingProgram<GroundedTuple<N>, Map> {
20767    /// Run this program on external bytes, producing a `GroundedTuple<N>`.
20768    #[inline]
20769    #[must_use]
20770    pub fn run(&self, external: &[u8]) -> Option<GroundedTuple<N>> {
20771        if N == 0 || external.is_empty() || external.len() % N != 0 {
20772            return None;
20773        }
20774        let window = external.len() / N;
20775        let mut coords: [GroundedCoord; N] = [const { GroundedCoord::w8(0) }; N];
20776        let mut i = 0usize;
20777        while i < N {
20778            let start = i * window;
20779            let end = start + window;
20780            let sub = &external[start..end];
20781            // Walk this window through the same leaf/composition
20782            // dispatch as the GroundedCoord interpreter above. A
20783            // helper that runs the chain is reused via the same
20784            // primitive accessors.
20785            let outcome = match self.primitive.op() {
20786                GroundingPrimitiveOp::Then | GroundingPrimitiveOp::AndThen => {
20787                    let chain = self.primitive.chain();
20788                    if chain.is_empty() {
20789                        return None;
20790                    }
20791                    let mut last: Option<GroundedCoord> = None;
20792                    for &op in chain {
20793                        match interpret_leaf_op(op, sub) {
20794                            Some(c) => last = Some(c),
20795                            None => return None,
20796                        }
20797                    }
20798                    last
20799                }
20800                GroundingPrimitiveOp::MapErr => self
20801                    .primitive
20802                    .chain()
20803                    .first()
20804                    .and_then(|&op| interpret_leaf_op(op, sub)),
20805                leaf => interpret_leaf_op(leaf, sub),
20806            };
20807            match outcome {
20808                Some(c) => {
20809                    coords[i] = c;
20810                }
20811                None => {
20812                    return None;
20813                }
20814            }
20815            i += 1;
20816        }
20817        Some(GroundedTuple::new(coords))
20818    }
20819}
20820
20821/// Foundation-canonical leaf-op interpreter. Called directly by
20822/// `GroundingProgram::run` for leaf primitives and step-by-step for
20823/// composition ops.
20824#[inline]
20825fn interpret_leaf_op(op: GroundingPrimitiveOp, external: &[u8]) -> Option<GroundedCoord> {
20826    match op {
20827        GroundingPrimitiveOp::ReadBytes | GroundingPrimitiveOp::InterpretLeInteger => {
20828            external.first().map(|&b| GroundedCoord::w8(b))
20829        }
20830        GroundingPrimitiveOp::InterpretBeInteger => external.last().map(|&b| GroundedCoord::w8(b)),
20831        GroundingPrimitiveOp::Digest => {
20832            // Foundation-canonical digest: first byte as `GroundedCoord` —
20833            // the full 32-byte digest requires a Datum<W256> sink that does
20834            // not fit in `GroundedCoord`. Downstream that needs the full
20835            // digest composes a richer program via Then/AndThen chains over
20836            // the 12 closed combinators — no `ground()` override exists after
20837            // W4 closure.
20838            external.first().map(|&b| GroundedCoord::w8(b))
20839        }
20840        GroundingPrimitiveOp::DecodeUtf8 => {
20841            // ASCII single-byte path — the canonical v0.2.2 semantics for
20842            // `Grounding::ground` over `GroundedCoord` outputs. Multi-byte
20843            // UTF-8 sequences are out of scope for w8-sized leaves; a richer
20844            // structured output composes via combinator chains into
20845            // `GroundedTuple<N>`.
20846            match external.first() {
20847                Some(&b) if b < 0x80 => Some(GroundedCoord::w8(b)),
20848                _ => None,
20849            }
20850        }
20851        GroundingPrimitiveOp::DecodeJson => {
20852            // Accept JSON number scalars (leading `-` or ASCII digit).
20853            match external.first() {
20854                Some(&b) if b == b'-' || b.is_ascii_digit() => Some(GroundedCoord::w8(b)),
20855                _ => None,
20856            }
20857        }
20858        GroundingPrimitiveOp::ConstValue => Some(GroundedCoord::w8(0)),
20859        GroundingPrimitiveOp::SelectField | GroundingPrimitiveOp::SelectIndex => {
20860            // Selector ops are composition-only in normal use; if invoked
20861            // directly, forward the first byte as a GroundedCoord.
20862            external.first().map(|&b| GroundedCoord::w8(b))
20863        }
20864        GroundingPrimitiveOp::Then
20865        | GroundingPrimitiveOp::AndThen
20866        | GroundingPrimitiveOp::MapErr => {
20867            // Composite ops are dispatched by `run()` through the chain;
20868            // they never reach the leaf interpreter.
20869            None
20870        }
20871    }
20872}
20873
20874/// v0.2.2 Phase J: MarkersImpliedBy impls for the closed catalogue of valid
20875/// (marker tuple, GroundingMapKind) pairs. These are the compile-time
20876/// witnesses the foundation accepts; every absent pair is a rejection.
20877impl MarkersImpliedBy<DigestGroundingMap> for (TotalMarker,) {}
20878impl MarkersImpliedBy<BinaryGroundingMap> for (TotalMarker, InvertibleMarker) {}
20879impl MarkersImpliedBy<DigestGroundingMap> for (TotalMarker, InvertibleMarker) {}
20880impl MarkersImpliedBy<BinaryGroundingMap>
20881    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20882{
20883}
20884impl MarkersImpliedBy<DigestGroundingMap>
20885    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20886{
20887}
20888impl MarkersImpliedBy<IntegerGroundingMap>
20889    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20890{
20891}
20892impl MarkersImpliedBy<JsonGroundingMap>
20893    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20894{
20895}
20896impl MarkersImpliedBy<Utf8GroundingMap>
20897    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20898{
20899}
20900impl MarkersImpliedBy<JsonGroundingMap> for (InvertibleMarker, PreservesStructureMarker) {}
20901impl MarkersImpliedBy<Utf8GroundingMap> for (InvertibleMarker, PreservesStructureMarker) {}
20902
20903/// v0.2.2 T2.5: foundation-private test-only back-door module.
20904/// Exposes crate-internal constructors for `Trace`, `TraceEvent`, and
20905/// `MulContext` to the `uor-foundation-test-helpers` workspace member, which
20906/// re-exports them under stable test-only names. Not part of the public API.
20907#[doc(hidden)]
20908pub mod __test_helpers {
20909    use super::{ContentAddress, ContentFingerprint, MulContext, Trace, TraceEvent, Validated};
20910
20911    /// Test-only ctor: build a Trace from a slice of events with a
20912    /// `ContentFingerprint::zero()` placeholder. Tests that need a non-zero
20913    /// fingerprint use `trace_with_fingerprint` instead. Parametric in
20914    /// `TR_MAX` per the wiki's ADR-018; callers pick the trace event-count
20915    /// ceiling from their selected `HostBounds`.
20916    #[must_use]
20917    pub fn trace_from_events<const TR_MAX: usize>(events: &[TraceEvent]) -> Trace<TR_MAX> {
20918        trace_with_fingerprint(events, 0, ContentFingerprint::zero())
20919    }
20920
20921    /// Test-only ctor that takes an explicit `witt_level_bits` and
20922    /// `ContentFingerprint`. Used by round-trip tests that need to verify
20923    /// the verify-trace fingerprint passthrough invariant.
20924    #[must_use]
20925    pub fn trace_with_fingerprint<const TR_MAX: usize>(
20926        events: &[TraceEvent],
20927        witt_level_bits: u16,
20928        content_fingerprint: ContentFingerprint,
20929    ) -> Trace<TR_MAX> {
20930        let mut arr = [None; TR_MAX];
20931        let n = events.len().min(TR_MAX);
20932        let mut i = 0;
20933        while i < n {
20934            arr[i] = Some(events[i]);
20935            i += 1;
20936        }
20937        // The test-helpers back-door uses the foundation-private
20938        // `from_replay_events_const` to build malformed fixtures for error-path
20939        // tests. Downstream code uses `Trace::try_from_events` (validating).
20940        Trace::from_replay_events_const(arr, n as u16, witt_level_bits, content_fingerprint)
20941    }
20942
20943    /// Test-only ctor: build a TraceEvent.
20944    #[must_use]
20945    pub fn trace_event(step_index: u32, target: u128) -> TraceEvent {
20946        TraceEvent::new(
20947            step_index,
20948            crate::PrimitiveOp::Add,
20949            ContentAddress::from_u128(target),
20950        )
20951    }
20952
20953    /// Test-only ctor: build a MulContext.
20954    #[must_use]
20955    pub fn mul_context(stack_budget_bytes: u64, const_eval: bool, limb_count: usize) -> MulContext {
20956        MulContext::new(stack_budget_bytes, const_eval, limb_count)
20957    }
20958
20959    /// Test-only ctor: wrap any T in a Runtime-phase Validated. Used by
20960    /// integration tests to construct `Validated<Decl, P>` values that
20961    /// the public API otherwise can't construct directly.
20962    #[must_use]
20963    pub fn validated_runtime<T>(inner: T) -> Validated<T> {
20964        Validated::new(inner)
20965    }
20966}
20967
20968/// Tolerance for entropy equality checks in the Product/Coproduct
20969/// Completion Amendment mint primitives. Returns an absolute-error bound
20970/// scaled to the magnitude of `expected`, so PT_4 / ST_2 / CPT_5
20971/// verifications are robust to floating-point rounding accumulated through
20972/// Künneth products and componentwise sums. The default-host (f64) backing
20973/// is hidden behind the `DefaultDecimal` alias so the function signature
20974/// reads as host-typed; downstream that swaps `H::Decimal` reaches the
20975/// same surface via the alias rebind.
20976type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
20977
20978#[inline]
20979const fn pc_entropy_tolerance(expected: DefaultDecimal) -> DefaultDecimal {
20980    let magnitude = if expected < 0.0 { -expected } else { expected };
20981    let scale = if magnitude > 1.0 { magnitude } else { 1.0 };
20982    1024.0 * <DefaultDecimal>::EPSILON * scale
20983}
20984
20985/// Validate an entropy value before participating in additivity checks.
20986/// Rejects NaN, ±∞, and negative values — the foundation's
20987/// `primitive_descent_metrics` produces `residual × LN_2` with
20988/// `residual: u32`, so valid entropies are non-negative finite Decimals.
20989#[inline]
20990fn pc_entropy_input_is_valid(value: DefaultDecimal) -> bool {
20991    value.is_finite() && value >= 0.0
20992}
20993
20994/// Check that `actual` matches `expected` within tolerance and that both
20995/// inputs are valid entropy values. Returns `false` if either input is
20996/// non-finite, negative, or differs from `expected` by more than
20997/// `pc_entropy_tolerance(expected)`.
20998#[inline]
20999fn pc_entropy_additivity_holds(actual: DefaultDecimal, expected: DefaultDecimal) -> bool {
21000    if !pc_entropy_input_is_valid(actual) || !pc_entropy_input_is_valid(expected) {
21001        return false;
21002    }
21003    let diff = actual - expected;
21004    let diff_abs = if diff < 0.0 { -diff } else { diff };
21005    diff_abs <= pc_entropy_tolerance(expected)
21006}
21007
21008/// Evidence bundle for `PartitionProductWitness`. Carries the PT_1 / PT_3 /
21009/// PT_4 input values used at mint time. Derives `PartialEq` only because
21010/// `f64` entropy fields exclude `Eq` / `Hash`; this is the auditing surface,
21011/// not a hash-map key.
21012#[derive(Debug, Clone, Copy, PartialEq)]
21013pub struct PartitionProductEvidence {
21014    /// Left operand `siteBudget` (data sites only, PT_1 input).
21015    pub left_site_budget: u16,
21016    /// Right operand `siteBudget`.
21017    pub right_site_budget: u16,
21018    /// Left operand `SITE_COUNT` (layout width, layout-invariant input).
21019    pub left_total_site_count: u16,
21020    /// Right operand `SITE_COUNT`.
21021    pub right_total_site_count: u16,
21022    /// Left operand Euler characteristic (PT_3 input).
21023    pub left_euler: i32,
21024    /// Right operand Euler characteristic.
21025    pub right_euler: i32,
21026    /// Left operand entropy in nats (PT_4 input).
21027    pub left_entropy_nats_bits: u64,
21028    /// Right operand entropy in nats.
21029    pub right_entropy_nats_bits: u64,
21030    /// Fingerprint of the source witness the evidence belongs to.
21031    pub source_witness_fingerprint: ContentFingerprint,
21032}
21033
21034/// Evidence bundle for `PartitionCoproductWitness`. Carries the
21035/// ST_1 / ST_2 / ST_9 / ST_10 input values used at mint time.
21036#[derive(Debug, Clone, Copy, PartialEq)]
21037pub struct PartitionCoproductEvidence {
21038    pub left_site_budget: u16,
21039    pub right_site_budget: u16,
21040    pub left_total_site_count: u16,
21041    pub right_total_site_count: u16,
21042    pub left_euler: i32,
21043    pub right_euler: i32,
21044    pub left_entropy_nats_bits: u64,
21045    pub right_entropy_nats_bits: u64,
21046    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21047    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21048    pub source_witness_fingerprint: ContentFingerprint,
21049}
21050
21051/// Evidence bundle for `CartesianProductWitness`. Carries the
21052/// CPT_1 / CPT_3 / CPT_4 / CPT_5 input values used at mint time, plus
21053/// `combined_entropy_nats` — the CartesianProductWitness itself does not
21054/// store entropy (see §1a), so the evidence sidecar preserves the
21055/// verification target value for re-audit.
21056#[derive(Debug, Clone, Copy, PartialEq)]
21057pub struct CartesianProductEvidence {
21058    pub left_site_budget: u16,
21059    pub right_site_budget: u16,
21060    pub left_total_site_count: u16,
21061    pub right_total_site_count: u16,
21062    pub left_euler: i32,
21063    pub right_euler: i32,
21064    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21065    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21066    pub left_entropy_nats_bits: u64,
21067    pub right_entropy_nats_bits: u64,
21068    pub combined_entropy_nats_bits: u64,
21069    pub source_witness_fingerprint: ContentFingerprint,
21070}
21071
21072/// Inputs to `PartitionProductWitness::mint_verified`. Mirrors the
21073/// underlying primitive's parameter list; each field is supplied by the
21074/// caller (typically a `product_shape!` macro expansion or a manual
21075/// construction following the amendment's Gap 2 pattern). Derives
21076/// `PartialEq` only because of the `f64` entropy fields.
21077#[derive(Debug, Clone, Copy, PartialEq)]
21078pub struct PartitionProductMintInputs {
21079    pub witt_bits: u16,
21080    pub left_fingerprint: ContentFingerprint,
21081    pub right_fingerprint: ContentFingerprint,
21082    pub left_site_budget: u16,
21083    pub right_site_budget: u16,
21084    pub left_total_site_count: u16,
21085    pub right_total_site_count: u16,
21086    pub left_euler: i32,
21087    pub right_euler: i32,
21088    pub left_entropy_nats_bits: u64,
21089    pub right_entropy_nats_bits: u64,
21090    pub combined_site_budget: u16,
21091    pub combined_site_count: u16,
21092    pub combined_euler: i32,
21093    pub combined_entropy_nats_bits: u64,
21094    pub combined_fingerprint: ContentFingerprint,
21095}
21096
21097/// Inputs to `PartitionCoproductWitness::mint_verified`. Adds three
21098/// structural fields beyond the other two MintInputs: the combined
21099/// constraint array, the boundary index between L and R regions, and the
21100/// tag site layout index. These feed `validate_coproduct_structure` at
21101/// mint time so ST_6 / ST_7 / ST_8 are verified numerically rather than
21102/// trusted from the caller.
21103/// Derives `Debug`, `Clone`, `Copy` only — no `PartialEq`. `ConstraintRef`
21104/// does not implement `PartialEq`, so deriving equality on a struct with a
21105/// `&[ConstraintRef]` field would not compile. MintInputs is not used as
21106/// an equality target in practice; downstream consumers compare the minted
21107/// witness (which derives `Eq` + `Hash`) instead.
21108#[derive(Debug, Clone, Copy)]
21109pub struct PartitionCoproductMintInputs {
21110    pub witt_bits: u16,
21111    pub left_fingerprint: ContentFingerprint,
21112    pub right_fingerprint: ContentFingerprint,
21113    pub left_site_budget: u16,
21114    pub right_site_budget: u16,
21115    pub left_total_site_count: u16,
21116    pub right_total_site_count: u16,
21117    pub left_euler: i32,
21118    pub right_euler: i32,
21119    pub left_entropy_nats_bits: u64,
21120    pub right_entropy_nats_bits: u64,
21121    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21122    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21123    pub combined_site_budget: u16,
21124    pub combined_site_count: u16,
21125    pub combined_euler: i32,
21126    pub combined_entropy_nats_bits: u64,
21127    pub combined_betti: [u32; MAX_BETTI_DIMENSION],
21128    pub combined_fingerprint: ContentFingerprint,
21129    pub combined_constraints: &'static [crate::pipeline::ConstraintRef],
21130    pub left_constraint_count: usize,
21131    pub tag_site: u16,
21132}
21133
21134/// Inputs to `CartesianProductWitness::mint_verified`. Matches the
21135/// CartesianProduct mint primitive's parameter list.
21136#[derive(Debug, Clone, Copy, PartialEq)]
21137pub struct CartesianProductMintInputs {
21138    pub witt_bits: u16,
21139    pub left_fingerprint: ContentFingerprint,
21140    pub right_fingerprint: ContentFingerprint,
21141    pub left_site_budget: u16,
21142    pub right_site_budget: u16,
21143    pub left_total_site_count: u16,
21144    pub right_total_site_count: u16,
21145    pub left_euler: i32,
21146    pub right_euler: i32,
21147    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21148    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21149    pub left_entropy_nats_bits: u64,
21150    pub right_entropy_nats_bits: u64,
21151    pub combined_site_budget: u16,
21152    pub combined_site_count: u16,
21153    pub combined_euler: i32,
21154    pub combined_betti: [u32; MAX_BETTI_DIMENSION],
21155    pub combined_entropy_nats_bits: u64,
21156    pub combined_fingerprint: ContentFingerprint,
21157}
21158
21159/// Sealed PartitionProduct witness — content-addressed assertion that a
21160/// partition decomposes as `PartitionProduct(left, right)` per PT_2a.
21161/// Minting is gated on PT_1, PT_3, PT_4, and the foundation
21162/// `ProductLayoutWidth` invariant being verified against component
21163/// shapes. Existence of an instance is the attestation — there is no
21164/// partial or unverified form.
21165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21166pub struct PartitionProductWitness {
21167    witt_bits: u16,
21168    content_fingerprint: ContentFingerprint,
21169    left_fingerprint: ContentFingerprint,
21170    right_fingerprint: ContentFingerprint,
21171    combined_site_budget: u16,
21172    combined_site_count: u16,
21173}
21174
21175impl PartitionProductWitness {
21176    /// Witt level at which the witness was minted.
21177    #[inline]
21178    #[must_use]
21179    pub const fn witt_bits(&self) -> u16 {
21180        self.witt_bits
21181    }
21182    /// Content fingerprint of the combined (A × B) shape.
21183    #[inline]
21184    #[must_use]
21185    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21186        self.content_fingerprint
21187    }
21188    /// Content fingerprint of the left factor A.
21189    #[inline]
21190    #[must_use]
21191    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21192        self.left_fingerprint
21193    }
21194    /// Content fingerprint of the right factor B.
21195    #[inline]
21196    #[must_use]
21197    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21198        self.right_fingerprint
21199    }
21200    /// `siteBudget(A × B)` per PT_1.
21201    #[inline]
21202    #[must_use]
21203    pub const fn combined_site_budget(&self) -> u16 {
21204        self.combined_site_budget
21205    }
21206    /// `SITE_COUNT(A × B)` — the foundation layout width.
21207    #[inline]
21208    #[must_use]
21209    pub const fn combined_site_count(&self) -> u16 {
21210        self.combined_site_count
21211    }
21212    /// Crate-internal mint entry. Only the verified mint primitive may call this.
21213    #[inline]
21214    #[must_use]
21215    #[allow(clippy::too_many_arguments)]
21216    pub(crate) const fn with_level_fingerprints_and_sites(
21217        witt_bits: u16,
21218        content_fingerprint: ContentFingerprint,
21219        left_fingerprint: ContentFingerprint,
21220        right_fingerprint: ContentFingerprint,
21221        combined_site_budget: u16,
21222        combined_site_count: u16,
21223    ) -> Self {
21224        Self {
21225            witt_bits,
21226            content_fingerprint,
21227            left_fingerprint,
21228            right_fingerprint,
21229            combined_site_budget,
21230            combined_site_count,
21231        }
21232    }
21233}
21234
21235/// Sealed PartitionCoproduct witness — content-addressed assertion that a
21236/// partition decomposes as `PartitionCoproduct(left, right)` per PT_2b.
21237/// Minting verifies ST_1, ST_2, ST_6, ST_7, ST_8, ST_9, ST_10, the
21238/// foundation `CoproductLayoutWidth` invariant, and — for ST_6/ST_7/ST_8 —
21239/// walks the supplied constraint array through `validate_coproduct_structure`.
21240#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21241pub struct PartitionCoproductWitness {
21242    witt_bits: u16,
21243    content_fingerprint: ContentFingerprint,
21244    left_fingerprint: ContentFingerprint,
21245    right_fingerprint: ContentFingerprint,
21246    combined_site_budget: u16,
21247    combined_site_count: u16,
21248    tag_site_index: u16,
21249}
21250
21251impl PartitionCoproductWitness {
21252    #[inline]
21253    #[must_use]
21254    pub const fn witt_bits(&self) -> u16 {
21255        self.witt_bits
21256    }
21257    #[inline]
21258    #[must_use]
21259    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21260        self.content_fingerprint
21261    }
21262    #[inline]
21263    #[must_use]
21264    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21265        self.left_fingerprint
21266    }
21267    #[inline]
21268    #[must_use]
21269    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21270        self.right_fingerprint
21271    }
21272    /// `siteBudget(A + B)` per ST_1 = max(siteBudget(A), siteBudget(B)).
21273    #[inline]
21274    #[must_use]
21275    pub const fn combined_site_budget(&self) -> u16 {
21276        self.combined_site_budget
21277    }
21278    /// `SITE_COUNT(A + B)` — the foundation layout width including the new tag site.
21279    #[inline]
21280    #[must_use]
21281    pub const fn combined_site_count(&self) -> u16 {
21282        self.combined_site_count
21283    }
21284    /// Index of the tag site in the layout convention of §4b'.
21285    /// Equals `max(SITE_COUNT(A), SITE_COUNT(B))`.
21286    #[inline]
21287    #[must_use]
21288    pub const fn tag_site_index(&self) -> u16 {
21289        self.tag_site_index
21290    }
21291    #[inline]
21292    #[must_use]
21293    #[allow(clippy::too_many_arguments)]
21294    pub(crate) const fn with_level_fingerprints_sites_and_tag(
21295        witt_bits: u16,
21296        content_fingerprint: ContentFingerprint,
21297        left_fingerprint: ContentFingerprint,
21298        right_fingerprint: ContentFingerprint,
21299        combined_site_budget: u16,
21300        combined_site_count: u16,
21301        tag_site_index: u16,
21302    ) -> Self {
21303        Self {
21304            witt_bits,
21305            content_fingerprint,
21306            left_fingerprint,
21307            right_fingerprint,
21308            combined_site_budget,
21309            combined_site_count,
21310            tag_site_index,
21311        }
21312    }
21313}
21314
21315/// Sealed CartesianPartitionProduct witness — content-addressed
21316/// assertion that a shape is `CartesianPartitionProduct(left, right)`
21317/// per CPT_2a. Minting verifies CPT_1, CPT_3, CPT_4, CPT_5, and the
21318/// foundation `CartesianLayoutWidth` invariant. The witness stores
21319/// a snapshot of the combined topological invariants (χ, Betti profile)
21320/// because the construction is axiomatic at the invariant level per §3c.
21321/// Entropy is not stored here (f64 has no Eq/Hash); use the paired
21322/// `CartesianProductEvidence` for entropy re-audit.
21323#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21324pub struct CartesianProductWitness {
21325    witt_bits: u16,
21326    content_fingerprint: ContentFingerprint,
21327    left_fingerprint: ContentFingerprint,
21328    right_fingerprint: ContentFingerprint,
21329    combined_site_budget: u16,
21330    combined_site_count: u16,
21331    combined_euler: i32,
21332    combined_betti: [u32; MAX_BETTI_DIMENSION],
21333}
21334
21335impl CartesianProductWitness {
21336    #[inline]
21337    #[must_use]
21338    pub const fn witt_bits(&self) -> u16 {
21339        self.witt_bits
21340    }
21341    #[inline]
21342    #[must_use]
21343    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21344        self.content_fingerprint
21345    }
21346    #[inline]
21347    #[must_use]
21348    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21349        self.left_fingerprint
21350    }
21351    #[inline]
21352    #[must_use]
21353    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21354        self.right_fingerprint
21355    }
21356    #[inline]
21357    #[must_use]
21358    pub const fn combined_site_budget(&self) -> u16 {
21359        self.combined_site_budget
21360    }
21361    #[inline]
21362    #[must_use]
21363    pub const fn combined_site_count(&self) -> u16 {
21364        self.combined_site_count
21365    }
21366    #[inline]
21367    #[must_use]
21368    pub const fn combined_euler(&self) -> i32 {
21369        self.combined_euler
21370    }
21371    #[inline]
21372    #[must_use]
21373    pub const fn combined_betti(&self) -> [u32; MAX_BETTI_DIMENSION] {
21374        self.combined_betti
21375    }
21376    #[inline]
21377    #[must_use]
21378    #[allow(clippy::too_many_arguments)]
21379    pub(crate) const fn with_level_fingerprints_and_invariants(
21380        witt_bits: u16,
21381        content_fingerprint: ContentFingerprint,
21382        left_fingerprint: ContentFingerprint,
21383        right_fingerprint: ContentFingerprint,
21384        combined_site_budget: u16,
21385        combined_site_count: u16,
21386        combined_euler: i32,
21387        combined_betti: [u32; MAX_BETTI_DIMENSION],
21388    ) -> Self {
21389        Self {
21390            witt_bits,
21391            content_fingerprint,
21392            left_fingerprint,
21393            right_fingerprint,
21394            combined_site_budget,
21395            combined_site_count,
21396            combined_euler,
21397            combined_betti,
21398        }
21399    }
21400}
21401
21402impl Certificate for PartitionProductWitness {
21403    const IRI: &'static str = "https://uor.foundation/partition/PartitionProduct";
21404    type Evidence = PartitionProductEvidence;
21405}
21406
21407impl Certificate for PartitionCoproductWitness {
21408    const IRI: &'static str = "https://uor.foundation/partition/PartitionCoproduct";
21409    type Evidence = PartitionCoproductEvidence;
21410}
21411
21412impl Certificate for CartesianProductWitness {
21413    const IRI: &'static str = "https://uor.foundation/partition/CartesianPartitionProduct";
21414    type Evidence = CartesianProductEvidence;
21415}
21416
21417impl core::fmt::Display for PartitionProductWitness {
21418    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21419        f.write_str("PartitionProductWitness")
21420    }
21421}
21422impl core::error::Error for PartitionProductWitness {}
21423
21424impl core::fmt::Display for PartitionCoproductWitness {
21425    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21426        f.write_str("PartitionCoproductWitness")
21427    }
21428}
21429impl core::error::Error for PartitionCoproductWitness {}
21430
21431impl core::fmt::Display for CartesianProductWitness {
21432    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21433        f.write_str("CartesianProductWitness")
21434    }
21435}
21436impl core::error::Error for CartesianProductWitness {}
21437
21438/// Sealed mint path for certificates that require multi-theorem verification
21439/// before minting. Introduced by the Product/Coproduct Completion Amendment
21440/// §1c; distinct from `MintWithLevelFingerprint` (which is the generic
21441/// partial-mint path for sealed shims). `VerifiedMint` implementors are
21442/// the three partition-algebra witnesses, each routing through a
21443/// foundation-internal mint primitive that verifies the relevant theorems.
21444/// The trait is public so external callers can invoke `mint_verified`
21445/// directly, but the `Certificate` supertrait's `certificate_sealed::Sealed`
21446/// bound keeps the implementor set closed to this crate.
21447pub trait VerifiedMint: Certificate {
21448    /// Caller-supplied input bundle — one `*MintInputs` struct per witness.
21449    type Inputs;
21450    /// Failure kind — always `GenericImpossibilityWitness` citing the
21451    /// specific op-namespace theorem or foundation-namespace layout
21452    /// invariant that was violated.
21453    type Error;
21454    /// Verify the theorems and invariants against `inputs`, then mint a
21455    /// witness or return a typed impossibility witness.
21456    /// # Errors
21457    /// Returns a `GenericImpossibilityWitness::for_identity(iri)` when any
21458    /// of the gated theorems or foundation invariants fails. The IRI
21459    /// identifies exactly which identity failed — `op/PT_*`, `op/ST_*`,
21460    /// `op/CPT_*`, or `foundation/*LayoutWidth` / `foundation/CoproductTagEncoding`.
21461    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error>
21462    where
21463        Self: Sized;
21464}
21465
21466/// Recursive classifier used by `validate_coproduct_structure`. Inspects
21467/// one `ConstraintRef`, tallies tag-pinner sightings via mutable references,
21468/// and recurses into `Conjunction` conjuncts up to `max_depth` levels. See
21469/// plan §A4 for the depth bound rationale.
21470#[allow(clippy::too_many_arguments)]
21471fn pc_classify_constraint(
21472    c: &crate::pipeline::ConstraintRef,
21473    in_left_region: bool,
21474    tag_site: u16,
21475    max_depth: u32,
21476    left_pins: &mut u32,
21477    right_pins: &mut u32,
21478    left_bias_ok: &mut bool,
21479    right_bias_ok: &mut bool,
21480) -> Result<(), GenericImpossibilityWitness> {
21481    match c {
21482        crate::pipeline::ConstraintRef::Site { position } => {
21483            if (*position as u16) >= tag_site {
21484                return Err(GenericImpossibilityWitness::for_identity(
21485                    "https://uor.foundation/op/ST_6",
21486                ));
21487            }
21488        }
21489        crate::pipeline::ConstraintRef::Carry { site } => {
21490            if (*site as u16) >= tag_site {
21491                return Err(GenericImpossibilityWitness::for_identity(
21492                    "https://uor.foundation/op/ST_6",
21493                ));
21494            }
21495        }
21496        crate::pipeline::ConstraintRef::Affine { coefficients, coefficient_count, bias } => {
21497            let count = *coefficient_count as usize;
21498            let mut nonzero_count: u32 = 0;
21499            let mut nonzero_index: usize = 0;
21500            let mut max_nonzero_index: usize = 0;
21501            let mut i: usize = 0;
21502            while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS {
21503                if coefficients[i] != 0 {
21504                    nonzero_count = nonzero_count.saturating_add(1);
21505                    nonzero_index = i;
21506                    if i > max_nonzero_index { max_nonzero_index = i; }
21507                }
21508                i += 1;
21509            }
21510            let touches_tag_site = nonzero_count > 0
21511                && (max_nonzero_index as u16) >= tag_site;
21512            let is_canonical_tag_pinner = nonzero_count == 1
21513                && (nonzero_index as u16) == tag_site
21514                && coefficients[nonzero_index] == 1;
21515            if is_canonical_tag_pinner {
21516                if *bias != 0 && *bias != -1 {
21517                    return Err(GenericImpossibilityWitness::for_identity(
21518                        "https://uor.foundation/foundation/CoproductTagEncoding",
21519                    ));
21520                }
21521                if in_left_region {
21522                    *left_pins = left_pins.saturating_add(1);
21523                    if *bias != 0 { *left_bias_ok = false; }
21524                } else {
21525                    *right_pins = right_pins.saturating_add(1);
21526                    if *bias != -1 { *right_bias_ok = false; }
21527                }
21528            } else if touches_tag_site {
21529                let nonzero_only_at_tag_site = nonzero_count == 1
21530                    && (nonzero_index as u16) == tag_site;
21531                if nonzero_only_at_tag_site {
21532                    return Err(GenericImpossibilityWitness::for_identity(
21533                        "https://uor.foundation/foundation/CoproductTagEncoding",
21534                    ));
21535                } else {
21536                    return Err(GenericImpossibilityWitness::for_identity(
21537                        "https://uor.foundation/op/ST_6",
21538                    ));
21539                }
21540            }
21541        }
21542        crate::pipeline::ConstraintRef::Conjunction { conjuncts, conjunct_count } => {
21543            if max_depth == 0 {
21544                return Err(GenericImpossibilityWitness::for_identity(
21545                    "https://uor.foundation/op/ST_6",
21546                ));
21547            }
21548            let count = *conjunct_count as usize;
21549            let mut idx: usize = 0;
21550            while idx < count && idx < crate::pipeline::CONJUNCTION_MAX_TERMS {
21551                let lifted = conjuncts[idx].into_constraint();
21552                pc_classify_constraint(
21553                    &lifted,
21554                    in_left_region,
21555                    tag_site,
21556                    max_depth - 1,
21557                    left_pins,
21558                    right_pins,
21559                    left_bias_ok,
21560                    right_bias_ok,
21561                )?;
21562                idx += 1;
21563            }
21564        }
21565        crate::pipeline::ConstraintRef::Residue { .. }
21566        | crate::pipeline::ConstraintRef::Hamming { .. }
21567        | crate::pipeline::ConstraintRef::Depth { .. }
21568        | crate::pipeline::ConstraintRef::SatClauses { .. }
21569        | crate::pipeline::ConstraintRef::Bound { .. }
21570        // ADR-057: Recurse references a shape by content-addressed IRI;
21571        // no site references at this level to check.
21572        | crate::pipeline::ConstraintRef::Recurse { .. } => {
21573            // No site references at this level; nothing to check.
21574        }
21575    }
21576    Ok(())
21577}
21578
21579/// Validates ST_6 / ST_7 / ST_8 for a PartitionCoproduct construction by
21580/// walking the emitted constraint array. Recurses into
21581/// `ConstraintRef::Conjunction` conjuncts up to depth 8 (bounded by
21582/// `NERVE_CONSTRAINTS_CAP`) so nested constructions are audited without
21583/// unbounded recursion.
21584/// # Errors
21585/// Returns `GenericImpossibilityWitness::for_identity(...)` citing the
21586/// specific failed identity: `op/ST_6`, `op/ST_7`, or
21587/// `foundation/CoproductTagEncoding`. ST_8 is implied by ST_6 ∧ ST_7 and
21588/// is not cited separately on failure.
21589pub(crate) fn validate_coproduct_structure(
21590    combined_constraints: &[crate::pipeline::ConstraintRef],
21591    left_constraint_count: usize,
21592    tag_site: u16,
21593) -> Result<(), GenericImpossibilityWitness> {
21594    let mut left_pins: u32 = 0;
21595    let mut right_pins: u32 = 0;
21596    let mut left_bias_ok: bool = true;
21597    let mut right_bias_ok: bool = true;
21598    let mut idx: usize = 0;
21599    while idx < combined_constraints.len() {
21600        let in_left_region = idx < left_constraint_count;
21601        pc_classify_constraint(
21602            &combined_constraints[idx],
21603            in_left_region,
21604            tag_site,
21605            NERVE_CONSTRAINTS_CAP as u32,
21606            &mut left_pins,
21607            &mut right_pins,
21608            &mut left_bias_ok,
21609            &mut right_bias_ok,
21610        )?;
21611        idx += 1;
21612    }
21613    if left_pins != 1 || right_pins != 1 {
21614        return Err(GenericImpossibilityWitness::for_identity(
21615            "https://uor.foundation/op/ST_6",
21616        ));
21617    }
21618    if !left_bias_ok || !right_bias_ok {
21619        return Err(GenericImpossibilityWitness::for_identity(
21620            "https://uor.foundation/op/ST_7",
21621        ));
21622    }
21623    Ok(())
21624}
21625
21626/// Mint a `PartitionProductWitness` after verifying PT_1, PT_3, PT_4, and
21627/// the `ProductLayoutWidth` layout invariant. PT_2a is structural (the
21628/// witness existing is the claim); no separate check is needed once the
21629/// invariants match.
21630#[allow(clippy::too_many_arguments)]
21631pub(crate) fn pc_primitive_partition_product(
21632    witt_bits: u16,
21633    left_fingerprint: ContentFingerprint,
21634    right_fingerprint: ContentFingerprint,
21635    left_site_budget: u16,
21636    right_site_budget: u16,
21637    left_total_site_count: u16,
21638    right_total_site_count: u16,
21639    left_euler: i32,
21640    right_euler: i32,
21641    left_entropy_nats_bits: u64,
21642    right_entropy_nats_bits: u64,
21643    combined_site_budget: u16,
21644    combined_site_count: u16,
21645    combined_euler: i32,
21646    combined_entropy_nats_bits: u64,
21647    combined_fingerprint: ContentFingerprint,
21648) -> Result<PartitionProductWitness, GenericImpossibilityWitness> {
21649    let left_entropy_nats =
21650        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21651    let right_entropy_nats =
21652        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21653    let combined_entropy_nats =
21654        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21655    if combined_site_budget != left_site_budget.saturating_add(right_site_budget) {
21656        return Err(GenericImpossibilityWitness::for_identity(
21657            "https://uor.foundation/op/PT_1",
21658        ));
21659    }
21660    if combined_site_count != left_total_site_count.saturating_add(right_total_site_count) {
21661        return Err(GenericImpossibilityWitness::for_identity(
21662            "https://uor.foundation/foundation/ProductLayoutWidth",
21663        ));
21664    }
21665    if combined_euler != left_euler.saturating_add(right_euler) {
21666        return Err(GenericImpossibilityWitness::for_identity(
21667            "https://uor.foundation/op/PT_3",
21668        ));
21669    }
21670    if !pc_entropy_input_is_valid(left_entropy_nats)
21671        || !pc_entropy_input_is_valid(right_entropy_nats)
21672        || !pc_entropy_input_is_valid(combined_entropy_nats)
21673    {
21674        return Err(GenericImpossibilityWitness::for_identity(
21675            "https://uor.foundation/op/PT_4",
21676        ));
21677    }
21678    let expected_entropy = left_entropy_nats + right_entropy_nats;
21679    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21680        return Err(GenericImpossibilityWitness::for_identity(
21681            "https://uor.foundation/op/PT_4",
21682        ));
21683    }
21684    Ok(PartitionProductWitness::with_level_fingerprints_and_sites(
21685        witt_bits,
21686        combined_fingerprint,
21687        left_fingerprint,
21688        right_fingerprint,
21689        combined_site_budget,
21690        combined_site_count,
21691    ))
21692}
21693
21694/// Mint a `PartitionCoproductWitness` after verifying ST_1, ST_2, ST_6,
21695/// ST_7, ST_8, ST_9, ST_10, the `CoproductLayoutWidth` layout invariant,
21696/// the tag-site alignment against §4b', and running
21697/// `validate_coproduct_structure` over the supplied constraint array.
21698#[allow(clippy::too_many_arguments)]
21699pub(crate) fn pc_primitive_partition_coproduct(
21700    witt_bits: u16,
21701    left_fingerprint: ContentFingerprint,
21702    right_fingerprint: ContentFingerprint,
21703    left_site_budget: u16,
21704    right_site_budget: u16,
21705    left_total_site_count: u16,
21706    right_total_site_count: u16,
21707    left_euler: i32,
21708    right_euler: i32,
21709    left_entropy_nats_bits: u64,
21710    right_entropy_nats_bits: u64,
21711    left_betti: [u32; MAX_BETTI_DIMENSION],
21712    right_betti: [u32; MAX_BETTI_DIMENSION],
21713    combined_site_budget: u16,
21714    combined_site_count: u16,
21715    combined_euler: i32,
21716    combined_entropy_nats_bits: u64,
21717    combined_betti: [u32; MAX_BETTI_DIMENSION],
21718    combined_fingerprint: ContentFingerprint,
21719    combined_constraints: &[crate::pipeline::ConstraintRef],
21720    left_constraint_count: usize,
21721    tag_site: u16,
21722) -> Result<PartitionCoproductWitness, GenericImpossibilityWitness> {
21723    let left_entropy_nats =
21724        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21725    let right_entropy_nats =
21726        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21727    let combined_entropy_nats =
21728        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21729    let expected_budget = if left_site_budget > right_site_budget {
21730        left_site_budget
21731    } else {
21732        right_site_budget
21733    };
21734    if combined_site_budget != expected_budget {
21735        return Err(GenericImpossibilityWitness::for_identity(
21736            "https://uor.foundation/op/ST_1",
21737        ));
21738    }
21739    let max_total = if left_total_site_count > right_total_site_count {
21740        left_total_site_count
21741    } else {
21742        right_total_site_count
21743    };
21744    let expected_total = max_total.saturating_add(1);
21745    if combined_site_count != expected_total {
21746        return Err(GenericImpossibilityWitness::for_identity(
21747            "https://uor.foundation/foundation/CoproductLayoutWidth",
21748        ));
21749    }
21750    if !pc_entropy_input_is_valid(left_entropy_nats)
21751        || !pc_entropy_input_is_valid(right_entropy_nats)
21752        || !pc_entropy_input_is_valid(combined_entropy_nats)
21753    {
21754        return Err(GenericImpossibilityWitness::for_identity(
21755            "https://uor.foundation/op/ST_2",
21756        ));
21757    }
21758    let max_operand_entropy = if left_entropy_nats > right_entropy_nats {
21759        left_entropy_nats
21760    } else {
21761        right_entropy_nats
21762    };
21763    let expected_entropy = core::f64::consts::LN_2 + max_operand_entropy;
21764    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21765        return Err(GenericImpossibilityWitness::for_identity(
21766            "https://uor.foundation/op/ST_2",
21767        ));
21768    }
21769    if tag_site != max_total {
21770        return Err(GenericImpossibilityWitness::for_identity(
21771            "https://uor.foundation/foundation/CoproductLayoutWidth",
21772        ));
21773    }
21774    validate_coproduct_structure(combined_constraints, left_constraint_count, tag_site)?;
21775    if combined_euler != left_euler.saturating_add(right_euler) {
21776        return Err(GenericImpossibilityWitness::for_identity(
21777            "https://uor.foundation/op/ST_9",
21778        ));
21779    }
21780    let mut k: usize = 0;
21781    while k < MAX_BETTI_DIMENSION {
21782        if combined_betti[k] != left_betti[k].saturating_add(right_betti[k]) {
21783            return Err(GenericImpossibilityWitness::for_identity(
21784                "https://uor.foundation/op/ST_10",
21785            ));
21786        }
21787        k += 1;
21788    }
21789    Ok(
21790        PartitionCoproductWitness::with_level_fingerprints_sites_and_tag(
21791            witt_bits,
21792            combined_fingerprint,
21793            left_fingerprint,
21794            right_fingerprint,
21795            combined_site_budget,
21796            combined_site_count,
21797            max_total,
21798        ),
21799    )
21800}
21801
21802/// Mint a `CartesianProductWitness` after verifying CPT_1, CPT_3, CPT_4,
21803/// CPT_5, and the `CartesianLayoutWidth` layout invariant. Checks
21804/// caller-supplied Künneth-composed invariants against the component
21805/// values (the witness defines these axiomatically per §3c).
21806#[allow(clippy::too_many_arguments)]
21807pub(crate) fn pc_primitive_cartesian_product(
21808    witt_bits: u16,
21809    left_fingerprint: ContentFingerprint,
21810    right_fingerprint: ContentFingerprint,
21811    left_site_budget: u16,
21812    right_site_budget: u16,
21813    left_total_site_count: u16,
21814    right_total_site_count: u16,
21815    left_euler: i32,
21816    right_euler: i32,
21817    left_betti: [u32; MAX_BETTI_DIMENSION],
21818    right_betti: [u32; MAX_BETTI_DIMENSION],
21819    left_entropy_nats_bits: u64,
21820    right_entropy_nats_bits: u64,
21821    combined_site_budget: u16,
21822    combined_site_count: u16,
21823    combined_euler: i32,
21824    combined_betti: [u32; MAX_BETTI_DIMENSION],
21825    combined_entropy_nats_bits: u64,
21826    combined_fingerprint: ContentFingerprint,
21827) -> Result<CartesianProductWitness, GenericImpossibilityWitness> {
21828    let left_entropy_nats =
21829        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21830    let right_entropy_nats =
21831        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21832    let combined_entropy_nats =
21833        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21834    if combined_site_budget != left_site_budget.saturating_add(right_site_budget) {
21835        return Err(GenericImpossibilityWitness::for_identity(
21836            "https://uor.foundation/op/CPT_1",
21837        ));
21838    }
21839    if combined_site_count != left_total_site_count.saturating_add(right_total_site_count) {
21840        return Err(GenericImpossibilityWitness::for_identity(
21841            "https://uor.foundation/foundation/CartesianLayoutWidth",
21842        ));
21843    }
21844    if combined_euler != left_euler.saturating_mul(right_euler) {
21845        return Err(GenericImpossibilityWitness::for_identity(
21846            "https://uor.foundation/op/CPT_3",
21847        ));
21848    }
21849    let kunneth = crate::pipeline::kunneth_compose(&left_betti, &right_betti);
21850    let mut k: usize = 0;
21851    while k < MAX_BETTI_DIMENSION {
21852        if combined_betti[k] != kunneth[k] {
21853            return Err(GenericImpossibilityWitness::for_identity(
21854                "https://uor.foundation/op/CPT_4",
21855            ));
21856        }
21857        k += 1;
21858    }
21859    if !pc_entropy_input_is_valid(left_entropy_nats)
21860        || !pc_entropy_input_is_valid(right_entropy_nats)
21861        || !pc_entropy_input_is_valid(combined_entropy_nats)
21862    {
21863        return Err(GenericImpossibilityWitness::for_identity(
21864            "https://uor.foundation/op/CPT_5",
21865        ));
21866    }
21867    let expected_entropy = left_entropy_nats + right_entropy_nats;
21868    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21869        return Err(GenericImpossibilityWitness::for_identity(
21870            "https://uor.foundation/op/CPT_5",
21871        ));
21872    }
21873    Ok(
21874        CartesianProductWitness::with_level_fingerprints_and_invariants(
21875            witt_bits,
21876            combined_fingerprint,
21877            left_fingerprint,
21878            right_fingerprint,
21879            combined_site_budget,
21880            combined_site_count,
21881            combined_euler,
21882            combined_betti,
21883        ),
21884    )
21885}
21886
21887impl VerifiedMint for PartitionProductWitness {
21888    type Inputs = PartitionProductMintInputs;
21889    type Error = GenericImpossibilityWitness;
21890    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
21891        pc_primitive_partition_product(
21892            inputs.witt_bits,
21893            inputs.left_fingerprint,
21894            inputs.right_fingerprint,
21895            inputs.left_site_budget,
21896            inputs.right_site_budget,
21897            inputs.left_total_site_count,
21898            inputs.right_total_site_count,
21899            inputs.left_euler,
21900            inputs.right_euler,
21901            inputs.left_entropy_nats_bits,
21902            inputs.right_entropy_nats_bits,
21903            inputs.combined_site_budget,
21904            inputs.combined_site_count,
21905            inputs.combined_euler,
21906            inputs.combined_entropy_nats_bits,
21907            inputs.combined_fingerprint,
21908        )
21909    }
21910}
21911
21912impl VerifiedMint for PartitionCoproductWitness {
21913    type Inputs = PartitionCoproductMintInputs;
21914    type Error = GenericImpossibilityWitness;
21915    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
21916        pc_primitive_partition_coproduct(
21917            inputs.witt_bits,
21918            inputs.left_fingerprint,
21919            inputs.right_fingerprint,
21920            inputs.left_site_budget,
21921            inputs.right_site_budget,
21922            inputs.left_total_site_count,
21923            inputs.right_total_site_count,
21924            inputs.left_euler,
21925            inputs.right_euler,
21926            inputs.left_entropy_nats_bits,
21927            inputs.right_entropy_nats_bits,
21928            inputs.left_betti,
21929            inputs.right_betti,
21930            inputs.combined_site_budget,
21931            inputs.combined_site_count,
21932            inputs.combined_euler,
21933            inputs.combined_entropy_nats_bits,
21934            inputs.combined_betti,
21935            inputs.combined_fingerprint,
21936            inputs.combined_constraints,
21937            inputs.left_constraint_count,
21938            inputs.tag_site,
21939        )
21940    }
21941}
21942
21943impl VerifiedMint for CartesianProductWitness {
21944    type Inputs = CartesianProductMintInputs;
21945    type Error = GenericImpossibilityWitness;
21946    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
21947        pc_primitive_cartesian_product(
21948            inputs.witt_bits,
21949            inputs.left_fingerprint,
21950            inputs.right_fingerprint,
21951            inputs.left_site_budget,
21952            inputs.right_site_budget,
21953            inputs.left_total_site_count,
21954            inputs.right_total_site_count,
21955            inputs.left_euler,
21956            inputs.right_euler,
21957            inputs.left_betti,
21958            inputs.right_betti,
21959            inputs.left_entropy_nats_bits,
21960            inputs.right_entropy_nats_bits,
21961            inputs.combined_site_budget,
21962            inputs.combined_site_count,
21963            inputs.combined_euler,
21964            inputs.combined_betti,
21965            inputs.combined_entropy_nats_bits,
21966            inputs.combined_fingerprint,
21967        )
21968    }
21969}
21970
21971/// Data record of a partition's runtime-queried properties. Produced at
21972/// witness-mint time and consulted by consumer code that holds a
21973/// `PartitionHandle` and a `PartitionResolver`. Phase 9 stores entropy
21974/// as the IEEE-754 `u64` bit-pattern (`entropy_nats_bits`) so the record
21975/// derives `Eq + Hash` cleanly; consumers project to `H::Decimal` via
21976/// `<H::Decimal as DecimalTranscendental>::from_bits`.
21977#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21978pub struct PartitionRecord<H: crate::HostTypes> {
21979    /// Data sites only — the partition's `siteBudget`, not its layout width.
21980    pub site_budget: u16,
21981    /// Euler characteristic of the partition's nerve.
21982    pub euler: i32,
21983    /// Betti profile of the partition's nerve, padded to `MAX_BETTI_DIMENSION`.
21984    pub betti: [u32; MAX_BETTI_DIMENSION],
21985    /// Shannon entropy in nats (matches `LandauerBudget::nats()` convention).
21986    pub entropy_nats_bits: u64,
21987    _phantom: core::marker::PhantomData<H>,
21988}
21989
21990impl<H: crate::HostTypes> PartitionRecord<H> {
21991    /// Construct a new record. The phantom marker ensures records are
21992    /// parameterized by the host types they originate from.
21993    #[inline]
21994    #[must_use]
21995    pub const fn new(
21996        site_budget: u16,
21997        euler: i32,
21998        betti: [u32; MAX_BETTI_DIMENSION],
21999        entropy_nats_bits: u64,
22000    ) -> Self {
22001        Self {
22002            site_budget,
22003            euler,
22004            betti,
22005            entropy_nats_bits,
22006            _phantom: core::marker::PhantomData,
22007        }
22008    }
22009}
22010
22011/// Resolver mapping content fingerprints to `PartitionRecord`s. Provided
22012/// by the host application — typically a persistent store, an in-memory
22013/// registry populated from witness mint-time data, or a chain-of-witnesses
22014/// trail that can reconstruct properties.
22015pub trait PartitionResolver<H: crate::HostTypes> {
22016    /// Look up partition data by fingerprint. Returns `None` if the
22017    /// resolver has no record for the handle. Handles remain valid as
22018    /// identity tokens regardless of resolver presence.
22019    fn resolve(&self, fp: ContentFingerprint) -> Option<PartitionRecord<H>>;
22020}
22021
22022/// Content-addressed identity token for a partition. Carries only a
22023/// fingerprint; partition data is recovered by pairing the handle with a
22024/// `PartitionResolver` via `resolve_with`. Handles compare and hash by
22025/// fingerprint, so they can serve as keys in content-addressed indices
22026/// without resolver access.
22027#[derive(Debug)]
22028pub struct PartitionHandle<H: crate::HostTypes> {
22029    fingerprint: ContentFingerprint,
22030    _phantom: core::marker::PhantomData<H>,
22031}
22032impl<H: crate::HostTypes> Copy for PartitionHandle<H> {}
22033impl<H: crate::HostTypes> Clone for PartitionHandle<H> {
22034    #[inline]
22035    fn clone(&self) -> Self {
22036        *self
22037    }
22038}
22039impl<H: crate::HostTypes> PartialEq for PartitionHandle<H> {
22040    #[inline]
22041    fn eq(&self, other: &Self) -> bool {
22042        self.fingerprint == other.fingerprint
22043    }
22044}
22045impl<H: crate::HostTypes> Eq for PartitionHandle<H> {}
22046impl<H: crate::HostTypes> core::hash::Hash for PartitionHandle<H> {
22047    #[inline]
22048    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
22049        self.fingerprint.hash(state);
22050    }
22051}
22052
22053impl<H: crate::HostTypes> PartitionHandle<H> {
22054    /// Construct a handle from a content fingerprint.
22055    #[inline]
22056    #[must_use]
22057    pub const fn from_fingerprint(fingerprint: ContentFingerprint) -> Self {
22058        Self {
22059            fingerprint,
22060            _phantom: core::marker::PhantomData,
22061        }
22062    }
22063    /// Return the content fingerprint this handle references.
22064    #[inline]
22065    #[must_use]
22066    pub const fn fingerprint(&self) -> ContentFingerprint {
22067        self.fingerprint
22068    }
22069    /// Resolve this handle against a consumer-supplied resolver.
22070    /// Returns `None` if the resolver has no record for this fingerprint.
22071    #[inline]
22072    pub fn resolve_with<R: PartitionResolver<H>>(
22073        &self,
22074        resolver: &R,
22075    ) -> Option<PartitionRecord<H>> {
22076        resolver.resolve(self.fingerprint)
22077    }
22078}
22079
22080/// Resolver-absent default `Element<H>`. Returns empty defaults via the
22081/// `HostTypes::EMPTY_*` constants — used by `NullDatum<H>` and
22082/// `NullTypeDefinition<H>` to satisfy their `Element` associated types.
22083#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22084pub struct NullElement<H: HostTypes> {
22085    _phantom: core::marker::PhantomData<H>,
22086}
22087impl<H: HostTypes> Default for NullElement<H> {
22088    fn default() -> Self {
22089        Self {
22090            _phantom: core::marker::PhantomData,
22091        }
22092    }
22093}
22094impl<H: HostTypes> crate::kernel::address::Element<H> for NullElement<H> {
22095    fn length(&self) -> u64 {
22096        0
22097    }
22098    fn addresses(&self) -> &H::HostString {
22099        H::EMPTY_HOST_STRING
22100    }
22101    fn digest(&self) -> &H::HostString {
22102        H::EMPTY_HOST_STRING
22103    }
22104    fn digest_algorithm(&self) -> &H::HostString {
22105        H::EMPTY_HOST_STRING
22106    }
22107    fn canonical_bytes(&self) -> &H::WitnessBytes {
22108        H::EMPTY_WITNESS_BYTES
22109    }
22110    fn witt_length(&self) -> u64 {
22111        0
22112    }
22113}
22114
22115/// Resolver-absent default `Datum<H>`. All numeric methods return 0.
22116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22117pub struct NullDatum<H: HostTypes> {
22118    element: NullElement<H>,
22119    _phantom: core::marker::PhantomData<H>,
22120}
22121impl<H: HostTypes> Default for NullDatum<H> {
22122    fn default() -> Self {
22123        Self {
22124            element: NullElement::default(),
22125            _phantom: core::marker::PhantomData,
22126        }
22127    }
22128}
22129impl<H: HostTypes> crate::kernel::schema::Datum<H> for NullDatum<H> {
22130    fn value(&self) -> u64 {
22131        0
22132    }
22133    fn witt_length(&self) -> u64 {
22134        0
22135    }
22136    fn stratum(&self) -> u64 {
22137        0
22138    }
22139    fn spectrum(&self) -> u64 {
22140        0
22141    }
22142    type Element = NullElement<H>;
22143    fn element(&self) -> &Self::Element {
22144        &self.element
22145    }
22146}
22147
22148/// Resolver-absent default `TermExpression<H>`. Empty marker trait, no methods.
22149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22150pub struct NullTermExpression<H: HostTypes> {
22151    _phantom: core::marker::PhantomData<H>,
22152}
22153impl<H: HostTypes> Default for NullTermExpression<H> {
22154    fn default() -> Self {
22155        Self {
22156            _phantom: core::marker::PhantomData,
22157        }
22158    }
22159}
22160impl<H: HostTypes> crate::kernel::schema::TermExpression<H> for NullTermExpression<H> {}
22161
22162/// Resolver-absent default `SiteIndex<H>`. Self-recursive: `ancilla_site()`
22163/// returns `&self` (no ancilla pairing in the default).
22164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22165pub struct NullSiteIndex<H: HostTypes> {
22166    _phantom: core::marker::PhantomData<H>,
22167}
22168impl<H: HostTypes> Default for NullSiteIndex<H> {
22169    fn default() -> Self {
22170        Self {
22171            _phantom: core::marker::PhantomData,
22172        }
22173    }
22174}
22175impl<H: HostTypes> crate::bridge::partition::SiteIndex<H> for NullSiteIndex<H> {
22176    fn site_position(&self) -> u64 {
22177        0
22178    }
22179    fn site_state(&self) -> u64 {
22180        0
22181    }
22182    type SiteIndexTarget = NullSiteIndex<H>;
22183    fn ancilla_site(&self) -> &Self::SiteIndexTarget {
22184        self
22185    }
22186}
22187
22188/// Resolver-absent default `TagSite<H>`. Embeds an inline `NullSiteIndex`
22189/// field so the inherited `ancilla_site()` accessor returns a valid
22190/// reference; `tag_value()` returns false.
22191#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22192pub struct NullTagSite<H: HostTypes> {
22193    ancilla: NullSiteIndex<H>,
22194}
22195impl<H: HostTypes> Default for NullTagSite<H> {
22196    fn default() -> Self {
22197        Self {
22198            ancilla: NullSiteIndex::default(),
22199        }
22200    }
22201}
22202impl<H: HostTypes> crate::bridge::partition::SiteIndex<H> for NullTagSite<H> {
22203    fn site_position(&self) -> u64 {
22204        0
22205    }
22206    fn site_state(&self) -> u64 {
22207        0
22208    }
22209    type SiteIndexTarget = NullSiteIndex<H>;
22210    fn ancilla_site(&self) -> &Self::SiteIndexTarget {
22211        &self.ancilla
22212    }
22213}
22214impl<H: HostTypes> crate::bridge::partition::TagSite<H> for NullTagSite<H> {
22215    fn tag_value(&self) -> bool {
22216        false
22217    }
22218}
22219
22220/// Resolver-absent default `SiteBinding<H>`. Embeds inline `NullConstraint`
22221/// and `NullSiteIndex` so the trait's reference accessors work via &self.field.
22222#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22223pub struct NullSiteBinding<H: HostTypes> {
22224    constraint: NullConstraint<H>,
22225    site_index: NullSiteIndex<H>,
22226}
22227impl<H: HostTypes> Default for NullSiteBinding<H> {
22228    fn default() -> Self {
22229        Self {
22230            constraint: NullConstraint::default(),
22231            site_index: NullSiteIndex::default(),
22232        }
22233    }
22234}
22235impl<H: HostTypes> crate::bridge::partition::SiteBinding<H> for NullSiteBinding<H> {
22236    type Constraint = NullConstraint<H>;
22237    fn pinned_by(&self) -> &Self::Constraint {
22238        &self.constraint
22239    }
22240    type SiteIndex = NullSiteIndex<H>;
22241    fn pins_coordinate(&self) -> &Self::SiteIndex {
22242        &self.site_index
22243    }
22244}
22245
22246/// Resolver-absent default `Constraint<H>`. Returns Vertical metric axis,
22247/// empty pinned-sites slice, and zero crossing cost.
22248#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22249pub struct NullConstraint<H: HostTypes> {
22250    _phantom: core::marker::PhantomData<H>,
22251}
22252impl<H: HostTypes> Default for NullConstraint<H> {
22253    fn default() -> Self {
22254        Self {
22255            _phantom: core::marker::PhantomData,
22256        }
22257    }
22258}
22259impl<H: HostTypes> crate::user::type_::Constraint<H> for NullConstraint<H> {
22260    fn metric_axis(&self) -> MetricAxis {
22261        MetricAxis::Vertical
22262    }
22263    type SiteIndex = NullSiteIndex<H>;
22264    fn pins_sites(&self) -> &[Self::SiteIndex] {
22265        &[]
22266    }
22267    fn crossing_cost(&self) -> u64 {
22268        0
22269    }
22270}
22271
22272/// Resolver-absent default `FreeRank<H>`. Empty budget — `is_closed()` true,
22273/// zero counts. Empty `has_site` / `has_binding` slices.
22274#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22275pub struct NullFreeRank<H: HostTypes> {
22276    _phantom: core::marker::PhantomData<H>,
22277}
22278impl<H: HostTypes> Default for NullFreeRank<H> {
22279    fn default() -> Self {
22280        Self {
22281            _phantom: core::marker::PhantomData,
22282        }
22283    }
22284}
22285impl<H: HostTypes> crate::bridge::partition::FreeRank<H> for NullFreeRank<H> {
22286    fn total_sites(&self) -> u64 {
22287        0
22288    }
22289    fn pinned_count(&self) -> u64 {
22290        0
22291    }
22292    fn free_rank(&self) -> u64 {
22293        0
22294    }
22295    fn is_closed(&self) -> bool {
22296        true
22297    }
22298    type SiteIndex = NullSiteIndex<H>;
22299    fn has_site(&self) -> &[Self::SiteIndex] {
22300        &[]
22301    }
22302    type SiteBinding = NullSiteBinding<H>;
22303    fn has_binding(&self) -> &[Self::SiteBinding] {
22304        &[]
22305    }
22306    fn reversible_strategy(&self) -> bool {
22307        false
22308    }
22309}
22310
22311/// Resolver-absent default `IrreducibleSet<H>`. Implements `Component<H>` with empty
22312/// `member` slice and zero `cardinality`.
22313#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22314pub struct NullIrreducibleSet<H: HostTypes> {
22315    _phantom: core::marker::PhantomData<H>,
22316}
22317impl<H: HostTypes> Default for NullIrreducibleSet<H> {
22318    fn default() -> Self {
22319        Self {
22320            _phantom: core::marker::PhantomData,
22321        }
22322    }
22323}
22324impl<H: HostTypes> crate::bridge::partition::Component<H> for NullIrreducibleSet<H> {
22325    type Datum = NullDatum<H>;
22326    fn member(&self) -> &[Self::Datum] {
22327        &[]
22328    }
22329    fn cardinality(&self) -> u64 {
22330        0
22331    }
22332}
22333impl<H: HostTypes> crate::bridge::partition::IrreducibleSet<H> for NullIrreducibleSet<H> {}
22334
22335/// Resolver-absent default `ReducibleSet<H>`. Implements `Component<H>` with empty
22336/// `member` slice and zero `cardinality`.
22337#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22338pub struct NullReducibleSet<H: HostTypes> {
22339    _phantom: core::marker::PhantomData<H>,
22340}
22341impl<H: HostTypes> Default for NullReducibleSet<H> {
22342    fn default() -> Self {
22343        Self {
22344            _phantom: core::marker::PhantomData,
22345        }
22346    }
22347}
22348impl<H: HostTypes> crate::bridge::partition::Component<H> for NullReducibleSet<H> {
22349    type Datum = NullDatum<H>;
22350    fn member(&self) -> &[Self::Datum] {
22351        &[]
22352    }
22353    fn cardinality(&self) -> u64 {
22354        0
22355    }
22356}
22357impl<H: HostTypes> crate::bridge::partition::ReducibleSet<H> for NullReducibleSet<H> {}
22358
22359/// Resolver-absent default `UnitGroup<H>`. Implements `Component<H>` with empty
22360/// `member` slice and zero `cardinality`.
22361#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22362pub struct NullUnitGroup<H: HostTypes> {
22363    _phantom: core::marker::PhantomData<H>,
22364}
22365impl<H: HostTypes> Default for NullUnitGroup<H> {
22366    fn default() -> Self {
22367        Self {
22368            _phantom: core::marker::PhantomData,
22369        }
22370    }
22371}
22372impl<H: HostTypes> crate::bridge::partition::Component<H> for NullUnitGroup<H> {
22373    type Datum = NullDatum<H>;
22374    fn member(&self) -> &[Self::Datum] {
22375        &[]
22376    }
22377    fn cardinality(&self) -> u64 {
22378        0
22379    }
22380}
22381impl<H: HostTypes> crate::bridge::partition::UnitGroup<H> for NullUnitGroup<H> {}
22382
22383/// Resolver-absent default `Complement<H>`. Implements `Component<H>` plus
22384/// the `exterior_criteria()` accessor returning a reference to an embedded
22385/// `NullTermExpression`.
22386#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22387pub struct NullComplement<H: HostTypes> {
22388    term: NullTermExpression<H>,
22389}
22390impl<H: HostTypes> Default for NullComplement<H> {
22391    fn default() -> Self {
22392        Self {
22393            term: NullTermExpression::default(),
22394        }
22395    }
22396}
22397impl<H: HostTypes> crate::bridge::partition::Component<H> for NullComplement<H> {
22398    type Datum = NullDatum<H>;
22399    fn member(&self) -> &[Self::Datum] {
22400        &[]
22401    }
22402    fn cardinality(&self) -> u64 {
22403        0
22404    }
22405}
22406impl<H: HostTypes> crate::bridge::partition::Complement<H> for NullComplement<H> {
22407    type TermExpression = NullTermExpression<H>;
22408    fn exterior_criteria(&self) -> &Self::TermExpression {
22409        &self.term
22410    }
22411}
22412
22413/// Resolver-absent default `TypeDefinition<H>`. Embeds inline `NullElement`
22414/// for the content_address accessor.
22415#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22416pub struct NullTypeDefinition<H: HostTypes> {
22417    element: NullElement<H>,
22418}
22419impl<H: HostTypes> Default for NullTypeDefinition<H> {
22420    fn default() -> Self {
22421        Self {
22422            element: NullElement::default(),
22423        }
22424    }
22425}
22426impl<H: HostTypes> crate::user::type_::TypeDefinition<H> for NullTypeDefinition<H> {
22427    type Element = NullElement<H>;
22428    fn content_address(&self) -> &Self::Element {
22429        &self.element
22430    }
22431}
22432
22433/// Resolver-absent default `Partition<H>`. Embeds inline stubs for every
22434/// sub-trait associated type so `Partition<H>` accessors return references
22435/// to fields rather than to statics. The only meaningful state is the
22436/// `fingerprint`; everything else uses `HostTypes::EMPTY_*` defaults.
22437/// Returned by the three witness trait impls' `left_factor` / `right_factor`
22438/// / `left_summand` / etc. accessors as the resolver-absent value pathway.
22439/// Consumers needing real partition data pair the sibling `PartitionHandle`
22440/// with a `PartitionResolver` instead.
22441#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22442pub struct NullPartition<H: HostTypes> {
22443    irreducibles: NullIrreducibleSet<H>,
22444    reducibles: NullReducibleSet<H>,
22445    units: NullUnitGroup<H>,
22446    exterior: NullComplement<H>,
22447    free_rank: NullFreeRank<H>,
22448    tag_site: NullTagSite<H>,
22449    source_type: NullTypeDefinition<H>,
22450    fingerprint: ContentFingerprint,
22451}
22452
22453impl<H: HostTypes> NullPartition<H> {
22454    /// Construct a NullPartition with the given content fingerprint.
22455    /// All other fields are resolver-absent defaults.
22456    #[inline]
22457    #[must_use]
22458    pub fn from_fingerprint(fingerprint: ContentFingerprint) -> Self {
22459        Self {
22460            irreducibles: NullIrreducibleSet::default(),
22461            reducibles: NullReducibleSet::default(),
22462            units: NullUnitGroup::default(),
22463            exterior: NullComplement::default(),
22464            free_rank: NullFreeRank::default(),
22465            tag_site: NullTagSite::default(),
22466            source_type: NullTypeDefinition::default(),
22467            fingerprint,
22468        }
22469    }
22470    /// Returns the content fingerprint identifying which Partition this stub stands in for.
22471    #[inline]
22472    #[must_use]
22473    pub const fn fingerprint(&self) -> ContentFingerprint {
22474        self.fingerprint
22475    }
22476    /// Phase 2 (orphan-closure): absent-value sentinel used by Null stubs
22477    /// in other namespaces to satisfy `&Self::Partition` return borrows.
22478    pub const ABSENT: NullPartition<H> = NullPartition {
22479        irreducibles: NullIrreducibleSet {
22480            _phantom: core::marker::PhantomData,
22481        },
22482        reducibles: NullReducibleSet {
22483            _phantom: core::marker::PhantomData,
22484        },
22485        units: NullUnitGroup {
22486            _phantom: core::marker::PhantomData,
22487        },
22488        exterior: NullComplement {
22489            term: NullTermExpression {
22490                _phantom: core::marker::PhantomData,
22491            },
22492        },
22493        free_rank: NullFreeRank {
22494            _phantom: core::marker::PhantomData,
22495        },
22496        tag_site: NullTagSite {
22497            ancilla: NullSiteIndex {
22498                _phantom: core::marker::PhantomData,
22499            },
22500        },
22501        source_type: NullTypeDefinition {
22502            element: NullElement {
22503                _phantom: core::marker::PhantomData,
22504            },
22505        },
22506        fingerprint: ContentFingerprint::zero(),
22507    };
22508}
22509
22510impl<H: HostTypes> crate::bridge::partition::Partition<H> for NullPartition<H> {
22511    type IrreducibleSet = NullIrreducibleSet<H>;
22512    fn irreducibles(&self) -> &Self::IrreducibleSet {
22513        &self.irreducibles
22514    }
22515    type ReducibleSet = NullReducibleSet<H>;
22516    fn reducibles(&self) -> &Self::ReducibleSet {
22517        &self.reducibles
22518    }
22519    type UnitGroup = NullUnitGroup<H>;
22520    fn units(&self) -> &Self::UnitGroup {
22521        &self.units
22522    }
22523    type Complement = NullComplement<H>;
22524    fn exterior(&self) -> &Self::Complement {
22525        &self.exterior
22526    }
22527    fn density(&self) -> H::Decimal {
22528        H::EMPTY_DECIMAL
22529    }
22530    type TypeDefinition = NullTypeDefinition<H>;
22531    fn source_type(&self) -> &Self::TypeDefinition {
22532        &self.source_type
22533    }
22534    fn witt_length(&self) -> u64 {
22535        0
22536    }
22537    type FreeRank = NullFreeRank<H>;
22538    fn site_budget(&self) -> &Self::FreeRank {
22539        &self.free_rank
22540    }
22541    fn is_exhaustive(&self) -> bool {
22542        true
22543    }
22544    type TagSite = NullTagSite<H>;
22545    fn tag_site_of(&self) -> &Self::TagSite {
22546        &self.tag_site
22547    }
22548    fn product_category_level(&self) -> &H::HostString {
22549        H::EMPTY_HOST_STRING
22550    }
22551}
22552
22553impl<H: HostTypes> crate::bridge::partition::PartitionProduct<H> for PartitionProductWitness {
22554    type Partition = NullPartition<H>;
22555    fn left_factor(&self) -> Self::Partition {
22556        NullPartition::from_fingerprint(self.left_fingerprint)
22557    }
22558    fn right_factor(&self) -> Self::Partition {
22559        NullPartition::from_fingerprint(self.right_fingerprint)
22560    }
22561}
22562
22563impl<H: HostTypes> crate::bridge::partition::PartitionCoproduct<H> for PartitionCoproductWitness {
22564    type Partition = NullPartition<H>;
22565    fn left_summand(&self) -> Self::Partition {
22566        NullPartition::from_fingerprint(self.left_fingerprint)
22567    }
22568    fn right_summand(&self) -> Self::Partition {
22569        NullPartition::from_fingerprint(self.right_fingerprint)
22570    }
22571}
22572
22573impl<H: HostTypes> crate::bridge::partition::CartesianPartitionProduct<H>
22574    for CartesianProductWitness
22575{
22576    type Partition = NullPartition<H>;
22577    fn left_cartesian_factor(&self) -> Self::Partition {
22578        NullPartition::from_fingerprint(self.left_fingerprint)
22579    }
22580    fn right_cartesian_factor(&self) -> Self::Partition {
22581        NullPartition::from_fingerprint(self.right_fingerprint)
22582    }
22583}
22584
22585/// v0.2.1 ergonomics prelude. Re-exports the core symbols downstream crates
22586/// need for the consumer-facing one-liners.
22587/// Ontology-driven: the set of certificate / type / builder symbols is
22588/// sourced from `conformance:PreludeExport` individuals. Adding a new
22589/// symbol to the prelude is an ontology edit, verified against the
22590/// codegen's known-name mapping at build time.
22591pub mod prelude {
22592    pub use super::calibrations;
22593    pub use super::Add;
22594    pub use super::And;
22595    pub use super::BNot;
22596    pub use super::BinaryGroundingMap;
22597    pub use super::BindingEntry;
22598    pub use super::BindingsTable;
22599    pub use super::BornRuleVerification;
22600    pub use super::Calibration;
22601    pub use super::CalibrationError;
22602    pub use super::CanonicalTimingPolicy;
22603    pub use super::Certificate;
22604    pub use super::Certified;
22605    pub use super::ChainAuditTrail;
22606    pub use super::CompileTime;
22607    pub use super::CompileUnit;
22608    pub use super::CompileUnitBuilder;
22609    pub use super::CompletenessAuditTrail;
22610    pub use super::CompletenessCertificate;
22611    pub use super::ConstrainedTypeInput;
22612    pub use super::ContentAddress;
22613    pub use super::ContentFingerprint;
22614    pub use super::Datum;
22615    pub use super::DigestGroundingMap;
22616    pub use super::Embed;
22617    pub use super::FragmentMarker;
22618    pub use super::GenericImpossibilityWitness;
22619    pub use super::GeodesicCertificate;
22620    pub use super::GeodesicEvidenceBundle;
22621    pub use super::Grounded;
22622    pub use super::GroundedCoord;
22623    pub use super::GroundedShape;
22624    pub use super::GroundedTuple;
22625    pub use super::GroundedValue;
22626    pub use super::Grounding;
22627    pub use super::GroundingCertificate;
22628    pub use super::GroundingExt;
22629    pub use super::GroundingMapKind;
22630    pub use super::GroundingProgram;
22631    pub use super::Hasher;
22632    pub use super::ImpossibilityWitnessKind;
22633    pub use super::InhabitanceCertificate;
22634    pub use super::InhabitanceImpossibilityWitness;
22635    pub use super::IntegerGroundingMap;
22636    pub use super::Invertible;
22637    pub use super::InvolutionCertificate;
22638    pub use super::IsometryCertificate;
22639    pub use super::JsonGroundingMap;
22640    pub use super::LandauerBudget;
22641    pub use super::LiftChainCertificate;
22642    pub use super::MeasurementCertificate;
22643    pub use super::Mul;
22644    pub use super::Nanos;
22645    pub use super::Neg;
22646    pub use super::OntologyTarget;
22647    pub use super::Or;
22648    pub use super::PipelineFailure;
22649    pub use super::PreservesMetric;
22650    pub use super::PreservesStructure;
22651    pub use super::RingOp;
22652    pub use super::Runtime;
22653    pub use super::ShapeViolation;
22654    pub use super::Sub;
22655    pub use super::Succ;
22656    pub use super::Term;
22657    pub use super::TermArena;
22658    pub use super::TimingPolicy;
22659    pub use super::Total;
22660    pub use super::TransformCertificate;
22661    pub use super::Triad;
22662    pub use super::UnaryRingOp;
22663    pub use super::UorTime;
22664    pub use super::Utf8GroundingMap;
22665    pub use super::ValidLevelEmbedding;
22666    pub use super::Validated;
22667    pub use super::ValidationPhase;
22668    pub use super::Xor;
22669    pub use super::W16;
22670    pub use super::W8;
22671    pub use crate::pipeline::empty_bindings_table;
22672    pub use crate::pipeline::{
22673        validate_constrained_type, validate_constrained_type_const, ConstrainedTypeShape,
22674        ConstraintRef, FragmentKind,
22675    };
22676    pub use crate::{DecimalTranscendental, DefaultHostTypes, HostTypes, WittLevel};
22677}