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/// // ADR-060: `Sinking` and `Grounded` carry an `INLINE_BYTES`
806/// // const-generic the application derives from its `HostBounds`; this
807/// // example fixes a concrete width.
808/// const N: usize = 32;
809/// struct MyJsonSink;
810///
811/// impl Sinking<N> for MyJsonSink {
812///     type Source = ConstrainedTypeInput;
813///     type ProjectionMap = Utf8ProjectionMap;
814///     type Output = String;
815///
816///     fn project(&self, grounded: &Grounded<ConstrainedTypeInput, N>) -> String {
817///         format!("{:?}", grounded.unit_address())
818///     }
819/// }
820/// ```
821pub trait Sinking<const INLINE_BYTES: usize> {
822    /// The ring-side shape `T` carried by the `Grounded<T>` being projected.
823    /// Sealed via `GroundedShape` — downstream cannot forge an admissible Source.
824    type Source: GroundedShape;
825
826    /// The ontology-declared ProjectionMap kind this impl serves. Sealed to
827    /// the closed set of `morphism:ProjectionMap` individuals.
828    type ProjectionMap: ProjectionMapKind;
829
830    /// The host-side output type of this projection. Intentionally generic —
831    /// downstream chooses `String`, `Vec<u8>`, `serde_json::Value`, or any
832    /// host-appropriate carrier.
833    type Output;
834
835    /// Project a grounded ring value to the host output. The `&Grounded<Source>`
836    /// input is unforgeable (Grounded is sealed per §2) — no raw data can be
837    /// laundered through this contract.
838    fn project(&self, grounded: &Grounded<'_, Self::Source, INLINE_BYTES>) -> Self::Output;
839}
840
841/// Target §4.6: extension trait tying `EmitEffect<H>` (ontology-declarative)
842/// to `Sinking` (Rust-operational). Emit-effect implementations carry a
843/// specific `Sinking` impl; the emit operation threads a sealed
844/// `Grounded<Source>` through the projection.
845pub trait EmitThrough<const INLINE_BYTES: usize, H: crate::HostTypes>:
846    crate::bridge::boundary::EmitEffect<H>
847{
848    /// The `Sinking` implementation this emit-effect routes through.
849    type Sinking: Sinking<INLINE_BYTES>;
850
851    /// Emit a grounded value through this effect's bound `Sinking`. The
852    /// input type is the sealed `Grounded<Source>` of the bound `Sinking`;
853    /// nothing else is admissible.
854    fn emit(
855        &self,
856        grounded: &Grounded<'_, <Self::Sinking as Sinking<INLINE_BYTES>>::Source, INLINE_BYTES>,
857    ) -> <Self::Sinking as Sinking<INLINE_BYTES>>::Output;
858}
859
860/// v0.2.2 W13: sealed marker trait for the validation phase at which a
861/// `Validated<T, Phase>` was witnessed. Implemented only by `CompileTime`
862/// and `Runtime`; downstream cannot extend.
863pub trait ValidationPhase: validation_phase_sealed::Sealed {}
864
865mod validation_phase_sealed {
866    /// Private supertrait. Not implementable outside this crate.
867    pub trait Sealed {}
868    impl Sealed for super::CompileTime {}
869    impl Sealed for super::Runtime {}
870}
871
872/// v0.2.2 W13: marker for compile-time validated witnesses produced by
873/// `validate_const()` and usable in `const` contexts. Convertible to
874/// `Validated<T, Runtime>` via `From`.
875#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
876pub struct CompileTime;
877impl ValidationPhase for CompileTime {}
878
879/// v0.2.2 W13: marker for runtime-validated witnesses produced by
880/// `validate()`. The default phase of `Validated<T>` so v0.2.1 call
881/// sites continue to compile.
882#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
883pub struct Runtime;
884impl ValidationPhase for Runtime {}
885
886/// Proof that a value was produced by the conformance checker,
887/// not fabricated by Prism code.
888/// The inner value and `_sealed` field are private, so `Validated<T>`
889/// can only be constructed within this crate.
890/// v0.2.2 W13: parameterized by a `Phase: ValidationPhase` discriminator.
891/// `Validated<T, CompileTime>` was witnessed by `validate_const()` and is
892/// usable in const contexts. `Validated<T, Runtime>` (the default) was
893/// witnessed by `validate()`. A `CompileTime` witness is convertible to
894/// a `Runtime` witness via `From`.
895/// # Examples
896/// ```no_run
897/// use uor_foundation::enforcement::{CompileUnitBuilder, ConstrainedTypeInput, Term};
898/// use uor_foundation::{WittLevel, VerificationDomain};
899///
900/// // Validated<T> proves that a value passed conformance checking.
901/// // You cannot construct one directly — only builder validate() methods
902/// // and the minting boundary produce them.
903/// // ADR-060: `Term` carries an `INLINE_BYTES` const-generic the
904/// // application derives from its `HostBounds`; fix a concrete width.
905/// const N: usize = 32;
906/// let terms: [Term<'static, N>; 1] =
907///     [uor_foundation::pipeline::literal_u64(1, WittLevel::W8)];
908/// let domains = [VerificationDomain::Enumerative];
909///
910/// let validated = CompileUnitBuilder::new()
911///     .root_term(&terms)
912///     .witt_level_ceiling(WittLevel::W8)
913///     .thermodynamic_budget(1024)
914///     .target_domains(&domains)
915///     .result_type::<ConstrainedTypeInput>()
916///     .validate()
917///     .expect("all fields set");
918///
919/// // Access the inner value through the proof wrapper:
920/// let _compile_unit = validated.inner();
921/// ```
922#[derive(Debug, Clone, PartialEq, Eq)]
923pub struct Validated<T, Phase: ValidationPhase = Runtime> {
924    /// The validated inner value.
925    inner: T,
926    /// Phantom marker for the validation phase (`CompileTime` or `Runtime`).
927    _phase: PhantomData<Phase>,
928    /// Prevents external construction.
929    _sealed: (),
930}
931
932impl<T, Phase: ValidationPhase> Validated<T, Phase> {
933    /// Returns a reference to the validated inner value.
934    #[inline]
935    #[must_use]
936    pub const fn inner(&self) -> &T {
937        &self.inner
938    }
939
940    /// Creates a new `Validated<T, Phase>` wrapper. Only callable within the crate.
941    #[inline]
942    #[allow(dead_code)]
943    pub(crate) const fn new(inner: T) -> Self {
944        Self {
945            inner,
946            _phase: PhantomData,
947            _sealed: (),
948        }
949    }
950}
951
952/// v0.2.2 W13: a compile-time witness is usable wherever a runtime witness is required.
953impl<T> From<Validated<T, CompileTime>> for Validated<T, Runtime> {
954    #[inline]
955    fn from(value: Validated<T, CompileTime>) -> Self {
956        Self {
957            inner: value.inner,
958            _phase: PhantomData,
959            _sealed: (),
960        }
961    }
962}
963
964/// An opaque derivation trace that can only be extended by the rewrite engine.
965/// Records the rewrite-step count, the source `witt_level_bits`, and the
966/// parametric `content_fingerprint`. Private fields prevent external
967/// construction; produced exclusively by `Grounded::derivation()` so the
968/// verify path can re-derive the source certificate via
969/// `Derivation::replay() -> Trace -> verify_trace`.
970#[derive(Debug, Clone, PartialEq, Eq)]
971pub struct Derivation<const FP_MAX: usize = 32> {
972    /// Number of rewrite steps in this derivation.
973    step_count: u32,
974    /// v0.2.2 T5: Witt level the source grounding was minted at. Carried
975    /// through replay so the verifier can reconstruct the certificate.
976    witt_level_bits: u16,
977    /// v0.2.2 T5: parametric content fingerprint of the source unit's
978    /// full state, computed at grounding time by the consumer-supplied
979    /// `Hasher`. Carried through replay so the verifier can reproduce
980    /// the source certificate via passthrough.
981    content_fingerprint: ContentFingerprint<FP_MAX>,
982}
983
984impl<const FP_MAX: usize> Derivation<FP_MAX> {
985    /// Returns the number of rewrite steps.
986    #[inline]
987    #[must_use]
988    pub const fn step_count(&self) -> u32 {
989        self.step_count
990    }
991
992    /// v0.2.2 T5: returns the Witt level the source grounding was minted at.
993    #[inline]
994    #[must_use]
995    pub const fn witt_level_bits(&self) -> u16 {
996        self.witt_level_bits
997    }
998
999    /// v0.2.2 T5: returns the parametric content fingerprint of the source
1000    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
1001    #[inline]
1002    #[must_use]
1003    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
1004        self.content_fingerprint
1005    }
1006
1007    /// Creates a new derivation. Only callable within the crate.
1008    #[inline]
1009    #[must_use]
1010    #[allow(dead_code)]
1011    pub(crate) const fn new(
1012        step_count: u32,
1013        witt_level_bits: u16,
1014        content_fingerprint: ContentFingerprint<FP_MAX>,
1015    ) -> Self {
1016        Self {
1017            step_count,
1018            witt_level_bits,
1019            content_fingerprint,
1020        }
1021    }
1022}
1023
1024/// An opaque free rank that can only be decremented by `PinningEffect`
1025/// and incremented by `UnbindingEffect` \[never by direct mutation\].
1026#[derive(Debug, Clone, PartialEq, Eq)]
1027pub struct FreeRank {
1028    /// Total site capacity at the Witt level.
1029    total: u32,
1030    /// Currently pinned sites.
1031    pinned: u32,
1032}
1033
1034impl FreeRank {
1035    /// Returns the total site capacity.
1036    #[inline]
1037    #[must_use]
1038    pub const fn total(&self) -> u32 {
1039        self.total
1040    }
1041
1042    /// Returns the number of currently pinned sites.
1043    #[inline]
1044    #[must_use]
1045    pub const fn pinned(&self) -> u32 {
1046        self.pinned
1047    }
1048
1049    /// Returns the number of remaining (unpinned) sites.
1050    #[inline]
1051    #[must_use]
1052    pub const fn remaining(&self) -> u32 {
1053        self.total - self.pinned
1054    }
1055
1056    /// Creates a new free rank. Only callable within the crate.
1057    #[inline]
1058    #[allow(dead_code)]
1059    pub(crate) const fn new(total: u32, pinned: u32) -> Self {
1060        Self { total, pinned }
1061    }
1062}
1063
1064/// v0.2.2 Phase A: sealed `H::Decimal`-backed newtype carrying the
1065/// `observable:LandauerCost` accumulator in `observable:Nats`.
1066/// Monotonic within a pipeline invocation. The UOR ring operates
1067/// at the Landauer temperature (β* = ln 2), so this observable is
1068/// a direct measure of irreversible bit-erasure performed.
1069/// Phase 9: parameterized over `H: HostTypes` so the underlying
1070/// decimal type tracks the host's chosen precision.
1071#[derive(Debug)]
1072pub struct LandauerBudget<H: HostTypes = crate::DefaultHostTypes> {
1073    /// Accumulated Landauer cost in nats. Non-negative, finite.
1074    nats: H::Decimal,
1075    /// Phantom marker pinning the host type.
1076    _phantom: core::marker::PhantomData<H>,
1077    /// Prevents external construction.
1078    _sealed: (),
1079}
1080
1081impl<H: HostTypes> LandauerBudget<H> {
1082    /// Returns the accumulated Landauer cost in nats.
1083    #[inline]
1084    #[must_use]
1085    pub const fn nats(&self) -> H::Decimal {
1086        self.nats
1087    }
1088
1089    /// Crate-internal constructor. Caller guarantees `nats` is
1090    /// non-negative and finite (i.e. not NaN, not infinite).
1091    #[inline]
1092    #[must_use]
1093    #[allow(dead_code)]
1094    pub(crate) const fn new(nats: H::Decimal) -> Self {
1095        Self {
1096            nats,
1097            _phantom: core::marker::PhantomData,
1098            _sealed: (),
1099        }
1100    }
1101
1102    /// Crate-internal constructor for the zero-cost initial budget.
1103    #[inline]
1104    #[must_use]
1105    #[allow(dead_code)]
1106    pub(crate) const fn zero() -> Self {
1107        Self {
1108            nats: H::EMPTY_DECIMAL,
1109            _phantom: core::marker::PhantomData,
1110            _sealed: (),
1111        }
1112    }
1113}
1114
1115impl<H: HostTypes> Copy for LandauerBudget<H> {}
1116impl<H: HostTypes> Clone for LandauerBudget<H> {
1117    #[inline]
1118    fn clone(&self) -> Self {
1119        *self
1120    }
1121}
1122impl<H: HostTypes> PartialEq for LandauerBudget<H> {
1123    #[inline]
1124    fn eq(&self, other: &Self) -> bool {
1125        self.nats == other.nats
1126    }
1127}
1128impl<H: HostTypes> Eq for LandauerBudget<H> {}
1129impl<H: HostTypes> PartialOrd for LandauerBudget<H> {
1130    #[inline]
1131    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1132        Some(self.cmp(other))
1133    }
1134}
1135impl<H: HostTypes> Ord for LandauerBudget<H> {
1136    #[inline]
1137    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1138        // Total order on H::Decimal with NaN excluded by construction.
1139        self.nats
1140            .partial_cmp(&other.nats)
1141            .unwrap_or(core::cmp::Ordering::Equal)
1142    }
1143}
1144impl<H: HostTypes> core::hash::Hash for LandauerBudget<H> {
1145    #[inline]
1146    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
1147        // DecimalTranscendental::to_bits gives a stable u64 fingerprint
1148        // for any in-range Decimal value.
1149        self.nats.to_bits().hash(state);
1150    }
1151}
1152
1153/// v0.2.2 Phase A: foundation-internal deterministic two-clock value
1154/// carried by every `Grounded<T>` and `Certified<C>`. The two clocks are
1155/// `landauer_nats` (a `LandauerBudget` value backed by `observable:LandauerCost`)
1156/// and `rewrite_steps` (a `u64` backed by `derivation:stepCount` on
1157/// `derivation:TermMetrics`). Each clock is monotonic within a pipeline
1158/// invocation, content-deterministic, ontology-grounded, and binds to a
1159/// physical wall-clock lower bound through established physics (Landauer's
1160/// principle for nats; Margolus-Levitin for rewrite steps). Two clocks
1161/// because exactly two physical lower-bound theorems are grounded; adding
1162/// a third clock would require grounding a third physical theorem.
1163/// `PartialOrd` is component-wise: `a < b` iff every field of `a` is `<=`
1164/// the corresponding field of `b` and at least one is strictly `<`. Two
1165/// `UorTime` values from unrelated computations are genuinely incomparable,
1166/// so `UorTime` is `PartialOrd` but **not** `Ord`.
1167#[derive(Debug)]
1168pub struct UorTime<H: HostTypes = crate::DefaultHostTypes> {
1169    /// Landauer budget consumed, in `observable:Nats`.
1170    landauer_nats: LandauerBudget<H>,
1171    /// Total rewrite steps taken (`derivation:stepCount`).
1172    rewrite_steps: u64,
1173    /// Prevents external construction.
1174    _sealed: (),
1175}
1176
1177impl<H: HostTypes> UorTime<H> {
1178    /// Returns the Landauer budget consumed, in `observable:Nats`.
1179    /// Maps to `observable:LandauerCost`.
1180    #[inline]
1181    #[must_use]
1182    pub const fn landauer_nats(&self) -> LandauerBudget<H> {
1183        self.landauer_nats
1184    }
1185
1186    /// Returns the total rewrite steps taken.
1187    /// Maps to `derivation:stepCount` on `derivation:TermMetrics`.
1188    #[inline]
1189    #[must_use]
1190    pub const fn rewrite_steps(&self) -> u64 {
1191        self.rewrite_steps
1192    }
1193
1194    /// Crate-internal constructor. Reachable only from the pipeline at witness mint time.
1195    #[inline]
1196    #[must_use]
1197    #[allow(dead_code)]
1198    pub(crate) const fn new(landauer_nats: LandauerBudget<H>, rewrite_steps: u64) -> Self {
1199        Self {
1200            landauer_nats,
1201            rewrite_steps,
1202            _sealed: (),
1203        }
1204    }
1205
1206    /// Crate-internal constructor for the zero initial value.
1207    #[inline]
1208    #[must_use]
1209    #[allow(dead_code)]
1210    pub(crate) const fn zero() -> Self {
1211        Self {
1212            landauer_nats: LandauerBudget::<H>::zero(),
1213            rewrite_steps: 0,
1214            _sealed: (),
1215        }
1216    }
1217
1218    /// Returns the provable minimum wall-clock duration that the
1219    /// computation producing this witness could have taken under the
1220    /// given calibration. Returns `max(Landauer-bound, Margolus-Levitin-bound)`.
1221    /// The Landauer bound is `landauer_nats × k_B·T / thermal_power`.
1222    /// The Margolus-Levitin bound is `π·ℏ·rewrite_steps / (2·characteristic_energy)`.
1223    /// Pure arithmetic — no transcendentals, no state. Const-evaluable
1224    /// where the `UorTime` value is known at compile time.
1225    #[inline]
1226    #[must_use]
1227    pub fn min_wall_clock(&self, cal: &Calibration<H>) -> Nanos {
1228        // Landauer bound: nats × k_B·T / thermal_power = seconds.
1229        let landauer_seconds = self.landauer_nats.nats() * cal.k_b_t() / cal.thermal_power();
1230        // Margolus-Levitin bound: π·ℏ / (2·E) per orthogonal state transition.
1231        // π·ℏ ≈ 3.31194e-34 J·s; encoded as the f64 bit pattern of
1232        // `core::f64::consts::PI * 1.054_571_817e-34` so the constant is
1233        // representable across host Decimal types.
1234        let pi_times_h_bar =
1235            <H::Decimal as DecimalTranscendental>::from_bits(crate::PI_TIMES_H_BAR_BITS);
1236        let two = <H::Decimal as DecimalTranscendental>::from_u32(2);
1237        let ml_seconds_per_step = pi_times_h_bar / (two * cal.characteristic_energy());
1238        let steps = <H::Decimal as DecimalTranscendental>::from_u64(self.rewrite_steps);
1239        let ml_seconds = ml_seconds_per_step * steps;
1240        let max_seconds = if landauer_seconds > ml_seconds {
1241            landauer_seconds
1242        } else {
1243            ml_seconds
1244        };
1245        // Convert seconds to nanoseconds, saturate on overflow.
1246        let nanos_per_second =
1247            <H::Decimal as DecimalTranscendental>::from_bits(crate::NANOS_PER_SECOND_BITS);
1248        let nanos = max_seconds * nanos_per_second;
1249        Nanos {
1250            ns: <H::Decimal as DecimalTranscendental>::as_u64_saturating(nanos),
1251            _sealed: (),
1252        }
1253    }
1254}
1255
1256impl<H: HostTypes> Copy for UorTime<H> {}
1257impl<H: HostTypes> Clone for UorTime<H> {
1258    #[inline]
1259    fn clone(&self) -> Self {
1260        *self
1261    }
1262}
1263impl<H: HostTypes> PartialEq for UorTime<H> {
1264    #[inline]
1265    fn eq(&self, other: &Self) -> bool {
1266        self.landauer_nats == other.landauer_nats && self.rewrite_steps == other.rewrite_steps
1267    }
1268}
1269impl<H: HostTypes> Eq for UorTime<H> {}
1270impl<H: HostTypes> core::hash::Hash for UorTime<H> {
1271    #[inline]
1272    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
1273        self.landauer_nats.hash(state);
1274        self.rewrite_steps.hash(state);
1275    }
1276}
1277impl<H: HostTypes> PartialOrd for UorTime<H> {
1278    #[inline]
1279    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1280        let l = self.landauer_nats.cmp(&other.landauer_nats);
1281        let r = self.rewrite_steps.cmp(&other.rewrite_steps);
1282        match (l, r) {
1283            (core::cmp::Ordering::Equal, core::cmp::Ordering::Equal) => {
1284                Some(core::cmp::Ordering::Equal)
1285            }
1286            (core::cmp::Ordering::Less, core::cmp::Ordering::Less)
1287            | (core::cmp::Ordering::Less, core::cmp::Ordering::Equal)
1288            | (core::cmp::Ordering::Equal, core::cmp::Ordering::Less) => {
1289                Some(core::cmp::Ordering::Less)
1290            }
1291            (core::cmp::Ordering::Greater, core::cmp::Ordering::Greater)
1292            | (core::cmp::Ordering::Greater, core::cmp::Ordering::Equal)
1293            | (core::cmp::Ordering::Equal, core::cmp::Ordering::Greater) => {
1294                Some(core::cmp::Ordering::Greater)
1295            }
1296            _ => None,
1297        }
1298    }
1299}
1300
1301/// v0.2.2 Phase A: sealed lower-bound carrier for wall-clock duration.
1302/// Produced only by `UorTime::min_wall_clock` and similar foundation
1303/// time conversions. The sealing guarantees that any `Nanos` value is
1304/// a provable physical bound, not a raw integer. Developers who need
1305/// the underlying `u64` call `.as_u64()`; the sealing prevents
1306/// accidentally passing a host-measured duration where the type system
1307/// expects "a provable minimum".
1308#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1309pub struct Nanos {
1310    /// The provable lower-bound duration in nanoseconds.
1311    ns: u64,
1312    /// Prevents external construction.
1313    _sealed: (),
1314}
1315
1316impl Nanos {
1317    /// Returns the underlying nanosecond count. The value is a provable
1318    /// physical lower bound under whatever calibration produced it.
1319    #[inline]
1320    #[must_use]
1321    pub const fn as_u64(self) -> u64 {
1322        self.ns
1323    }
1324}
1325
1326/// v0.2.2 Phase A: error returned by `Calibration::new` when the supplied
1327/// physical parameters fail plausibility validation.
1328#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1329pub enum CalibrationError {
1330    /// `k_b_t` was non-positive, NaN, or outside the known-universe
1331    /// temperature range (`1e-30 ≤ k_b_t ≤ 1e-15` joules).
1332    ThermalEnergy,
1333    /// `thermal_power` was non-positive, NaN, or above the thermodynamic maximum (`1e9` W).
1334    ThermalPower,
1335    /// `characteristic_energy` was non-positive, NaN, or above the
1336    /// k_B·T × Avogadro-class bound (`1e3` joules).
1337    CharacteristicEnergy,
1338}
1339
1340impl core::fmt::Display for CalibrationError {
1341    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1342        match self {
1343            Self::ThermalEnergy => {
1344                f.write_str("calibration k_b_t out of range (must be in [1e-30, 1e-15] joules)")
1345            }
1346            Self::ThermalPower => {
1347                f.write_str("calibration thermal_power out of range (must be > 0 and <= 1e9 W)")
1348            }
1349            Self::CharacteristicEnergy => f.write_str(
1350                "calibration characteristic_energy out of range (must be > 0 and <= 1e3 J)",
1351            ),
1352        }
1353    }
1354}
1355
1356impl core::error::Error for CalibrationError {}
1357
1358/// v0.2.2 Phase A: physical-substrate calibration for wall-clock binding.
1359/// Construction is open via [`Calibration::new`], but the fields are
1360/// private and validated for physical plausibility. Used to convert
1361/// `UorTime` to a provable wall-clock lower bound via
1362/// [`UorTime::min_wall_clock`].
1363/// **A `Calibration` is never passed into `pipeline::run`,
1364/// `resolver::*::certify`, `validate_const`, or any other foundation entry
1365/// point.** The foundation computes `UorTime` without physical
1366/// interpretation; the developer applies a `Calibration` after the fact.
1367#[derive(Debug)]
1368pub struct Calibration<H: HostTypes = crate::DefaultHostTypes> {
1369    /// Boltzmann constant times temperature, in joules.
1370    k_b_t: H::Decimal,
1371    /// Sustained dissipation in watts.
1372    thermal_power: H::Decimal,
1373    /// Mean energy above ground state, in joules.
1374    characteristic_energy: H::Decimal,
1375    /// Phantom marker pinning the host type.
1376    _phantom: core::marker::PhantomData<H>,
1377}
1378
1379impl<H: HostTypes> Copy for Calibration<H> {}
1380impl<H: HostTypes> Clone for Calibration<H> {
1381    #[inline]
1382    fn clone(&self) -> Self {
1383        *self
1384    }
1385}
1386impl<H: HostTypes> PartialEq for Calibration<H> {
1387    #[inline]
1388    fn eq(&self, other: &Self) -> bool {
1389        self.k_b_t == other.k_b_t
1390            && self.thermal_power == other.thermal_power
1391            && self.characteristic_energy == other.characteristic_energy
1392    }
1393}
1394
1395impl<H: HostTypes> Calibration<H> {
1396    /// Construct a calibration with physically plausible parameters.
1397    /// Validation: every parameter must be positive and finite. `k_b_t`
1398    /// must lie within the known-universe temperature range
1399    /// (`1e-30 <= k_b_t <= 1e-15` joules covers ~1 nK to ~1e8 K).
1400    /// `thermal_power` must be at most `1e9` W (gigawatt class — far above
1401    /// any plausible single-compute envelope). `characteristic_energy`
1402    /// must be at most `1e3` J (kilojoule class — astronomically generous).
1403    /// # Errors
1404    /// Returns `CalibrationError::InvalidThermalEnergy` when `k_b_t` is
1405    /// non-positive, NaN, or outside the temperature range.
1406    /// Returns `CalibrationError::InvalidThermalPower` when `thermal_power`
1407    /// is non-positive, NaN, or above the maximum.
1408    /// Returns `CalibrationError::InvalidCharacteristicEnergy` when
1409    /// `characteristic_energy` is non-positive, NaN, or above the maximum.
1410    /// # Example
1411    /// ```
1412    /// use uor_foundation::enforcement::Calibration;
1413    /// use uor_foundation::DefaultHostTypes;
1414    /// // X86 server-class envelope at room temperature.
1415    /// // k_B·T at 300 K = 4.14e-21 J; 85 W sustained TDP; ~1e-15 J/op.
1416    /// let cal = Calibration::<DefaultHostTypes>::new(4.14e-21, 85.0, 1.0e-15)
1417    ///     .expect("physically plausible server calibration");
1418    /// # let _ = cal;
1419    /// ```
1420    #[inline]
1421    pub fn new(
1422        k_b_t: H::Decimal,
1423        thermal_power: H::Decimal,
1424        characteristic_energy: H::Decimal,
1425    ) -> Result<Self, CalibrationError> {
1426        // Bit-pattern bounds for the validation envelope. Reading them
1427        // through `from_bits` lets the host's chosen Decimal precision
1428        // resolve the comparison without any hardcoded f64 in source.
1429        let zero = <H::Decimal as Default>::default();
1430        let kbt_lo =
1431            <H::Decimal as DecimalTranscendental>::from_bits(crate::CALIBRATION_KBT_LO_BITS);
1432        let kbt_hi =
1433            <H::Decimal as DecimalTranscendental>::from_bits(crate::CALIBRATION_KBT_HI_BITS);
1434        let tp_hi = <H::Decimal as DecimalTranscendental>::from_bits(
1435            crate::CALIBRATION_THERMAL_POWER_HI_BITS,
1436        );
1437        let ce_hi = <H::Decimal as DecimalTranscendental>::from_bits(
1438            crate::CALIBRATION_CHAR_ENERGY_HI_BITS,
1439        );
1440        // NaN identity: NaN != NaN. PartialEq is the defining bound.
1441        #[allow(clippy::eq_op)]
1442        let k_b_t_nan = k_b_t != k_b_t;
1443        if k_b_t_nan || k_b_t <= zero || k_b_t < kbt_lo || k_b_t > kbt_hi {
1444            return Err(CalibrationError::ThermalEnergy);
1445        }
1446        #[allow(clippy::eq_op)]
1447        let tp_nan = thermal_power != thermal_power;
1448        if tp_nan || thermal_power <= zero || thermal_power > tp_hi {
1449            return Err(CalibrationError::ThermalPower);
1450        }
1451        #[allow(clippy::eq_op)]
1452        let ce_nan = characteristic_energy != characteristic_energy;
1453        if ce_nan || characteristic_energy <= zero || characteristic_energy > ce_hi {
1454            return Err(CalibrationError::CharacteristicEnergy);
1455        }
1456        Ok(Self {
1457            k_b_t,
1458            thermal_power,
1459            characteristic_energy,
1460            _phantom: core::marker::PhantomData,
1461        })
1462    }
1463
1464    /// Returns the Boltzmann constant times temperature, in joules.
1465    #[inline]
1466    #[must_use]
1467    pub const fn k_b_t(&self) -> H::Decimal {
1468        self.k_b_t
1469    }
1470
1471    /// Returns the sustained thermal power dissipation, in watts.
1472    #[inline]
1473    #[must_use]
1474    pub const fn thermal_power(&self) -> H::Decimal {
1475        self.thermal_power
1476    }
1477
1478    /// Returns the characteristic energy above ground state, in joules.
1479    #[inline]
1480    #[must_use]
1481    pub const fn characteristic_energy(&self) -> H::Decimal {
1482        self.characteristic_energy
1483    }
1484
1485    /// v0.2.2 T5.5: zero sentinel. All three fields are 0.0 — physically
1486    /// meaningless but safely constructible. Used as the unreachable-branch
1487    /// placeholder in the const-context preset literals (`X86_SERVER`,
1488    /// `ARM_MOBILE`, `CORTEX_M_EMBEDDED`, `CONSERVATIVE_WORST_CASE`). The
1489    /// `meta/calibration_presets_valid` conformance check verifies the
1490    /// preset literals always succeed in `Calibration::new`, so this
1491    /// sentinel is never produced in practice. Do not use it directly;
1492    /// it is exposed only because Rust's const-eval needs a fallback for
1493    /// the impossible `Err` arm of the preset match.
1494    pub const ZERO_SENTINEL: Calibration<H> = Self {
1495        k_b_t: H::EMPTY_DECIMAL,
1496        thermal_power: H::EMPTY_DECIMAL,
1497        characteristic_energy: H::EMPTY_DECIMAL,
1498        _phantom: core::marker::PhantomData,
1499    };
1500}
1501
1502impl Calibration<crate::DefaultHostTypes> {
1503    /// 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.
1504    #[inline]
1505    #[must_use]
1506    pub(crate) const fn from_f64_unchecked(
1507        k_b_t: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1508        thermal_power: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1509        characteristic_energy: <crate::DefaultHostTypes as crate::HostTypes>::Decimal,
1510    ) -> Self {
1511        Self {
1512            k_b_t,
1513            thermal_power,
1514            characteristic_energy,
1515            _phantom: core::marker::PhantomData,
1516        }
1517    }
1518}
1519
1520/// v0.2.2 Phase A: foundation-shipped preset calibrations covering common
1521/// substrates. The values are derived from published substrate thermals at
1522/// T=300 K (room temperature, where k_B·T ≈ 4.14e-21 J).
1523pub mod calibrations {
1524    use super::Calibration;
1525    use crate::DefaultHostTypes;
1526
1527    /// Server-class x86 (Xeon/EPYC sustained envelope).
1528    /// k_B·T = 4.14e-21 J (T = 300 K), thermal_power = 85 W (typical TDP),
1529    /// characteristic_energy = 1e-15 J/op (~1 fJ/op for modern CMOS).
1530    pub const X86_SERVER: Calibration<DefaultHostTypes> =
1531        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 85.0, 1.0e-15);
1532
1533    /// Mobile ARM SoC (Apple M-series, Snapdragon 8-series sustained envelope).
1534    /// k_B·T = 4.14e-21 J, thermal_power = 5 W, characteristic_energy = 1e-16 J/op.
1535    pub const ARM_MOBILE: Calibration<DefaultHostTypes> =
1536        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 5.0, 1.0e-16);
1537
1538    /// Cortex-M embedded (STM32/nRF52 at 80 MHz).
1539    /// k_B·T = 4.14e-21 J, thermal_power = 0.1 W, characteristic_energy = 1e-17 J/op.
1540    pub const CORTEX_M_EMBEDDED: Calibration<DefaultHostTypes> =
1541        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 0.1, 1.0e-17);
1542
1543    /// The tightest provable lower bound that requires no trust in the
1544    /// issuer's claimed substrate. Values are physically sound but maximally
1545    /// generous: k_B·T at 300 K floor, thermal_power at 1 GW (above any
1546    /// plausible single-compute envelope), characteristic_energy at 1 J
1547    /// (astronomically generous).
1548    /// Applying this calibration yields the smallest `Nanos` physically
1549    /// possible for the computation regardless of substrate claims.
1550    pub const CONSERVATIVE_WORST_CASE: Calibration<DefaultHostTypes> =
1551        Calibration::<DefaultHostTypes>::from_f64_unchecked(4.14e-21, 1.0e9, 1.0);
1552}
1553
1554/// v0.2.2 Phase B (target §1.7): timing-policy carrier. Parametric over host tuning.
1555/// Supplies the preflight / runtime Nanos budgets (canonical values from
1556/// `reduction:PreflightTimingBound` and `reduction:RuntimeTimingBound`) plus
1557/// the `Calibration` used to convert an input's a-priori `UorTime` estimate
1558/// into a Nanos lower bound for comparison against the budget.
1559/// The foundation-canonical default [`CanonicalTimingPolicy`] uses
1560/// `calibrations::CONSERVATIVE_WORST_CASE` (the tightest provable lower-bound
1561/// calibration) and the 10 ms budget from the ontology. Host code overrides by
1562/// implementing `TimingPolicy` on a marker struct and substituting at the
1563/// preflight-function call site.
1564pub trait TimingPolicy {
1565    /// Preflight Nanos budget. Inputs whose a-priori UorTime → min_wall_clock
1566    /// under `Self::CALIBRATION` exceeds this value are rejected at preflight.
1567    const PREFLIGHT_BUDGET_NS: u64;
1568    /// Runtime Nanos budget for post-admission reduction.
1569    const RUNTIME_BUDGET_NS: u64;
1570    /// Canonical Calibration used to convert a-priori UorTime estimates to Nanos.
1571    /// 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`.
1572    const CALIBRATION: &'static Calibration<crate::DefaultHostTypes>;
1573}
1574
1575/// v0.2.2 Phase B: foundation-canonical [`TimingPolicy`]. Budget values mirror
1576/// `reduction:PreflightTimingBound` and `reduction:RuntimeTimingBound`; calibration
1577/// is `calibrations::CONSERVATIVE_WORST_CASE` so the Nanos lower bound from any
1578/// input UorTime is the tightest physically-defensible value.
1579#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1580pub struct CanonicalTimingPolicy;
1581
1582impl TimingPolicy for CanonicalTimingPolicy {
1583    const PREFLIGHT_BUDGET_NS: u64 = 10_000_000;
1584    const RUNTIME_BUDGET_NS: u64 = 10_000_000;
1585    const CALIBRATION: &'static Calibration<crate::DefaultHostTypes> =
1586        &calibrations::CONSERVATIVE_WORST_CASE;
1587}
1588
1589/// Phase H (target §1.6): foundation-owned transcendental-arithmetic entry points.
1590/// Routes through the always-on `libm` dependency so every build — std, alloc,
1591/// and strict no_std — has access to `ln` / `exp` / `sqrt` for `xsd:decimal`
1592/// observables. Gating these behind an optional feature flag was considered and
1593/// rejected per target §1.6: an observable that exists in one build and not
1594/// another violates the foundation's "one surface" discipline.
1595/// Downstream code that needs transcendentals should call these wrappers —
1596/// they are the canonical entry point for the four observables target §3 enumerates
1597/// (`convergenceRate`, `residualEntropy`, `collapseAmplitude`, and `op:OA_5` pricing)
1598/// and for any future observable whose implementation admits transcendentals.
1599pub mod transcendentals {
1600    use crate::DecimalTranscendental;
1601
1602    /// Natural logarithm. Dispatches via `DecimalTranscendental::ln`; the foundation's f64 / f32 impls route through `libm::log` / `logf`.
1603    /// Returns `NaN` for `x <= 0.0`, preserving `libm`'s contract.
1604    #[inline]
1605    #[must_use]
1606    pub fn ln<D: DecimalTranscendental>(x: D) -> D {
1607        x.ln()
1608    }
1609
1610    /// Exponential `e^x`. Dispatches via `DecimalTranscendental::exp`.
1611    #[inline]
1612    #[must_use]
1613    pub fn exp<D: DecimalTranscendental>(x: D) -> D {
1614        x.exp()
1615    }
1616
1617    /// Square root. Dispatches via `DecimalTranscendental::sqrt`. Returns `NaN` for `x < 0.0`.
1618    #[inline]
1619    #[must_use]
1620    pub fn sqrt<D: DecimalTranscendental>(x: D) -> D {
1621        x.sqrt()
1622    }
1623
1624    /// Shannon entropy term `-p · ln(p)` in nats. Returns 0 for `p = 0` by
1625    /// continuous extension. Used by `observable:residualEntropy`.
1626    #[inline]
1627    #[must_use]
1628    pub fn entropy_term_nats<D: DecimalTranscendental>(p: D) -> D {
1629        let zero = <D as Default>::default();
1630        if p <= zero {
1631            zero
1632        } else {
1633            zero - p * p.ln()
1634        }
1635    }
1636}
1637
1638/// Fixed-capacity term list for `#![no_std]`. Indices into a `TermArena`.
1639#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1640pub struct TermList {
1641    /// Start index in the arena.
1642    pub start: u32,
1643    /// Number of terms in this list.
1644    pub len: u32,
1645}
1646
1647/// Stack-resident arena for `Term` trees.
1648/// Fixed capacity determined by the const generic `CAP`.
1649/// All `Term` child references are `u32` indices into this arena.
1650/// `#![no_std]`-safe: no heap allocation.
1651/// # Examples
1652/// ```rust
1653/// use uor_foundation::enforcement::{TermArena, Term, TermList};
1654/// use uor_foundation::{WittLevel, PrimitiveOp};
1655///
1656/// // Build the expression `add(3, 5)` bottom-up in an arena.
1657/// // ADR-060: `TermArena` carries `<'a, INLINE_BYTES, CAP>`; the
1658/// // application derives `INLINE_BYTES` from its `HostBounds`. Here we
1659/// // fix a concrete inline width `N` and a capacity of 4.
1660/// const N: usize = 32;
1661/// let mut arena = TermArena::<N, 4>::new();
1662///
1663/// // Push leaves first:
1664/// let idx_3 = arena.push(uor_foundation::pipeline::literal_u64(3, WittLevel::W8));
1665/// let idx_5 = arena.push(uor_foundation::pipeline::literal_u64(5, WittLevel::W8));
1666///
1667/// // Push the application node, referencing the leaves by index:
1668/// let idx_add = arena.push(Term::Application {
1669///     operator: PrimitiveOp::Add,
1670///     args: TermList { start: idx_3.unwrap_or(0), len: 2 },
1671/// });
1672///
1673/// assert_eq!(arena.len(), 3);
1674/// // Retrieve a node by index:
1675/// let node = arena.get(idx_add.unwrap_or(0));
1676/// assert!(node.is_some());
1677/// ```
1678#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1679pub struct TermArena<'a, const INLINE_BYTES: usize, const CAP: usize> {
1680    /// Node storage. `None` slots are unused.
1681    nodes: [Option<Term<'a, INLINE_BYTES>>; CAP],
1682    /// Number of allocated nodes.
1683    len: u32,
1684}
1685
1686impl<'a, const INLINE_BYTES: usize, const CAP: usize> TermArena<'a, INLINE_BYTES, CAP> {
1687    /// Creates an empty arena.
1688    #[inline]
1689    #[must_use]
1690    pub const fn new() -> Self {
1691        // v0.2.2 T4.5.a: const-stable on MSRV 1.70 via the `[None; CAP]`
1692        // initializer (Term is Copy as of T4.5.a, so Option<Term> is Copy).
1693        Self {
1694            nodes: [None; CAP],
1695            len: 0,
1696        }
1697    }
1698
1699    /// Push a term into the arena and return its index.
1700    /// # Errors
1701    /// Returns `None` if the arena is full.
1702    #[must_use]
1703    pub fn push(&mut self, term: Term<'a, INLINE_BYTES>) -> Option<u32> {
1704        let idx = self.len;
1705        if (idx as usize) >= CAP {
1706            return None;
1707        }
1708        self.nodes[idx as usize] = Some(term);
1709        self.len = idx + 1;
1710        Some(idx)
1711    }
1712
1713    /// Returns a reference to the term at `index`, or `None` if out of bounds.
1714    #[inline]
1715    #[must_use]
1716    pub fn get(&self, index: u32) -> Option<&Term<'a, INLINE_BYTES>> {
1717        self.nodes
1718            .get(index as usize)
1719            .and_then(|slot| slot.as_ref())
1720    }
1721
1722    /// Returns the number of allocated nodes.
1723    #[inline]
1724    #[must_use]
1725    pub const fn len(&self) -> u32 {
1726        self.len
1727    }
1728
1729    /// Returns `true` if the arena has no allocated nodes.
1730    #[inline]
1731    #[must_use]
1732    pub const fn is_empty(&self) -> bool {
1733        self.len == 0
1734    }
1735
1736    /// v0.2.2 T4.5.b: returns the populated prefix of the arena as a slice.
1737    /// Each entry is `Some(term)` for the populated indices `0..len()`;
1738    /// downstream consumers index into this slice via `TermList::start` and
1739    /// `TermList::len` to walk the children of an Application/Match node.
1740    #[inline]
1741    #[must_use]
1742    pub fn as_slice(&self) -> &[Option<Term<'a, INLINE_BYTES>>] {
1743        &self.nodes[..self.len as usize]
1744    }
1745
1746    /// Wiki ADR-022 D2: const constructor that copies a static term slice
1747    /// into the arena. Used by the `prism_model!` proc-macro to emit a
1748    /// `const ROUTE: TermArena<CAP> = TermArena::from_slice(ROUTE_SLICE)`
1749    /// declaration alongside the model — the `const ROUTE_SLICE` carrying
1750    /// the term tree, this `from_slice` wrapping it into the arena form
1751    /// [`crate::pipeline::run_route`] consumes.
1752    /// `CAP` MUST be at least `slice.len()`; if the slice exceeds the
1753    /// arena's capacity the trailing terms are silently dropped (the
1754    /// `prism_model!` macro emits an arena sized to fit the route's term
1755    /// count plus headroom, so this case is unreachable from the macro's
1756    /// output).
1757    #[inline]
1758    #[must_use]
1759    pub const fn from_slice(slice: &'a [Term<'a, INLINE_BYTES>]) -> Self {
1760        let mut nodes: [Option<Term<'a, INLINE_BYTES>>; CAP] = [None; CAP];
1761        let mut i = 0usize;
1762        while i < slice.len() && i < CAP {
1763            nodes[i] = Some(slice[i]);
1764            i += 1;
1765        }
1766        // Cap at min(slice.len(), CAP) so a too-large slice doesn't
1767        // overrun. The macro emits arena CAP >= slice.len() so the
1768        // truncation branch is unreachable in practice.
1769        #[allow(clippy::cast_possible_truncation)]
1770        let len = if slice.len() > CAP {
1771            CAP as u32
1772        } else {
1773            slice.len() as u32
1774        };
1775        Self { nodes, len }
1776    }
1777}
1778
1779impl<'a, const INLINE_BYTES: usize, const CAP: usize> Default for TermArena<'a, INLINE_BYTES, CAP> {
1780    fn default() -> Self {
1781        Self::new()
1782    }
1783}
1784
1785/// Concrete AST node for the UOR term language.
1786/// Mirrors the EBNF grammar productions. All child references are
1787/// indices into a `TermArena`, keeping the AST stack-resident and
1788/// `#![no_std]`-safe.
1789/// # Examples
1790/// ```rust
1791/// use uor_foundation::enforcement::{Term, TermList};
1792/// use uor_foundation::{WittLevel, PrimitiveOp};
1793///
1794/// // ADR-060: `Term` carries `<'a, const INLINE_BYTES: usize>`. The
1795/// // application instantiates `INLINE_BYTES` from its selected
1796/// // `HostBounds` via `pipeline::carrier_inline_bytes::<B>()`; this
1797/// // example fixes a concrete width.
1798/// const N: usize = 32;
1799///
1800/// // Literal: an integer value tagged with a Witt level.
1801/// let lit: Term<'static, N> =
1802///     uor_foundation::pipeline::literal_u64(42, WittLevel::W8);
1803///
1804/// // Application: an operation applied to arguments.
1805/// // `args` is a TermList { start, len } pointing into a TermArena.
1806/// let app: Term<'static, N> = Term::Application {
1807///     operator: PrimitiveOp::Mul,
1808///     args: TermList { start: 0, len: 2 },
1809/// };
1810///
1811/// // Lift: canonical injection from a lower to a higher Witt level.
1812/// let lift: Term<'static, N> =
1813///     Term::Lift { operand_index: 0, target: WittLevel::new(32) };
1814///
1815/// // Project: canonical surjection from a higher to a lower level.
1816/// let proj: Term<'static, N> =
1817///     Term::Project { operand_index: 0, target: WittLevel::W8 };
1818/// let _ = (lit, app, lift, proj);
1819/// ```
1820#[allow(clippy::large_enum_variant)]
1821#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1822pub enum Term<'a, const INLINE_BYTES: usize> {
1823    /// Integer literal with Witt level annotation. Per ADR-051 the value
1824    /// carrier is a `TermValue` byte sequence whose length matches the declared
1825    /// `level`'s byte width. Use `uor_foundation::pipeline::literal_u64(value, level)`
1826    /// to construct a literal from a `u64` value (the narrow form).
1827    Literal {
1828        /// The literal value as a source-polymorphic carrier (ADR-051 +
1829        /// ADR-060). Inline length equals `level.witt_length() / 8`. Wider
1830        /// widths (W128, W256, …) are natively representable without
1831        /// `Concat` composition.
1832        value: crate::pipeline::TermValue<'a, INLINE_BYTES>,
1833        /// The Witt level of this literal.
1834        level: WittLevel,
1835    },
1836    /// Variable reference by name index.
1837    Variable {
1838        /// Index into the name table.
1839        name_index: u32,
1840    },
1841    /// Operation application: operator applied to arguments.
1842    Application {
1843        /// The primitive operation to apply.
1844        operator: PrimitiveOp,
1845        /// Argument list (indices into arena).
1846        args: TermList,
1847    },
1848    /// Lift: canonical injection W_n to W_m (n < m, lossless).
1849    Lift {
1850        /// Index of the operand term in the arena.
1851        operand_index: u32,
1852        /// Target Witt level.
1853        target: WittLevel,
1854    },
1855    /// Project: canonical surjection W_m to W_n (m > n, lossy).
1856    Project {
1857        /// Index of the operand term in the arena.
1858        operand_index: u32,
1859        /// Target Witt level.
1860        target: WittLevel,
1861    },
1862    /// Match expression with pattern-result pairs.
1863    Match {
1864        /// Index of the scrutinee term in the arena.
1865        scrutinee_index: u32,
1866        /// Match arms (indices into arena).
1867        arms: TermList,
1868    },
1869    /// Bounded recursion with descent measure.
1870    Recurse {
1871        /// Index of the descent measure term.
1872        measure_index: u32,
1873        /// Index of the base case term.
1874        base_index: u32,
1875        /// Index of the recursive step term.
1876        step_index: u32,
1877    },
1878    /// Stream construction via unfold.
1879    Unfold {
1880        /// Index of the seed term.
1881        seed_index: u32,
1882        /// Index of the step function term.
1883        step_index: u32,
1884    },
1885    /// Try expression with failure recovery.
1886    Try {
1887        /// Index of the body term.
1888        body_index: u32,
1889        /// Index of the handler term.
1890        handler_index: u32,
1891    },
1892    /// Substitution-axis-realized verb projection (wiki ADR-029 + ADR-030).
1893    /// Delegates evaluation to the application's `AxisTuple` substitution-axis
1894    /// impl: the catamorphism evaluates the input subtree, dispatches the
1895    /// axis at `axis_index` to the kernel identified by `kernel_id`, and
1896    /// emits the kernel's output as the result. Emitted by
1897    /// `prism_model!` from the closure-body form `hash(input)` (ADR-026 G19,
1898    /// which lowers to AxisInvocation against the application's HashAxis).
1899    AxisInvocation {
1900        /// Position of the axis in the application's `AxisTuple`.
1901        axis_index: u32,
1902        /// Per-axis kernel id (the SDK macro emits per-method `KERNEL_*` consts).
1903        kernel_id: u32,
1904        /// Input subtree's arena index (single input — current axes are 1-arg).
1905        input_index: u32,
1906    },
1907    /// Field-access projection over a partition_product input (wiki
1908    /// ADR-033 G20). The catamorphism's fold-rule evaluates `source`
1909    /// and slices `[byte_offset .. byte_offset + byte_length]` from
1910    /// the resulting bytes. Emitted by `prism_model!` and `verb!`
1911    /// from the closure-body forms `<expr>.<index>` and
1912    /// `<expr>.<field_name>` (named-field access requires the
1913    /// `partition_product!` declaration to use the named-field form).
1914    /// Coproduct field-access is rejected at macro-expansion time.
1915    ProjectField {
1916        /// Arena index of the source expression's term tree.
1917        source_index: u32,
1918        /// Byte offset into the source's evaluated bytes (proc-
1919        /// macro-computed from the partition-product factor widths).
1920        byte_offset: u32,
1921        /// Length of the projected slice in bytes.
1922        byte_length: u32,
1923    },
1924    /// Bounded search with structural early termination (wiki ADR-034).
1925    /// The catamorphism iterates `idx` from 0 up to (but excluding) the
1926    /// evaluated `domain_size`; for each iteration it evaluates
1927    /// `predicate` with `FIRST_ADMIT_IDX_NAME_INDEX` bound to `idx`.
1928    /// On the first non-zero predicate result the fold emits the
1929    /// coproduct value `(0x01, idx_bytes)` and terminates iteration; if
1930    /// no `idx` admits, the fold emits `(0x00, idx-width zero bytes)`.
1931    /// Emitted by `prism_model!` and `verb!` from the closure-body
1932    /// form `first_admit(<DomainTy>, |idx| <pred>)` (ADR-026 G16; the
1933    /// lowering target shifted from `Term::Recurse` to `Term::FirstAdmit`
1934    /// per ADR-034's structural-search commitment).
1935    FirstAdmit {
1936        /// Arena index of the domain-cardinality term (typically a
1937        /// `Term::Literal` carrying `<DomainTy as ConstrainedTypeShape>::CYCLE_SIZE`).
1938        domain_size_index: u32,
1939        /// Arena index of the predicate body. Evaluation visits
1940        /// `predicate` with `FIRST_ADMIT_IDX_NAME_INDEX` bound to the
1941        /// current candidate `idx`.
1942        predicate_index: u32,
1943    },
1944    /// ψ_1 (wiki ADR-035): nerve construction — Constraints → SimplicialComplex.
1945    /// Lowered from the closure-body form `nerve(<value_expr>)` (G21).
1946    /// Resolver-bound: consults the ResolverTuple's NerveResolver per ADR-036.
1947    Nerve {
1948        /// Arena index of the value-bytes operand (typically a
1949        /// `Term::Variable` for the route input or a `Term::ProjectField`).
1950        value_index: u32,
1951    },
1952    /// ψ_2 (wiki ADR-035): chain functor — SimplicialComplex → ChainComplex.
1953    /// Lowered from `chain_complex(<simplicial_expr>)` (G22).
1954    /// Resolver-bound: ChainComplexResolver per ADR-036.
1955    ChainComplex { simplicial_index: u32 },
1956    /// ψ_3 (wiki ADR-035): homology functor — ChainComplex → HomologyGroups.
1957    /// `H_k(C) = ker(∂_k) / im(∂_{k+1})`.
1958    /// Lowered from `homology_groups(<chain_expr>)` (G23).
1959    /// Resolver-bound: HomologyGroupResolver per ADR-036.
1960    HomologyGroups { chain_index: u32 },
1961    /// ψ_4 (wiki ADR-035): Betti-number extraction — HomologyGroups → BettiNumbers.
1962    /// Pure computation on resolved homology groups; no resolver consultation.
1963    /// Lowered from `betti(<homology_expr>)` (G24).
1964    Betti { homology_index: u32 },
1965    /// ψ_5 (wiki ADR-035): dualization functor — ChainComplex → CochainComplex.
1966    /// `C^k = Hom(C_k, R)`.
1967    /// Lowered from `cochain_complex(<chain_expr>)` (G25).
1968    /// Resolver-bound: CochainComplexResolver per ADR-036.
1969    CochainComplex { chain_index: u32 },
1970    /// ψ_6 (wiki ADR-035): cohomology functor — CochainComplex → CohomologyGroups.
1971    /// `H^k(C) = ker(δ^k) / im(δ^{k-1})`.
1972    /// Lowered from `cohomology_groups(<cochain_expr>)` (G26).
1973    /// Resolver-bound: CohomologyGroupResolver per ADR-036.
1974    CohomologyGroups { cochain_index: u32 },
1975    /// ψ_7 (wiki ADR-035): Kan-completion + Postnikov truncation —
1976    /// SimplicialComplex → PostnikovTower. The PostnikovResolver performs
1977    /// the Kan-completion internally; verb authors do not need to construct
1978    /// KanComplex values explicitly.
1979    /// Lowered from `postnikov_tower(<simplicial_expr>)` (G27).
1980    /// Resolver-bound: PostnikovResolver per ADR-036.
1981    PostnikovTower { simplicial_index: u32 },
1982    /// ψ_8 (wiki ADR-035): homotopy extraction — PostnikovTower → HomotopyGroups.
1983    /// π_k from each truncation stage.
1984    /// Lowered from `homotopy_groups(<postnikov_expr>)` (G28).
1985    /// Resolver-bound: HomotopyGroupResolver per ADR-036.
1986    HomotopyGroups { postnikov_index: u32 },
1987    /// ψ_9 (wiki ADR-035): k-invariant computation — HomotopyGroups → KInvariants.
1988    /// κ_k classifying the Postnikov tower.
1989    /// Lowered from `k_invariants(<homotopy_expr>)` (G29).
1990    /// Resolver-bound: KInvariantResolver per ADR-036.
1991    KInvariants { homotopy_index: u32 },
1992}
1993
1994/// Wiki ADR-024 verb-graph compile-time inlining: shift the arena-index
1995/// fields of `term` by `offset`. Used by [`inline_verb_fragment`] to
1996/// inline a verb's term-tree fragment into a host arena at compile time.
1997/// `Term::Variable`'s `name_index` is a binding-name reference (not an
1998/// arena index) and is preserved unchanged. `Term::Try`'s `handler_index`
1999/// is preserved unchanged when it equals `u32::MAX` (the default-
2000/// propagation sentinel per ADR-022 D3 G9).
2001#[must_use]
2002pub const fn shift_term<'a, const INLINE_BYTES: usize>(
2003    term: Term<'a, INLINE_BYTES>,
2004    offset: u32,
2005) -> Term<'a, INLINE_BYTES> {
2006    match term {
2007        Term::Literal { value, level } => Term::Literal { value, level },
2008        // name_index is a binding-name reference, not an arena index.
2009        Term::Variable { name_index } => Term::Variable { name_index },
2010        Term::Application { operator, args } => Term::Application {
2011            operator,
2012            args: TermList {
2013                start: args.start + offset,
2014                len: args.len,
2015            },
2016        },
2017        Term::Lift {
2018            operand_index,
2019            target,
2020        } => Term::Lift {
2021            operand_index: operand_index + offset,
2022            target,
2023        },
2024        Term::Project {
2025            operand_index,
2026            target,
2027        } => Term::Project {
2028            operand_index: operand_index + offset,
2029            target,
2030        },
2031        Term::Match {
2032            scrutinee_index,
2033            arms,
2034        } => Term::Match {
2035            scrutinee_index: scrutinee_index + offset,
2036            arms: TermList {
2037                start: arms.start + offset,
2038                len: arms.len,
2039            },
2040        },
2041        Term::Recurse {
2042            measure_index,
2043            base_index,
2044            step_index,
2045        } => Term::Recurse {
2046            measure_index: measure_index + offset,
2047            base_index: base_index + offset,
2048            step_index: step_index + offset,
2049        },
2050        Term::Unfold {
2051            seed_index,
2052            step_index,
2053        } => Term::Unfold {
2054            seed_index: seed_index + offset,
2055            step_index: step_index + offset,
2056        },
2057        Term::Try {
2058            body_index,
2059            handler_index,
2060        } => Term::Try {
2061            body_index: body_index + offset,
2062            handler_index: if handler_index == u32::MAX {
2063                u32::MAX
2064            } else {
2065                handler_index + offset
2066            },
2067        },
2068        Term::AxisInvocation {
2069            axis_index,
2070            kernel_id,
2071            input_index,
2072        } => Term::AxisInvocation {
2073            axis_index,
2074            kernel_id,
2075            input_index: input_index + offset,
2076        },
2077        Term::ProjectField {
2078            source_index,
2079            byte_offset,
2080            byte_length,
2081        } => Term::ProjectField {
2082            source_index: source_index + offset,
2083            byte_offset,
2084            byte_length,
2085        },
2086        Term::FirstAdmit {
2087            domain_size_index,
2088            predicate_index,
2089        } => Term::FirstAdmit {
2090            domain_size_index: domain_size_index + offset,
2091            predicate_index: predicate_index + offset,
2092        },
2093        Term::Nerve { value_index } => Term::Nerve {
2094            value_index: value_index + offset,
2095        },
2096        Term::ChainComplex { simplicial_index } => Term::ChainComplex {
2097            simplicial_index: simplicial_index + offset,
2098        },
2099        Term::HomologyGroups { chain_index } => Term::HomologyGroups {
2100            chain_index: chain_index + offset,
2101        },
2102        Term::Betti { homology_index } => Term::Betti {
2103            homology_index: homology_index + offset,
2104        },
2105        Term::CochainComplex { chain_index } => Term::CochainComplex {
2106            chain_index: chain_index + offset,
2107        },
2108        Term::CohomologyGroups { cochain_index } => Term::CohomologyGroups {
2109            cochain_index: cochain_index + offset,
2110        },
2111        Term::PostnikovTower { simplicial_index } => Term::PostnikovTower {
2112            simplicial_index: simplicial_index + offset,
2113        },
2114        Term::HomotopyGroups { postnikov_index } => Term::HomotopyGroups {
2115            postnikov_index: postnikov_index + offset,
2116        },
2117        Term::KInvariants { homotopy_index } => Term::KInvariants {
2118            homotopy_index: homotopy_index + offset,
2119        },
2120    }
2121}
2122
2123/// Wiki ADR-024 compile-time verb-fragment inlining helper.
2124/// Copies the verb `fragment` slice into `buf` starting at `len` while applying
2125/// two simultaneous transformations per term so the verb body becomes part of
2126/// the calling route's flat arena: Variable(0) substitution (the verb's `input`
2127/// parameter binds to the caller's argument expression by replacing each
2128/// `Variable { name_index: 0 }` with a copy of `buf[arg_root_idx]`), and arena-
2129/// index shifting (every non-Variable(0) term has its arena-index fields shifted
2130/// by `len` so internal references resolve correctly within the host).
2131/// The combined transformation realises ADR-024's compile-time inlining: the
2132/// verb body lands in the host arena with its `input` bound to the caller's
2133/// argument expression — verb-graph acyclicity is checked at const-eval time,
2134/// no `Term::VerbReference` variant or runtime depth guard is required.
2135/// # Panics
2136/// Panics at const-eval time if `len + fragment.len() > CAP` or if
2137/// `arg_root_idx as usize >= len`.
2138#[must_use]
2139pub const fn inline_verb_fragment<'a, const INLINE_BYTES: usize, const CAP: usize>(
2140    mut buf: [Term<'a, INLINE_BYTES>; CAP],
2141    mut len: usize,
2142    fragment: &[Term<'a, INLINE_BYTES>],
2143    arg_root_idx: u32,
2144) -> ([Term<'a, INLINE_BYTES>; CAP], usize) {
2145    let offset = len as u32;
2146    // Capture a copy of the caller's argument root term; `Variable { name_index: 0 }`
2147    // occurrences in the fragment are replaced by this copy per ADR-024.
2148    let arg_root_term = buf[arg_root_idx as usize];
2149    let mut i = 0;
2150    while i < fragment.len() {
2151        let term = fragment[i];
2152        let new_term = match term {
2153            Term::Variable { name_index: 0 } => arg_root_term,
2154            other => shift_term(other, offset),
2155        };
2156        buf[len] = new_term;
2157        len += 1;
2158        i += 1;
2159    }
2160    (buf, len)
2161}
2162
2163/// A type declaration with constraint kinds.
2164#[derive(Debug, Clone, PartialEq, Eq)]
2165pub struct TypeDeclaration {
2166    /// Name index for this type.
2167    pub name_index: u32,
2168    /// Constraint terms (indices into arena).
2169    pub constraints: TermList,
2170}
2171
2172/// A named binding: `let name : Type = term`.
2173#[derive(Debug, Clone, PartialEq, Eq)]
2174pub struct Binding {
2175    /// Name index for this binding.
2176    pub name_index: u32,
2177    /// Index of the type declaration.
2178    pub type_index: u32,
2179    /// Index of the value term in the arena.
2180    pub value_index: u32,
2181    /// EBNF surface syntax (compile-time constant).
2182    pub surface: &'static str,
2183    /// FNV-1a content address (compile-time constant).
2184    pub content_address: u64,
2185}
2186
2187impl Binding {
2188    /// v0.2.2 Phase P.3: lift this binding to the `BindingEntry` shape consumed by
2189    /// `BindingsTable`. `address` is derived from `content_address` via
2190    /// `ContentAddress::from_u64_fingerprint`; `bytes` re-uses the `surface` slice.
2191    /// Content-deterministic; const-compatible since all fields are `'static`.
2192    #[inline]
2193    #[must_use]
2194    pub const fn to_binding_entry(&self) -> BindingEntry {
2195        BindingEntry {
2196            address: ContentAddress::from_u64_fingerprint(self.content_address),
2197            bytes: self.surface.as_bytes(),
2198        }
2199    }
2200}
2201
2202/// An assertion: `assert lhs = rhs`.
2203#[derive(Debug, Clone, PartialEq, Eq)]
2204pub struct Assertion {
2205    /// Index of the left-hand side term.
2206    pub lhs_index: u32,
2207    /// Index of the right-hand side term.
2208    pub rhs_index: u32,
2209    /// EBNF surface syntax (compile-time constant).
2210    pub surface: &'static str,
2211}
2212
2213/// Boundary source declaration: `source name : Type via grounding`.
2214#[derive(Debug, Clone, PartialEq, Eq)]
2215pub struct SourceDeclaration {
2216    /// Name index for the source.
2217    pub name_index: u32,
2218    /// Index of the type declaration.
2219    pub type_index: u32,
2220    /// Name index of the grounding map.
2221    pub grounding_name_index: u32,
2222}
2223
2224/// Boundary sink declaration: `sink name : Type via projection`.
2225#[derive(Debug, Clone, PartialEq, Eq)]
2226pub struct SinkDeclaration {
2227    /// Name index for the sink.
2228    pub name_index: u32,
2229    /// Index of the type declaration.
2230    pub type_index: u32,
2231    /// Name index of the projection map.
2232    pub projection_name_index: u32,
2233}
2234
2235/// Structured violation diagnostic carrying metadata from the
2236/// conformance namespace. Every field is machine-readable.
2237/// # Examples
2238/// ```rust
2239/// use uor_foundation::enforcement::ShapeViolation;
2240/// use uor_foundation::ViolationKind;
2241///
2242/// // ShapeViolation carries structured metadata from the ontology.
2243/// // Every field is machine-readable — IRIs, counts, and a typed kind.
2244/// let violation = ShapeViolation {
2245///     shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2246///     constraint_iri: "https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
2247///     property_iri: "https://uor.foundation/reduction/rootTerm",
2248///     expected_range: "https://uor.foundation/schema/Term",
2249///     min_count: 1,
2250///     max_count: 1,
2251///     kind: ViolationKind::Missing,
2252/// };
2253///
2254/// // Machine-readable for tooling (IDE plugins, CI pipelines):
2255/// assert_eq!(violation.kind, ViolationKind::Missing);
2256/// assert!(violation.shape_iri.ends_with("CompileUnitShape"));
2257/// assert_eq!(violation.min_count, 1);
2258/// ```
2259#[derive(Debug, Clone, PartialEq, Eq)]
2260pub struct ShapeViolation {
2261    /// IRI of the `conformance:Shape` that was validated against.
2262    pub shape_iri: &'static str,
2263    /// IRI of the specific `conformance:PropertyConstraint` that failed.
2264    pub constraint_iri: &'static str,
2265    /// IRI of the property that was missing or invalid.
2266    pub property_iri: &'static str,
2267    /// The expected range class IRI.
2268    pub expected_range: &'static str,
2269    /// Minimum cardinality from the constraint.
2270    pub min_count: u32,
2271    /// Maximum cardinality (0 = unbounded).
2272    pub max_count: u32,
2273    /// What went wrong.
2274    pub kind: ViolationKind,
2275}
2276
2277impl core::fmt::Display for ShapeViolation {
2278    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2279        write!(
2280            f,
2281            "shape violation: {} (constraint {}, property {}, kind {:?})",
2282            self.shape_iri, self.constraint_iri, self.property_iri, self.kind,
2283        )
2284    }
2285}
2286
2287impl core::error::Error for ShapeViolation {}
2288
2289impl ShapeViolation {
2290    /// Phase C.3: returns the shape IRI as a `&'static str` suitable for
2291    /// `const fn` panic messages. The IRI uniquely identifies the violated
2292    /// constraint in the conformance catalog.
2293    #[inline]
2294    #[must_use]
2295    pub const fn const_message(&self) -> &'static str {
2296        self.shape_iri
2297    }
2298}
2299
2300/// Builder for `CompileUnit` admission into the reduction pipeline.
2301/// Collects `rootTerm`, `wittLevelCeiling`, `thermodynamicBudget`,
2302/// and `targetDomains`. The `validate()` method checks structural
2303/// constraints (Tier 1) and value-dependent constraints (Tier 2).
2304/// # Examples
2305/// ```rust
2306/// use uor_foundation::enforcement::{CompileUnitBuilder, ConstrainedTypeInput, Term};
2307/// use uor_foundation::{WittLevel, VerificationDomain, ViolationKind};
2308///
2309/// // A CompileUnit packages a term graph for reduction admission.
2310/// // The builder enforces that all required fields are present.
2311/// // ADR-060: `Term`/`CompileUnitBuilder` carry an `INLINE_BYTES`
2312/// // const-generic the application derives from its `HostBounds`; fix
2313/// // a concrete width.
2314/// const N: usize = 32;
2315/// let terms: [Term<'static, N>; 1] =
2316///     [uor_foundation::pipeline::literal_u64(1, WittLevel::W8)];
2317/// let domains = [VerificationDomain::Enumerative];
2318///
2319/// let unit = CompileUnitBuilder::<N>::new()
2320///     .root_term(&terms)
2321///     .witt_level_ceiling(WittLevel::W8)
2322///     .thermodynamic_budget(1024)
2323///     .target_domains(&domains)
2324///     .result_type::<ConstrainedTypeInput>()
2325///     .validate();
2326/// assert!(unit.is_ok());
2327///
2328/// // Omitting a required field produces a ShapeViolation
2329/// // with the exact conformance IRI that failed:
2330/// let err = CompileUnitBuilder::<N>::new()
2331///     .witt_level_ceiling(WittLevel::W8)
2332///     .thermodynamic_budget(1024)
2333///     .target_domains(&domains)
2334///     .result_type::<ConstrainedTypeInput>()
2335///     .validate();
2336/// assert!(err.is_err());
2337/// if let Err(violation) = err {
2338///     assert_eq!(violation.kind, ViolationKind::Missing);
2339///     assert!(violation.property_iri.contains("rootTerm"));
2340/// }
2341/// ```
2342#[derive(Debug, Clone)]
2343pub struct CompileUnitBuilder<'a, const INLINE_BYTES: usize> {
2344    /// The root term expression.
2345    root_term: Option<&'a [Term<'a, INLINE_BYTES>]>,
2346    /// v0.2.2 Phase H1: named bindings (`let name : Type = term` forms)
2347    /// declared by the compile unit. Stage 5 extracts these into a `BindingsTable`
2348    /// for grounding-aware and session resolvers; an empty slice declares no bindings.
2349    bindings: Option<&'a [Binding]>,
2350    /// The widest Witt level the computation may reference.
2351    witt_level_ceiling: Option<WittLevel>,
2352    /// Landauer-bounded energy budget.
2353    thermodynamic_budget: Option<u64>,
2354    /// Verification domains targeted.
2355    target_domains: Option<&'a [VerificationDomain]>,
2356    /// v0.2.2 T6.11: result-type IRI for ShapeMismatch detection.
2357    /// Set via `result_type::<T: ConstrainedTypeShape>()`. Required by
2358    /// `validate()` and `validate_compile_unit_const`. The pipeline checks
2359    /// `unit.result_type_iri() == T::IRI` at `pipeline::run` invocation
2360    /// time, returning `PipelineFailure::ShapeMismatch` on mismatch.
2361    result_type_iri: Option<&'static str>,
2362}
2363
2364/// A validated compile unit ready for reduction admission.
2365/// v0.2.2 Phase A (carrier widening): the lifetime parameter `'a` ties
2366/// the post-validation carrier to its builder's borrow. The `root_term`
2367/// and `target_domains` slices are retained through validation so
2368/// resolvers can inspect declared structure — previously these fields
2369/// were discarded at `validate()` and every resolver received a
2370/// 3-field scalar witness with no walkable structure.
2371/// Const-constructed compile units use the trivial specialization
2372/// `CompileUnit<'static>` — borrow-free and usable in const contexts.
2373#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2374pub struct CompileUnit<'a, const INLINE_BYTES: usize> {
2375    /// The Witt level ceiling.
2376    level: WittLevel,
2377    /// The thermodynamic budget.
2378    budget: u64,
2379    /// v0.2.2 T6.11: result-type IRI. The pipeline matches this against
2380    /// the caller's `T::IRI` to detect shape mismatches.
2381    result_type_iri: &'static str,
2382    /// v0.2.2 Phase A: root term expression, retained from the builder.
2383    /// Stage 5 (extract bindings) and the grounding-aware resolver walk
2384    /// this slice. Empty slice for the trivial `CompileUnit<'static>`
2385    /// specialization produced by builders that don't carry a term AST.
2386    root_term: &'a [Term<'a, INLINE_BYTES>],
2387    /// v0.2.2 Phase H1: named bindings retained from the builder. Consumed by Stage 5
2388    /// (`bindings_from_unit`) to materialize the `BindingsTable` for grounding-aware,
2389    /// session, and superposition resolvers. Empty slice declares no bindings.
2390    bindings: &'a [Binding],
2391    /// v0.2.2 Phase A: verification domains targeted, retained from the builder.
2392    target_domains: &'a [VerificationDomain],
2393}
2394
2395impl<'a, const INLINE_BYTES: usize> CompileUnit<'a, INLINE_BYTES> {
2396    /// Returns the Witt level ceiling declared at validation time.
2397    #[inline]
2398    #[must_use]
2399    pub const fn witt_level(&self) -> WittLevel {
2400        self.level
2401    }
2402
2403    /// Returns the thermodynamic budget declared at validation time.
2404    #[inline]
2405    #[must_use]
2406    pub const fn thermodynamic_budget(&self) -> u64 {
2407        self.budget
2408    }
2409
2410    /// v0.2.2 T6.11: returns the result-type IRI declared at validation
2411    /// time. The pipeline matches this against the caller's `T::IRI` to
2412    /// detect shape mismatches.
2413    #[inline]
2414    #[must_use]
2415    pub const fn result_type_iri(&self) -> &'static str {
2416        self.result_type_iri
2417    }
2418
2419    /// v0.2.2 Phase A: returns the root term slice declared at validation time.
2420    /// Empty for builders that did not supply a term AST.
2421    #[inline]
2422    #[must_use]
2423    pub const fn root_term(&self) -> &'a [Term<'a, INLINE_BYTES>] {
2424        self.root_term
2425    }
2426
2427    /// v0.2.2 Phase H1: returns the named bindings declared at validation time.
2428    /// Consumed by Stage 5 (`bindings_from_unit`) to materialize the `BindingsTable`.
2429    /// Empty slice for compile units that declare no bindings.
2430    #[inline]
2431    #[must_use]
2432    pub const fn bindings(&self) -> &'a [Binding] {
2433        self.bindings
2434    }
2435
2436    /// v0.2.2 Phase A: returns the verification domains declared at validation time.
2437    #[inline]
2438    #[must_use]
2439    pub const fn target_domains(&self) -> &'a [VerificationDomain] {
2440        self.target_domains
2441    }
2442
2443    /// v0.2.2 Phase G / T2.8 + T6.11: const-constructible parts form used
2444    /// by `validate_compile_unit_const` — the const-fn path reads the
2445    /// builder's fields and packs them into the `Validated` result.
2446    /// v0.2.2 Phase H1: bindings slice is retained alongside root_term;
2447    /// empty slice declares no bindings.
2448    #[inline]
2449    #[must_use]
2450    pub(crate) const fn from_parts_const(
2451        level: WittLevel,
2452        budget: u64,
2453        result_type_iri: &'static str,
2454        root_term: &'a [Term<'a, INLINE_BYTES>],
2455        bindings: &'a [Binding],
2456        target_domains: &'a [VerificationDomain],
2457    ) -> Self {
2458        Self {
2459            level,
2460            budget,
2461            result_type_iri,
2462            root_term,
2463            bindings,
2464            target_domains,
2465        }
2466    }
2467}
2468
2469impl<'a, const INLINE_BYTES: usize> CompileUnitBuilder<'a, INLINE_BYTES> {
2470    /// Creates a new empty builder.
2471    #[must_use]
2472    pub const fn new() -> Self {
2473        Self {
2474            root_term: None,
2475            bindings: None,
2476            witt_level_ceiling: None,
2477            thermodynamic_budget: None,
2478            target_domains: None,
2479            result_type_iri: None,
2480        }
2481    }
2482
2483    /// Set the root term expression.
2484    #[must_use]
2485    pub const fn root_term(mut self, terms: &'a [Term<'a, INLINE_BYTES>]) -> Self {
2486        self.root_term = Some(terms);
2487        self
2488    }
2489
2490    /// v0.2.2 Phase H1: set the named bindings declared by this compile unit.
2491    /// Consumed by Stage 5 (`bindings_from_unit`) to materialize the
2492    /// `BindingsTable` for grounding-aware, session, and superposition resolvers.
2493    /// Omit for compile units without bindings; the default is the empty slice.
2494    #[must_use]
2495    pub const fn bindings(mut self, bindings: &'a [Binding]) -> Self {
2496        self.bindings = Some(bindings);
2497        self
2498    }
2499
2500    /// Set the Witt level ceiling.
2501    #[must_use]
2502    pub const fn witt_level_ceiling(mut self, level: WittLevel) -> Self {
2503        self.witt_level_ceiling = Some(level);
2504        self
2505    }
2506
2507    /// Set the thermodynamic budget.
2508    #[must_use]
2509    pub const fn thermodynamic_budget(mut self, budget: u64) -> Self {
2510        self.thermodynamic_budget = Some(budget);
2511        self
2512    }
2513
2514    /// Set the target verification domains.
2515    #[must_use]
2516    pub const fn target_domains(mut self, domains: &'a [VerificationDomain]) -> Self {
2517        self.target_domains = Some(domains);
2518        self
2519    }
2520
2521    /// v0.2.2 T6.11: set the result-type IRI from a `ConstrainedTypeShape`
2522    /// type parameter. The pipeline matches this against the caller's
2523    /// `T::IRI` at `pipeline::run` invocation time, returning
2524    /// `PipelineFailure::ShapeMismatch` on mismatch.
2525    /// Required: `validate()` and `validate_compile_unit_const` reject
2526    /// builders without a result type set.
2527    #[must_use]
2528    pub const fn result_type<T: crate::pipeline::ConstrainedTypeShape>(mut self) -> Self {
2529        self.result_type_iri = Some(T::IRI);
2530        self
2531    }
2532
2533    /// v0.2.2 T2.8: const-fn accessor exposing the stored Witt level
2534    /// ceiling (or `None` if unset). Used by `validate_compile_unit_const`.
2535    #[inline]
2536    #[must_use]
2537    pub const fn witt_level_option(&self) -> Option<WittLevel> {
2538        self.witt_level_ceiling
2539    }
2540
2541    /// v0.2.2 T2.8: const-fn accessor exposing the stored thermodynamic
2542    /// budget (or `None` if unset).
2543    #[inline]
2544    #[must_use]
2545    pub const fn budget_option(&self) -> Option<u64> {
2546        self.thermodynamic_budget
2547    }
2548
2549    /// v0.2.2 T6.13: const-fn accessor — `true` iff `root_term` is set.
2550    #[inline]
2551    #[must_use]
2552    pub const fn has_root_term_const(&self) -> bool {
2553        self.root_term.is_some()
2554    }
2555
2556    /// v0.2.2 T6.13: const-fn accessor — `true` iff `target_domains` is
2557    /// set and non-empty.
2558    #[inline]
2559    #[must_use]
2560    pub const fn has_target_domains_const(&self) -> bool {
2561        match self.target_domains {
2562            Some(d) => !d.is_empty(),
2563            None => false,
2564        }
2565    }
2566
2567    /// v0.2.2 T6.13: const-fn accessor exposing the stored result-type IRI
2568    /// (or `None` if unset). Used by `validate_compile_unit_const`.
2569    #[inline]
2570    #[must_use]
2571    pub const fn result_type_iri_const(&self) -> Option<&'static str> {
2572        self.result_type_iri
2573    }
2574
2575    /// v0.2.2 Phase A: const-fn accessor exposing the stored root-term slice,
2576    /// or an empty slice if unset. Used by `validate_compile_unit_const` to
2577    /// propagate the AST into the widened `CompileUnit<'a>` carrier.
2578    #[inline]
2579    #[must_use]
2580    pub const fn root_term_slice_const(&self) -> &'a [Term<'a, INLINE_BYTES>] {
2581        match self.root_term {
2582            Some(terms) => terms,
2583            None => &[],
2584        }
2585    }
2586
2587    /// v0.2.2 Phase H1: const-fn accessor exposing the stored bindings slice,
2588    /// or an empty slice if unset. Used by `validate_compile_unit_const` to
2589    /// propagate the bindings declaration into the widened `CompileUnit<'a>` carrier.
2590    #[inline]
2591    #[must_use]
2592    pub const fn bindings_slice_const(&self) -> &'a [Binding] {
2593        match self.bindings {
2594            Some(bindings) => bindings,
2595            None => &[],
2596        }
2597    }
2598
2599    /// v0.2.2 Phase A: const-fn accessor exposing the stored target-domains
2600    /// slice, or an empty slice if unset. Used by `validate_compile_unit_const`.
2601    #[inline]
2602    #[must_use]
2603    pub const fn target_domains_slice_const(&self) -> &'a [VerificationDomain] {
2604        match self.target_domains {
2605            Some(d) => d,
2606            None => &[],
2607        }
2608    }
2609
2610    /// Validate against `CompileUnitShape`.
2611    /// Tier 1: checks presence and cardinality of all required fields.
2612    /// Tier 2: checks budget solvency and level coherence.
2613    /// # Errors
2614    /// Returns `ShapeViolation` if any constraint is not satisfied.
2615    pub fn validate(self) -> Result<Validated<CompileUnit<'a, INLINE_BYTES>>, ShapeViolation> {
2616        let root_term = match self.root_term {
2617            Some(terms) => terms,
2618            None => {
2619                return Err(ShapeViolation {
2620                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2621                    constraint_iri:
2622                        "https://uor.foundation/conformance/compileUnit_rootTerm_constraint",
2623                    property_iri: "https://uor.foundation/reduction/rootTerm",
2624                    expected_range: "https://uor.foundation/schema/Term",
2625                    min_count: 1,
2626                    max_count: 1,
2627                    kind: ViolationKind::Missing,
2628                })
2629            }
2630        };
2631        let level =
2632            match self.witt_level_ceiling {
2633                Some(l) => l,
2634                None => return Err(ShapeViolation {
2635                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2636                    constraint_iri:
2637                        "https://uor.foundation/conformance/compileUnit_unitWittLevel_constraint",
2638                    property_iri: "https://uor.foundation/reduction/unitWittLevel",
2639                    expected_range: "https://uor.foundation/schema/WittLevel",
2640                    min_count: 1,
2641                    max_count: 1,
2642                    kind: ViolationKind::Missing,
2643                }),
2644            };
2645        let budget = match self.thermodynamic_budget {
2646            Some(b) => b,
2647            None => return Err(ShapeViolation {
2648                shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2649                constraint_iri:
2650                    "https://uor.foundation/conformance/compileUnit_thermodynamicBudget_constraint",
2651                property_iri: "https://uor.foundation/reduction/thermodynamicBudget",
2652                expected_range: "http://www.w3.org/2001/XMLSchema#decimal",
2653                min_count: 1,
2654                max_count: 1,
2655                kind: ViolationKind::Missing,
2656            }),
2657        };
2658        let target_domains =
2659            match self.target_domains {
2660                Some(d) if !d.is_empty() => d,
2661                _ => return Err(ShapeViolation {
2662                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2663                    constraint_iri:
2664                        "https://uor.foundation/conformance/compileUnit_targetDomains_constraint",
2665                    property_iri: "https://uor.foundation/reduction/targetDomains",
2666                    expected_range: "https://uor.foundation/op/VerificationDomain",
2667                    min_count: 1,
2668                    max_count: 0,
2669                    kind: ViolationKind::Missing,
2670                }),
2671            };
2672        let result_type_iri = match self.result_type_iri {
2673            Some(iri) => iri,
2674            None => {
2675                return Err(ShapeViolation {
2676                    shape_iri: "https://uor.foundation/conformance/CompileUnitShape",
2677                    constraint_iri:
2678                        "https://uor.foundation/conformance/compileUnit_resultType_constraint",
2679                    property_iri: "https://uor.foundation/reduction/resultType",
2680                    expected_range: "https://uor.foundation/type/ConstrainedType",
2681                    min_count: 1,
2682                    max_count: 1,
2683                    kind: ViolationKind::Missing,
2684                })
2685            }
2686        };
2687        // v0.2.2 Phase H1: bindings is optional; absent declares no bindings.
2688        let bindings: &'a [Binding] = match self.bindings {
2689            Some(b) => b,
2690            None => &[],
2691        };
2692        Ok(Validated::new(CompileUnit {
2693            level,
2694            budget,
2695            result_type_iri,
2696            root_term,
2697            bindings,
2698            target_domains,
2699        }))
2700    }
2701}
2702
2703impl<'a, const INLINE_BYTES: usize> Default for CompileUnitBuilder<'a, INLINE_BYTES> {
2704    fn default() -> Self {
2705        Self::new()
2706    }
2707}
2708
2709/// Builder for `EffectDeclaration`. Validates against `EffectShape`.
2710#[derive(Debug, Clone)]
2711pub struct EffectDeclarationBuilder<'a> {
2712    /// The `name` field.
2713    name: Option<&'a str>,
2714    /// The `target_sites` field.
2715    target_sites: Option<&'a [u32]>,
2716    /// The `budget_delta` field.
2717    budget_delta: Option<i64>,
2718    /// The `commutes` field.
2719    commutes: Option<bool>,
2720}
2721
2722/// Declared effect validated against `EffectShape`.
2723#[derive(Debug, Clone, PartialEq, Eq)]
2724pub struct EffectDeclaration {
2725    /// Shape IRI this declaration was validated against.
2726    pub shape_iri: &'static str,
2727}
2728
2729impl EffectDeclaration {
2730    /// v0.2.2 Phase G: const-constructible empty form used by
2731    /// `validate_*_const` companion functions.
2732    #[inline]
2733    #[must_use]
2734    #[allow(dead_code)]
2735    pub(crate) const fn empty_const() -> Self {
2736        Self {
2737            shape_iri: "https://uor.foundation/conformance/EffectShape",
2738        }
2739    }
2740}
2741
2742impl<'a> EffectDeclarationBuilder<'a> {
2743    /// Creates a new empty builder.
2744    #[must_use]
2745    pub const fn new() -> Self {
2746        Self {
2747            name: None,
2748            target_sites: None,
2749            budget_delta: None,
2750            commutes: None,
2751        }
2752    }
2753
2754    /// Set the `name` field.
2755    #[must_use]
2756    pub const fn name(mut self, value: &'a str) -> Self {
2757        self.name = Some(value);
2758        self
2759    }
2760
2761    /// Set the `target_sites` field.
2762    #[must_use]
2763    pub const fn target_sites(mut self, value: &'a [u32]) -> Self {
2764        self.target_sites = Some(value);
2765        self
2766    }
2767
2768    /// Set the `budget_delta` field.
2769    #[must_use]
2770    pub const fn budget_delta(mut self, value: i64) -> Self {
2771        self.budget_delta = Some(value);
2772        self
2773    }
2774
2775    /// Set the `commutes` field.
2776    #[must_use]
2777    pub const fn commutes(mut self, value: bool) -> Self {
2778        self.commutes = Some(value);
2779        self
2780    }
2781
2782    /// Validate against `EffectShape`.
2783    /// # Errors
2784    /// Returns `ShapeViolation` if any required field is missing.
2785    pub fn validate(self) -> Result<Validated<EffectDeclaration>, ShapeViolation> {
2786        if self.name.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/name",
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        if self.target_sites.is_none() {
2798            return Err(ShapeViolation {
2799                shape_iri: "https://uor.foundation/conformance/EffectShape",
2800                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2801                property_iri: "https://uor.foundation/conformance/target_sites",
2802                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2803                min_count: 1,
2804                max_count: 1,
2805                kind: ViolationKind::Missing,
2806            });
2807        }
2808        if self.budget_delta.is_none() {
2809            return Err(ShapeViolation {
2810                shape_iri: "https://uor.foundation/conformance/EffectShape",
2811                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2812                property_iri: "https://uor.foundation/conformance/budget_delta",
2813                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2814                min_count: 1,
2815                max_count: 1,
2816                kind: ViolationKind::Missing,
2817            });
2818        }
2819        if self.commutes.is_none() {
2820            return Err(ShapeViolation {
2821                shape_iri: "https://uor.foundation/conformance/EffectShape",
2822                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2823                property_iri: "https://uor.foundation/conformance/commutes",
2824                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2825                min_count: 1,
2826                max_count: 1,
2827                kind: ViolationKind::Missing,
2828            });
2829        }
2830        Ok(Validated::new(EffectDeclaration {
2831            shape_iri: "https://uor.foundation/conformance/EffectShape",
2832        }))
2833    }
2834
2835    /// Phase C.1: const-fn companion for `EffectDeclarationBuilder::validate`.
2836    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
2837    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
2838    /// # Errors
2839    /// Returns `ShapeViolation` if any required field is missing.
2840    pub const fn validate_const(
2841        &self,
2842    ) -> Result<Validated<EffectDeclaration, CompileTime>, ShapeViolation> {
2843        if self.name.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/name",
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        if self.target_sites.is_none() {
2855            return Err(ShapeViolation {
2856                shape_iri: "https://uor.foundation/conformance/EffectShape",
2857                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2858                property_iri: "https://uor.foundation/conformance/target_sites",
2859                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2860                min_count: 1,
2861                max_count: 1,
2862                kind: ViolationKind::Missing,
2863            });
2864        }
2865        if self.budget_delta.is_none() {
2866            return Err(ShapeViolation {
2867                shape_iri: "https://uor.foundation/conformance/EffectShape",
2868                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2869                property_iri: "https://uor.foundation/conformance/budget_delta",
2870                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2871                min_count: 1,
2872                max_count: 1,
2873                kind: ViolationKind::Missing,
2874            });
2875        }
2876        if self.commutes.is_none() {
2877            return Err(ShapeViolation {
2878                shape_iri: "https://uor.foundation/conformance/EffectShape",
2879                constraint_iri: "https://uor.foundation/conformance/EffectShape",
2880                property_iri: "https://uor.foundation/conformance/commutes",
2881                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2882                min_count: 1,
2883                max_count: 1,
2884                kind: ViolationKind::Missing,
2885            });
2886        }
2887        Ok(Validated::new(EffectDeclaration {
2888            shape_iri: "https://uor.foundation/conformance/EffectShape",
2889        }))
2890    }
2891}
2892
2893impl<'a> Default for EffectDeclarationBuilder<'a> {
2894    fn default() -> Self {
2895        Self::new()
2896    }
2897}
2898
2899/// Builder for `GroundingDeclaration`. Validates against `GroundingShape`.
2900#[derive(Debug, Clone)]
2901pub struct GroundingDeclarationBuilder<'a> {
2902    /// The `source_type` field.
2903    source_type: Option<&'a str>,
2904    /// The `ring_mapping` field.
2905    ring_mapping: Option<&'a str>,
2906    /// The `invertibility` field.
2907    invertibility: Option<bool>,
2908}
2909
2910/// Declared grounding validated against `GroundingShape`.
2911#[derive(Debug, Clone, PartialEq, Eq)]
2912pub struct GroundingDeclaration {
2913    /// Shape IRI this declaration was validated against.
2914    pub shape_iri: &'static str,
2915}
2916
2917impl GroundingDeclaration {
2918    /// v0.2.2 Phase G: const-constructible empty form used by
2919    /// `validate_*_const` companion functions.
2920    #[inline]
2921    #[must_use]
2922    #[allow(dead_code)]
2923    pub(crate) const fn empty_const() -> Self {
2924        Self {
2925            shape_iri: "https://uor.foundation/conformance/GroundingShape",
2926        }
2927    }
2928}
2929
2930impl<'a> GroundingDeclarationBuilder<'a> {
2931    /// Creates a new empty builder.
2932    #[must_use]
2933    pub const fn new() -> Self {
2934        Self {
2935            source_type: None,
2936            ring_mapping: None,
2937            invertibility: None,
2938        }
2939    }
2940
2941    /// Set the `source_type` field.
2942    #[must_use]
2943    pub const fn source_type(mut self, value: &'a str) -> Self {
2944        self.source_type = Some(value);
2945        self
2946    }
2947
2948    /// Set the `ring_mapping` field.
2949    #[must_use]
2950    pub const fn ring_mapping(mut self, value: &'a str) -> Self {
2951        self.ring_mapping = Some(value);
2952        self
2953    }
2954
2955    /// Set the `invertibility` field.
2956    #[must_use]
2957    pub const fn invertibility(mut self, value: bool) -> Self {
2958        self.invertibility = Some(value);
2959        self
2960    }
2961
2962    /// Validate against `GroundingShape`.
2963    /// # Errors
2964    /// Returns `ShapeViolation` if any required field is missing.
2965    pub fn validate(self) -> Result<Validated<GroundingDeclaration>, ShapeViolation> {
2966        if self.source_type.is_none() {
2967            return Err(ShapeViolation {
2968                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2969                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2970                property_iri: "https://uor.foundation/conformance/source_type",
2971                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2972                min_count: 1,
2973                max_count: 1,
2974                kind: ViolationKind::Missing,
2975            });
2976        }
2977        if self.ring_mapping.is_none() {
2978            return Err(ShapeViolation {
2979                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2980                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2981                property_iri: "https://uor.foundation/conformance/ring_mapping",
2982                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2983                min_count: 1,
2984                max_count: 1,
2985                kind: ViolationKind::Missing,
2986            });
2987        }
2988        if self.invertibility.is_none() {
2989            return Err(ShapeViolation {
2990                shape_iri: "https://uor.foundation/conformance/GroundingShape",
2991                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
2992                property_iri: "https://uor.foundation/conformance/invertibility",
2993                expected_range: "http://www.w3.org/2002/07/owl#Thing",
2994                min_count: 1,
2995                max_count: 1,
2996                kind: ViolationKind::Missing,
2997            });
2998        }
2999        Ok(Validated::new(GroundingDeclaration {
3000            shape_iri: "https://uor.foundation/conformance/GroundingShape",
3001        }))
3002    }
3003
3004    /// Phase C.1: const-fn companion for `GroundingDeclarationBuilder::validate`.
3005    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3006    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3007    /// # Errors
3008    /// Returns `ShapeViolation` if any required field is missing.
3009    pub const fn validate_const(
3010        &self,
3011    ) -> Result<Validated<GroundingDeclaration, CompileTime>, ShapeViolation> {
3012        if self.source_type.is_none() {
3013            return Err(ShapeViolation {
3014                shape_iri: "https://uor.foundation/conformance/GroundingShape",
3015                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
3016                property_iri: "https://uor.foundation/conformance/source_type",
3017                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3018                min_count: 1,
3019                max_count: 1,
3020                kind: ViolationKind::Missing,
3021            });
3022        }
3023        if self.ring_mapping.is_none() {
3024            return Err(ShapeViolation {
3025                shape_iri: "https://uor.foundation/conformance/GroundingShape",
3026                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
3027                property_iri: "https://uor.foundation/conformance/ring_mapping",
3028                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3029                min_count: 1,
3030                max_count: 1,
3031                kind: ViolationKind::Missing,
3032            });
3033        }
3034        if self.invertibility.is_none() {
3035            return Err(ShapeViolation {
3036                shape_iri: "https://uor.foundation/conformance/GroundingShape",
3037                constraint_iri: "https://uor.foundation/conformance/GroundingShape",
3038                property_iri: "https://uor.foundation/conformance/invertibility",
3039                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3040                min_count: 1,
3041                max_count: 1,
3042                kind: ViolationKind::Missing,
3043            });
3044        }
3045        Ok(Validated::new(GroundingDeclaration {
3046            shape_iri: "https://uor.foundation/conformance/GroundingShape",
3047        }))
3048    }
3049}
3050
3051impl<'a> Default for GroundingDeclarationBuilder<'a> {
3052    fn default() -> Self {
3053        Self::new()
3054    }
3055}
3056
3057/// Builder for `DispatchDeclaration`. Validates against `DispatchShape`.
3058#[derive(Debug, Clone)]
3059pub struct DispatchDeclarationBuilder<'a, const INLINE_BYTES: usize> {
3060    /// The `predicate` field.
3061    predicate: Option<&'a [Term<'a, INLINE_BYTES>]>,
3062    /// The `target_resolver` field.
3063    target_resolver: Option<&'a str>,
3064    /// The `priority` field.
3065    priority: Option<u32>,
3066}
3067
3068/// Declared dispatch rule validated against `DispatchShape`.
3069#[derive(Debug, Clone, PartialEq, Eq)]
3070pub struct DispatchDeclaration {
3071    /// Shape IRI this declaration was validated against.
3072    pub shape_iri: &'static str,
3073}
3074
3075impl DispatchDeclaration {
3076    /// v0.2.2 Phase G: const-constructible empty form used by
3077    /// `validate_*_const` companion functions.
3078    #[inline]
3079    #[must_use]
3080    #[allow(dead_code)]
3081    pub(crate) const fn empty_const() -> Self {
3082        Self {
3083            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3084        }
3085    }
3086}
3087
3088impl<'a, const INLINE_BYTES: usize> DispatchDeclarationBuilder<'a, INLINE_BYTES> {
3089    /// Creates a new empty builder.
3090    #[must_use]
3091    pub const fn new() -> Self {
3092        Self {
3093            predicate: None,
3094            target_resolver: None,
3095            priority: None,
3096        }
3097    }
3098
3099    /// Set the `predicate` field.
3100    #[must_use]
3101    pub const fn predicate(mut self, value: &'a [Term<'a, INLINE_BYTES>]) -> Self {
3102        self.predicate = Some(value);
3103        self
3104    }
3105
3106    /// Set the `target_resolver` field.
3107    #[must_use]
3108    pub const fn target_resolver(mut self, value: &'a str) -> Self {
3109        self.target_resolver = Some(value);
3110        self
3111    }
3112
3113    /// Set the `priority` field.
3114    #[must_use]
3115    pub const fn priority(mut self, value: u32) -> Self {
3116        self.priority = Some(value);
3117        self
3118    }
3119
3120    /// Validate against `DispatchShape`.
3121    /// # Errors
3122    /// Returns `ShapeViolation` if any required field is missing.
3123    pub fn validate(self) -> Result<Validated<DispatchDeclaration>, ShapeViolation> {
3124        if self.predicate.is_none() {
3125            return Err(ShapeViolation {
3126                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3127                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3128                property_iri: "https://uor.foundation/conformance/predicate",
3129                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3130                min_count: 1,
3131                max_count: 1,
3132                kind: ViolationKind::Missing,
3133            });
3134        }
3135        if self.target_resolver.is_none() {
3136            return Err(ShapeViolation {
3137                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3138                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3139                property_iri: "https://uor.foundation/conformance/target_resolver",
3140                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3141                min_count: 1,
3142                max_count: 1,
3143                kind: ViolationKind::Missing,
3144            });
3145        }
3146        if self.priority.is_none() {
3147            return Err(ShapeViolation {
3148                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3149                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3150                property_iri: "https://uor.foundation/conformance/priority",
3151                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3152                min_count: 1,
3153                max_count: 1,
3154                kind: ViolationKind::Missing,
3155            });
3156        }
3157        Ok(Validated::new(DispatchDeclaration {
3158            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3159        }))
3160    }
3161
3162    /// Phase C.1: const-fn companion for `DispatchDeclarationBuilder::validate`.
3163    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3164    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3165    /// # Errors
3166    /// Returns `ShapeViolation` if any required field is missing.
3167    pub const fn validate_const(
3168        &self,
3169    ) -> Result<Validated<DispatchDeclaration, CompileTime>, ShapeViolation> {
3170        if self.predicate.is_none() {
3171            return Err(ShapeViolation {
3172                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3173                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3174                property_iri: "https://uor.foundation/conformance/predicate",
3175                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3176                min_count: 1,
3177                max_count: 1,
3178                kind: ViolationKind::Missing,
3179            });
3180        }
3181        if self.target_resolver.is_none() {
3182            return Err(ShapeViolation {
3183                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3184                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3185                property_iri: "https://uor.foundation/conformance/target_resolver",
3186                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3187                min_count: 1,
3188                max_count: 1,
3189                kind: ViolationKind::Missing,
3190            });
3191        }
3192        if self.priority.is_none() {
3193            return Err(ShapeViolation {
3194                shape_iri: "https://uor.foundation/conformance/DispatchShape",
3195                constraint_iri: "https://uor.foundation/conformance/DispatchShape",
3196                property_iri: "https://uor.foundation/conformance/priority",
3197                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3198                min_count: 1,
3199                max_count: 1,
3200                kind: ViolationKind::Missing,
3201            });
3202        }
3203        Ok(Validated::new(DispatchDeclaration {
3204            shape_iri: "https://uor.foundation/conformance/DispatchShape",
3205        }))
3206    }
3207}
3208
3209impl<'a, const INLINE_BYTES: usize> Default for DispatchDeclarationBuilder<'a, INLINE_BYTES> {
3210    fn default() -> Self {
3211        Self::new()
3212    }
3213}
3214
3215/// Builder for `LeaseDeclaration`. Validates against `LeaseShape`.
3216#[derive(Debug, Clone)]
3217pub struct LeaseDeclarationBuilder<'a> {
3218    /// The `linear_site` field.
3219    linear_site: Option<u32>,
3220    /// The `scope` field.
3221    scope: Option<&'a str>,
3222}
3223
3224/// Declared lease validated against `LeaseShape`.
3225#[derive(Debug, Clone, PartialEq, Eq)]
3226pub struct LeaseDeclaration {
3227    /// Shape IRI this declaration was validated against.
3228    pub shape_iri: &'static str,
3229}
3230
3231impl LeaseDeclaration {
3232    /// v0.2.2 Phase G: const-constructible empty form used by
3233    /// `validate_*_const` companion functions.
3234    #[inline]
3235    #[must_use]
3236    #[allow(dead_code)]
3237    pub(crate) const fn empty_const() -> Self {
3238        Self {
3239            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3240        }
3241    }
3242}
3243
3244impl<'a> LeaseDeclarationBuilder<'a> {
3245    /// Creates a new empty builder.
3246    #[must_use]
3247    pub const fn new() -> Self {
3248        Self {
3249            linear_site: None,
3250            scope: None,
3251        }
3252    }
3253
3254    /// Set the `linear_site` field.
3255    #[must_use]
3256    pub const fn linear_site(mut self, value: u32) -> Self {
3257        self.linear_site = Some(value);
3258        self
3259    }
3260
3261    /// Set the `scope` field.
3262    #[must_use]
3263    pub const fn scope(mut self, value: &'a str) -> Self {
3264        self.scope = Some(value);
3265        self
3266    }
3267
3268    /// Validate against `LeaseShape`.
3269    /// # Errors
3270    /// Returns `ShapeViolation` if any required field is missing.
3271    pub fn validate(self) -> Result<Validated<LeaseDeclaration>, ShapeViolation> {
3272        if self.linear_site.is_none() {
3273            return Err(ShapeViolation {
3274                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3275                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3276                property_iri: "https://uor.foundation/conformance/linear_site",
3277                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3278                min_count: 1,
3279                max_count: 1,
3280                kind: ViolationKind::Missing,
3281            });
3282        }
3283        if self.scope.is_none() {
3284            return Err(ShapeViolation {
3285                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3286                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3287                property_iri: "https://uor.foundation/conformance/scope",
3288                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3289                min_count: 1,
3290                max_count: 1,
3291                kind: ViolationKind::Missing,
3292            });
3293        }
3294        Ok(Validated::new(LeaseDeclaration {
3295            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3296        }))
3297    }
3298
3299    /// Phase C.1: const-fn companion for `LeaseDeclarationBuilder::validate`.
3300    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3301    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3302    /// # Errors
3303    /// Returns `ShapeViolation` if any required field is missing.
3304    pub const fn validate_const(
3305        &self,
3306    ) -> Result<Validated<LeaseDeclaration, CompileTime>, ShapeViolation> {
3307        if self.linear_site.is_none() {
3308            return Err(ShapeViolation {
3309                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3310                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3311                property_iri: "https://uor.foundation/conformance/linear_site",
3312                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3313                min_count: 1,
3314                max_count: 1,
3315                kind: ViolationKind::Missing,
3316            });
3317        }
3318        if self.scope.is_none() {
3319            return Err(ShapeViolation {
3320                shape_iri: "https://uor.foundation/conformance/LeaseShape",
3321                constraint_iri: "https://uor.foundation/conformance/LeaseShape",
3322                property_iri: "https://uor.foundation/conformance/scope",
3323                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3324                min_count: 1,
3325                max_count: 1,
3326                kind: ViolationKind::Missing,
3327            });
3328        }
3329        Ok(Validated::new(LeaseDeclaration {
3330            shape_iri: "https://uor.foundation/conformance/LeaseShape",
3331        }))
3332    }
3333}
3334
3335impl<'a> Default for LeaseDeclarationBuilder<'a> {
3336    fn default() -> Self {
3337        Self::new()
3338    }
3339}
3340
3341/// Builder for `StreamDeclaration`. Validates against `StreamShape`.
3342#[derive(Debug, Clone)]
3343pub struct StreamDeclarationBuilder<'a, const INLINE_BYTES: usize> {
3344    /// The `seed` field.
3345    seed: Option<&'a [Term<'a, INLINE_BYTES>]>,
3346    /// The `step` field.
3347    step: Option<&'a [Term<'a, INLINE_BYTES>]>,
3348    /// The `productivity_witness` field.
3349    productivity_witness: Option<&'a str>,
3350}
3351
3352/// Declared stream validated against `StreamShape`.
3353#[derive(Debug, Clone, PartialEq, Eq)]
3354pub struct StreamDeclaration {
3355    /// Shape IRI this declaration was validated against.
3356    pub shape_iri: &'static str,
3357}
3358
3359impl StreamDeclaration {
3360    /// v0.2.2 Phase G: const-constructible empty form used by
3361    /// `validate_*_const` companion functions.
3362    #[inline]
3363    #[must_use]
3364    #[allow(dead_code)]
3365    pub(crate) const fn empty_const() -> Self {
3366        Self {
3367            shape_iri: "https://uor.foundation/conformance/StreamShape",
3368        }
3369    }
3370}
3371
3372impl<'a, const INLINE_BYTES: usize> StreamDeclarationBuilder<'a, INLINE_BYTES> {
3373    /// Creates a new empty builder.
3374    #[must_use]
3375    pub const fn new() -> Self {
3376        Self {
3377            seed: None,
3378            step: None,
3379            productivity_witness: None,
3380        }
3381    }
3382
3383    /// Set the `seed` field.
3384    #[must_use]
3385    pub const fn seed(mut self, value: &'a [Term<'a, INLINE_BYTES>]) -> Self {
3386        self.seed = Some(value);
3387        self
3388    }
3389
3390    /// Set the `step` field.
3391    #[must_use]
3392    pub const fn step(mut self, value: &'a [Term<'a, INLINE_BYTES>]) -> Self {
3393        self.step = Some(value);
3394        self
3395    }
3396
3397    /// Set the `productivity_witness` field.
3398    #[must_use]
3399    pub const fn productivity_witness(mut self, value: &'a str) -> Self {
3400        self.productivity_witness = Some(value);
3401        self
3402    }
3403
3404    /// Validate against `StreamShape`.
3405    /// # Errors
3406    /// Returns `ShapeViolation` if any required field is missing.
3407    pub fn validate(self) -> Result<Validated<StreamDeclaration>, ShapeViolation> {
3408        if self.seed.is_none() {
3409            return Err(ShapeViolation {
3410                shape_iri: "https://uor.foundation/conformance/StreamShape",
3411                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3412                property_iri: "https://uor.foundation/conformance/seed",
3413                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3414                min_count: 1,
3415                max_count: 1,
3416                kind: ViolationKind::Missing,
3417            });
3418        }
3419        if self.step.is_none() {
3420            return Err(ShapeViolation {
3421                shape_iri: "https://uor.foundation/conformance/StreamShape",
3422                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3423                property_iri: "https://uor.foundation/conformance/step",
3424                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3425                min_count: 1,
3426                max_count: 1,
3427                kind: ViolationKind::Missing,
3428            });
3429        }
3430        if self.productivity_witness.is_none() {
3431            return Err(ShapeViolation {
3432                shape_iri: "https://uor.foundation/conformance/StreamShape",
3433                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3434                property_iri: "https://uor.foundation/conformance/productivity_witness",
3435                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3436                min_count: 1,
3437                max_count: 1,
3438                kind: ViolationKind::Missing,
3439            });
3440        }
3441        Ok(Validated::new(StreamDeclaration {
3442            shape_iri: "https://uor.foundation/conformance/StreamShape",
3443        }))
3444    }
3445
3446    /// Phase C.1: const-fn companion for `StreamDeclarationBuilder::validate`.
3447    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3448    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3449    /// # Errors
3450    /// Returns `ShapeViolation` if any required field is missing.
3451    pub const fn validate_const(
3452        &self,
3453    ) -> Result<Validated<StreamDeclaration, CompileTime>, ShapeViolation> {
3454        if self.seed.is_none() {
3455            return Err(ShapeViolation {
3456                shape_iri: "https://uor.foundation/conformance/StreamShape",
3457                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3458                property_iri: "https://uor.foundation/conformance/seed",
3459                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3460                min_count: 1,
3461                max_count: 1,
3462                kind: ViolationKind::Missing,
3463            });
3464        }
3465        if self.step.is_none() {
3466            return Err(ShapeViolation {
3467                shape_iri: "https://uor.foundation/conformance/StreamShape",
3468                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3469                property_iri: "https://uor.foundation/conformance/step",
3470                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3471                min_count: 1,
3472                max_count: 1,
3473                kind: ViolationKind::Missing,
3474            });
3475        }
3476        if self.productivity_witness.is_none() {
3477            return Err(ShapeViolation {
3478                shape_iri: "https://uor.foundation/conformance/StreamShape",
3479                constraint_iri: "https://uor.foundation/conformance/StreamShape",
3480                property_iri: "https://uor.foundation/conformance/productivity_witness",
3481                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3482                min_count: 1,
3483                max_count: 1,
3484                kind: ViolationKind::Missing,
3485            });
3486        }
3487        Ok(Validated::new(StreamDeclaration {
3488            shape_iri: "https://uor.foundation/conformance/StreamShape",
3489        }))
3490    }
3491}
3492
3493impl<'a, const INLINE_BYTES: usize> Default for StreamDeclarationBuilder<'a, INLINE_BYTES> {
3494    fn default() -> Self {
3495        Self::new()
3496    }
3497}
3498
3499/// Builder for `PredicateDeclaration`. Validates against `PredicateShape`.
3500#[derive(Debug, Clone)]
3501pub struct PredicateDeclarationBuilder<'a, const INLINE_BYTES: usize> {
3502    /// The `input_type` field.
3503    input_type: Option<&'a str>,
3504    /// The `evaluator` field.
3505    evaluator: Option<&'a [Term<'a, INLINE_BYTES>]>,
3506    /// The `termination_witness` field.
3507    termination_witness: Option<&'a str>,
3508}
3509
3510/// Declared predicate validated against `PredicateShape`.
3511#[derive(Debug, Clone, PartialEq, Eq)]
3512pub struct PredicateDeclaration {
3513    /// Shape IRI this declaration was validated against.
3514    pub shape_iri: &'static str,
3515}
3516
3517impl PredicateDeclaration {
3518    /// v0.2.2 Phase G: const-constructible empty form used by
3519    /// `validate_*_const` companion functions.
3520    #[inline]
3521    #[must_use]
3522    #[allow(dead_code)]
3523    pub(crate) const fn empty_const() -> Self {
3524        Self {
3525            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3526        }
3527    }
3528}
3529
3530impl<'a, const INLINE_BYTES: usize> PredicateDeclarationBuilder<'a, INLINE_BYTES> {
3531    /// Creates a new empty builder.
3532    #[must_use]
3533    pub const fn new() -> Self {
3534        Self {
3535            input_type: None,
3536            evaluator: None,
3537            termination_witness: None,
3538        }
3539    }
3540
3541    /// Set the `input_type` field.
3542    #[must_use]
3543    pub const fn input_type(mut self, value: &'a str) -> Self {
3544        self.input_type = Some(value);
3545        self
3546    }
3547
3548    /// Set the `evaluator` field.
3549    #[must_use]
3550    pub const fn evaluator(mut self, value: &'a [Term<'a, INLINE_BYTES>]) -> Self {
3551        self.evaluator = Some(value);
3552        self
3553    }
3554
3555    /// Set the `termination_witness` field.
3556    #[must_use]
3557    pub const fn termination_witness(mut self, value: &'a str) -> Self {
3558        self.termination_witness = Some(value);
3559        self
3560    }
3561
3562    /// Validate against `PredicateShape`.
3563    /// # Errors
3564    /// Returns `ShapeViolation` if any required field is missing.
3565    pub fn validate(self) -> Result<Validated<PredicateDeclaration>, ShapeViolation> {
3566        if self.input_type.is_none() {
3567            return Err(ShapeViolation {
3568                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3569                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3570                property_iri: "https://uor.foundation/conformance/input_type",
3571                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3572                min_count: 1,
3573                max_count: 1,
3574                kind: ViolationKind::Missing,
3575            });
3576        }
3577        if self.evaluator.is_none() {
3578            return Err(ShapeViolation {
3579                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3580                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3581                property_iri: "https://uor.foundation/conformance/evaluator",
3582                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3583                min_count: 1,
3584                max_count: 1,
3585                kind: ViolationKind::Missing,
3586            });
3587        }
3588        if self.termination_witness.is_none() {
3589            return Err(ShapeViolation {
3590                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3591                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3592                property_iri: "https://uor.foundation/conformance/termination_witness",
3593                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3594                min_count: 1,
3595                max_count: 1,
3596                kind: ViolationKind::Missing,
3597            });
3598        }
3599        Ok(Validated::new(PredicateDeclaration {
3600            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3601        }))
3602    }
3603
3604    /// Phase C.1: const-fn companion for `PredicateDeclarationBuilder::validate`.
3605    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3606    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3607    /// # Errors
3608    /// Returns `ShapeViolation` if any required field is missing.
3609    pub const fn validate_const(
3610        &self,
3611    ) -> Result<Validated<PredicateDeclaration, CompileTime>, ShapeViolation> {
3612        if self.input_type.is_none() {
3613            return Err(ShapeViolation {
3614                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3615                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3616                property_iri: "https://uor.foundation/conformance/input_type",
3617                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3618                min_count: 1,
3619                max_count: 1,
3620                kind: ViolationKind::Missing,
3621            });
3622        }
3623        if self.evaluator.is_none() {
3624            return Err(ShapeViolation {
3625                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3626                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3627                property_iri: "https://uor.foundation/conformance/evaluator",
3628                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3629                min_count: 1,
3630                max_count: 1,
3631                kind: ViolationKind::Missing,
3632            });
3633        }
3634        if self.termination_witness.is_none() {
3635            return Err(ShapeViolation {
3636                shape_iri: "https://uor.foundation/conformance/PredicateShape",
3637                constraint_iri: "https://uor.foundation/conformance/PredicateShape",
3638                property_iri: "https://uor.foundation/conformance/termination_witness",
3639                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3640                min_count: 1,
3641                max_count: 1,
3642                kind: ViolationKind::Missing,
3643            });
3644        }
3645        Ok(Validated::new(PredicateDeclaration {
3646            shape_iri: "https://uor.foundation/conformance/PredicateShape",
3647        }))
3648    }
3649}
3650
3651impl<'a, const INLINE_BYTES: usize> Default for PredicateDeclarationBuilder<'a, INLINE_BYTES> {
3652    fn default() -> Self {
3653        Self::new()
3654    }
3655}
3656
3657/// Builder for `ParallelDeclaration`. Validates against `ParallelShape`.
3658#[derive(Debug, Clone)]
3659pub struct ParallelDeclarationBuilder<'a> {
3660    /// The `site_partition` field.
3661    site_partition: Option<&'a [u32]>,
3662    /// The `disjointness_witness` field.
3663    disjointness_witness: Option<&'a str>,
3664}
3665
3666/// Declared parallel composition validated against `ParallelShape`.
3667#[derive(Debug, Clone, PartialEq, Eq)]
3668pub struct ParallelDeclaration {
3669    /// Shape IRI this declaration was validated against.
3670    pub shape_iri: &'static str,
3671}
3672
3673impl ParallelDeclaration {
3674    /// v0.2.2 Phase G: const-constructible empty form used by
3675    /// `validate_*_const` companion functions.
3676    #[inline]
3677    #[must_use]
3678    #[allow(dead_code)]
3679    pub(crate) const fn empty_const() -> Self {
3680        Self {
3681            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3682        }
3683    }
3684}
3685
3686impl<'a> ParallelDeclarationBuilder<'a> {
3687    /// Creates a new empty builder.
3688    #[must_use]
3689    pub const fn new() -> Self {
3690        Self {
3691            site_partition: None,
3692            disjointness_witness: None,
3693        }
3694    }
3695
3696    /// Set the `site_partition` field.
3697    #[must_use]
3698    pub const fn site_partition(mut self, value: &'a [u32]) -> Self {
3699        self.site_partition = Some(value);
3700        self
3701    }
3702
3703    /// Set the `disjointness_witness` field.
3704    #[must_use]
3705    pub const fn disjointness_witness(mut self, value: &'a str) -> Self {
3706        self.disjointness_witness = Some(value);
3707        self
3708    }
3709
3710    /// Validate against `ParallelShape`.
3711    /// # Errors
3712    /// Returns `ShapeViolation` if any required field is missing.
3713    pub fn validate(self) -> Result<Validated<ParallelDeclaration>, ShapeViolation> {
3714        if self.site_partition.is_none() {
3715            return Err(ShapeViolation {
3716                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3717                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3718                property_iri: "https://uor.foundation/conformance/site_partition",
3719                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3720                min_count: 1,
3721                max_count: 1,
3722                kind: ViolationKind::Missing,
3723            });
3724        }
3725        if self.disjointness_witness.is_none() {
3726            return Err(ShapeViolation {
3727                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3728                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3729                property_iri: "https://uor.foundation/conformance/disjointness_witness",
3730                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3731                min_count: 1,
3732                max_count: 1,
3733                kind: ViolationKind::Missing,
3734            });
3735        }
3736        Ok(Validated::new(ParallelDeclaration {
3737            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3738        }))
3739    }
3740
3741    /// Phase C.1: const-fn companion for `ParallelDeclarationBuilder::validate`.
3742    /// Returns `Validated<_, CompileTime>` on success, allowing compile-time
3743    /// evidence via `const _V: Validated<_, CompileTime> = builder.validate_const().unwrap();`.
3744    /// # Errors
3745    /// Returns `ShapeViolation` if any required field is missing.
3746    pub const fn validate_const(
3747        &self,
3748    ) -> Result<Validated<ParallelDeclaration, CompileTime>, ShapeViolation> {
3749        if self.site_partition.is_none() {
3750            return Err(ShapeViolation {
3751                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3752                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3753                property_iri: "https://uor.foundation/conformance/site_partition",
3754                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3755                min_count: 1,
3756                max_count: 1,
3757                kind: ViolationKind::Missing,
3758            });
3759        }
3760        if self.disjointness_witness.is_none() {
3761            return Err(ShapeViolation {
3762                shape_iri: "https://uor.foundation/conformance/ParallelShape",
3763                constraint_iri: "https://uor.foundation/conformance/ParallelShape",
3764                property_iri: "https://uor.foundation/conformance/disjointness_witness",
3765                expected_range: "http://www.w3.org/2002/07/owl#Thing",
3766                min_count: 1,
3767                max_count: 1,
3768                kind: ViolationKind::Missing,
3769            });
3770        }
3771        Ok(Validated::new(ParallelDeclaration {
3772            shape_iri: "https://uor.foundation/conformance/ParallelShape",
3773        }))
3774    }
3775}
3776
3777impl<'a> Default for ParallelDeclarationBuilder<'a> {
3778    fn default() -> Self {
3779        Self::new()
3780    }
3781}
3782
3783impl<'a> ParallelDeclarationBuilder<'a> {
3784    /// v0.2.2 T2.7: const-fn accessor returning the length of the
3785    /// declared site partition (or 0 if unset).
3786    #[inline]
3787    #[must_use]
3788    pub const fn site_partition_len(&self) -> usize {
3789        match self.site_partition {
3790            Some(p) => p.len(),
3791            None => 0,
3792        }
3793    }
3794
3795    /// v0.2.2 Phase A: const-fn accessor returning the declared site-partition
3796    /// slice, or an empty slice if unset. Used by `validate_parallel_const`
3797    /// to propagate the partition into the widened `ParallelDeclaration<'a>`.
3798    #[inline]
3799    #[must_use]
3800    pub const fn site_partition_slice_const(&self) -> &'a [u32] {
3801        match self.site_partition {
3802            Some(p) => p,
3803            None => &[],
3804        }
3805    }
3806
3807    /// v0.2.2 Phase A: const-fn accessor returning the declared disjointness-witness
3808    /// IRI string, or an empty string if unset.
3809    #[inline]
3810    #[must_use]
3811    pub const fn disjointness_witness_const(&self) -> &'a str {
3812        match self.disjointness_witness {
3813            Some(s) => s,
3814            None => "",
3815        }
3816    }
3817}
3818
3819impl<'a, const INLINE_BYTES: usize> StreamDeclarationBuilder<'a, INLINE_BYTES> {
3820    /// v0.2.2 canonical: productivity bound is 1 if a `productivityWitness`
3821    /// IRI is declared (the stream attests termination via a `proof:Proof`
3822    /// individual), 0 otherwise. The witness's IRI points to the termination
3823    /// proof; downstream resolvers dereference it for detailed bound
3824    /// information. This two-level split (presence flag here, IRI dereference
3825    /// elsewhere) is the canonical foundation-level shape.
3826    #[inline]
3827    #[must_use]
3828    pub const fn productivity_bound_const(&self) -> u64 {
3829        match self.productivity_witness {
3830            Some(_) => 1,
3831            None => 0,
3832        }
3833    }
3834
3835    /// v0.2.2 Phase A: const-fn accessor returning the declared seed term slice,
3836    /// or an empty slice if unset.
3837    #[inline]
3838    #[must_use]
3839    pub const fn seed_slice_const(&self) -> &'a [Term<'a, INLINE_BYTES>] {
3840        match self.seed {
3841            Some(t) => t,
3842            None => &[],
3843        }
3844    }
3845
3846    /// v0.2.2 Phase A: const-fn accessor returning the declared step term slice,
3847    /// or an empty slice if unset.
3848    #[inline]
3849    #[must_use]
3850    pub const fn step_slice_const(&self) -> &'a [Term<'a, INLINE_BYTES>] {
3851        match self.step {
3852            Some(t) => t,
3853            None => &[],
3854        }
3855    }
3856
3857    /// v0.2.2 Phase A: const-fn accessor returning the declared productivity-witness
3858    /// IRI, or an empty string if unset.
3859    #[inline]
3860    #[must_use]
3861    pub const fn productivity_witness_const(&self) -> &'a str {
3862        match self.productivity_witness {
3863            Some(s) => s,
3864            None => "",
3865        }
3866    }
3867}
3868
3869/// Builder for declaring a new Witt level beyond W32.
3870/// Validates against `WittLevelShape`.
3871#[derive(Debug, Clone)]
3872pub struct WittLevelDeclarationBuilder {
3873    /// The declared bit width.
3874    bit_width: Option<u32>,
3875    /// The declared cycle size.
3876    cycle_size: Option<u128>,
3877    /// The predecessor level.
3878    predecessor: Option<WittLevel>,
3879}
3880
3881/// Validated Witt level declaration.
3882#[derive(Debug, Clone, PartialEq, Eq)]
3883pub struct WittLevelDeclaration {
3884    /// The declared bit width.
3885    pub bit_width: u32,
3886    /// The predecessor level.
3887    pub predecessor: WittLevel,
3888}
3889
3890impl WittLevelDeclarationBuilder {
3891    /// Creates a new empty builder.
3892    #[must_use]
3893    pub const fn new() -> Self {
3894        Self {
3895            bit_width: None,
3896            cycle_size: None,
3897            predecessor: None,
3898        }
3899    }
3900
3901    /// Set the declared bit width.
3902    #[must_use]
3903    pub const fn bit_width(mut self, w: u32) -> Self {
3904        self.bit_width = Some(w);
3905        self
3906    }
3907
3908    /// Set the declared cycle size.
3909    #[must_use]
3910    pub const fn cycle_size(mut self, s: u128) -> Self {
3911        self.cycle_size = Some(s);
3912        self
3913    }
3914
3915    /// Set the predecessor Witt level.
3916    #[must_use]
3917    pub const fn predecessor(mut self, level: WittLevel) -> Self {
3918        self.predecessor = Some(level);
3919        self
3920    }
3921
3922    /// Validate against `WittLevelShape`.
3923    /// # Errors
3924    /// Returns `ShapeViolation` if any required field is missing.
3925    pub fn validate(self) -> Result<Validated<WittLevelDeclaration>, ShapeViolation> {
3926        let bw = match self.bit_width {
3927            Some(w) => w,
3928            None => {
3929                return Err(ShapeViolation {
3930                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3931                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3932                    property_iri: "https://uor.foundation/conformance/declaredBitWidth",
3933                    expected_range: "http://www.w3.org/2001/XMLSchema#positiveInteger",
3934                    min_count: 1,
3935                    max_count: 1,
3936                    kind: ViolationKind::Missing,
3937                })
3938            }
3939        };
3940        let pred = match self.predecessor {
3941            Some(p) => p,
3942            None => {
3943                return Err(ShapeViolation {
3944                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3945                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3946                    property_iri: "https://uor.foundation/conformance/predecessorLevel",
3947                    expected_range: "https://uor.foundation/schema/WittLevel",
3948                    min_count: 1,
3949                    max_count: 1,
3950                    kind: ViolationKind::Missing,
3951                })
3952            }
3953        };
3954        Ok(Validated::new(WittLevelDeclaration {
3955            bit_width: bw,
3956            predecessor: pred,
3957        }))
3958    }
3959
3960    /// Phase C.1: const-fn companion for `WittLevelDeclarationBuilder::validate`.
3961    /// # Errors
3962    /// Returns `ShapeViolation` if any required field is missing.
3963    pub const fn validate_const(
3964        &self,
3965    ) -> Result<Validated<WittLevelDeclaration, CompileTime>, ShapeViolation> {
3966        let bw = match self.bit_width {
3967            Some(w) => w,
3968            None => {
3969                return Err(ShapeViolation {
3970                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3971                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3972                    property_iri: "https://uor.foundation/conformance/declaredBitWidth",
3973                    expected_range: "http://www.w3.org/2001/XMLSchema#positiveInteger",
3974                    min_count: 1,
3975                    max_count: 1,
3976                    kind: ViolationKind::Missing,
3977                })
3978            }
3979        };
3980        let pred = match self.predecessor {
3981            Some(p) => p,
3982            None => {
3983                return Err(ShapeViolation {
3984                    shape_iri: "https://uor.foundation/conformance/WittLevelShape",
3985                    constraint_iri: "https://uor.foundation/conformance/WittLevelShape",
3986                    property_iri: "https://uor.foundation/conformance/predecessorLevel",
3987                    expected_range: "https://uor.foundation/schema/WittLevel",
3988                    min_count: 1,
3989                    max_count: 1,
3990                    kind: ViolationKind::Missing,
3991                })
3992            }
3993        };
3994        Ok(Validated::new(WittLevelDeclaration {
3995            bit_width: bw,
3996            predecessor: pred,
3997        }))
3998    }
3999}
4000
4001impl Default for WittLevelDeclarationBuilder {
4002    fn default() -> Self {
4003        Self::new()
4004    }
4005}
4006
4007/// Boundary session state tracker for the two-phase minting boundary.
4008/// Records crossing count and idempotency flag. Private fields
4009/// prevent external construction.
4010#[derive(Debug, Clone, PartialEq, Eq)]
4011pub struct BoundarySession {
4012    /// Total boundary crossings in this session.
4013    crossing_count: u32,
4014    /// Whether the boundary effect is idempotent.
4015    is_idempotent: bool,
4016}
4017
4018impl BoundarySession {
4019    /// Creates a new boundary session. Only callable within the crate.
4020    #[inline]
4021    #[allow(dead_code)]
4022    pub(crate) const fn new(is_idempotent: bool) -> Self {
4023        Self {
4024            crossing_count: 0,
4025            is_idempotent,
4026        }
4027    }
4028
4029    /// Returns the total boundary crossings.
4030    #[inline]
4031    #[must_use]
4032    pub const fn crossing_count(&self) -> u32 {
4033        self.crossing_count
4034    }
4035
4036    /// Returns whether the boundary effect is idempotent.
4037    #[inline]
4038    #[must_use]
4039    pub const fn is_idempotent(&self) -> bool {
4040        self.is_idempotent
4041    }
4042}
4043
4044/// Validate a scalar grounding intermediate against a `GroundingShape`
4045/// and mint it into a `Datum`. Only callable within `uor-foundation`.
4046/// # Errors
4047/// Returns `ShapeViolation` if the coordinate fails validation.
4048#[allow(dead_code)]
4049pub(crate) fn validate_and_mint_coord(
4050    grounded: GroundedCoord,
4051    shape: &Validated<GroundingDeclaration>,
4052    session: &mut BoundarySession,
4053) -> Result<Datum, ShapeViolation> {
4054    // The Validated<GroundingDeclaration> proves the shape was already
4055    // validated at builder time. The coordinate's level is guaranteed
4056    // correct by the closed GroundedCoordInner enum — the type system
4057    // enforces that only supported levels can be constructed.
4058    let _ = shape; // shape validation passed at builder time
4059    session.crossing_count += 1;
4060    let inner = match grounded.inner {
4061        GroundedCoordInner::W8(b) => DatumInner::W8(b),
4062        GroundedCoordInner::W16(b) => DatumInner::W16(b),
4063        GroundedCoordInner::W24(b) => DatumInner::W24(b),
4064        GroundedCoordInner::W32(b) => DatumInner::W32(b),
4065        GroundedCoordInner::W40(b) => DatumInner::W40(b),
4066        GroundedCoordInner::W48(b) => DatumInner::W48(b),
4067        GroundedCoordInner::W56(b) => DatumInner::W56(b),
4068        GroundedCoordInner::W64(b) => DatumInner::W64(b),
4069        GroundedCoordInner::W72(b) => DatumInner::W72(b),
4070        GroundedCoordInner::W80(b) => DatumInner::W80(b),
4071        GroundedCoordInner::W88(b) => DatumInner::W88(b),
4072        GroundedCoordInner::W96(b) => DatumInner::W96(b),
4073        GroundedCoordInner::W104(b) => DatumInner::W104(b),
4074        GroundedCoordInner::W112(b) => DatumInner::W112(b),
4075        GroundedCoordInner::W120(b) => DatumInner::W120(b),
4076        GroundedCoordInner::W128(b) => DatumInner::W128(b),
4077    };
4078    Ok(Datum { inner })
4079}
4080
4081/// Validate a tuple grounding intermediate and mint into a `Datum`.
4082/// Only callable within `uor-foundation`.
4083/// Mints the first coordinate of the tuple as the representative `Datum`.
4084/// Composite multi-coordinate `Datum` construction depends on the target
4085/// type's site decomposition, which is resolved during reduction evaluation.
4086/// # Errors
4087/// Returns `ShapeViolation` if the tuple is empty or fails validation.
4088#[allow(dead_code)]
4089pub(crate) fn validate_and_mint_tuple<const N: usize>(
4090    grounded: GroundedTuple<N>,
4091    shape: &Validated<GroundingDeclaration>,
4092    session: &mut BoundarySession,
4093) -> Result<Datum, ShapeViolation> {
4094    if N == 0 {
4095        return Err(ShapeViolation {
4096            shape_iri: shape.inner().shape_iri,
4097            constraint_iri: shape.inner().shape_iri,
4098            property_iri: "https://uor.foundation/conformance/groundingSourceType",
4099            expected_range: "https://uor.foundation/type/TypeDefinition",
4100            min_count: 1,
4101            max_count: 0,
4102            kind: ViolationKind::CardinalityViolation,
4103        });
4104    }
4105    // Mint the first coordinate as the representative Datum.
4106    // The full tuple is decomposed during reduction evaluation,
4107    // where each coordinate maps to a site in the constrained type.
4108    validate_and_mint_coord(grounded.coords[0].clone(), shape, session)
4109}
4110
4111/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Datum`.
4112/// Takes host bytes that have already passed the author's `Grounding` impl and
4113/// mints them into a sealed `Datum` at the supplied Witt level. The bytes are
4114/// decoded according to the level's byte width.
4115/// # Errors
4116/// Returns [`ShapeViolation`] if `bytes.len()` doesn't match the level's byte width
4117/// or if the level is unsupported.
4118pub fn mint_datum(level: crate::WittLevel, bytes: &[u8]) -> Result<Datum, ShapeViolation> {
4119    let expected_bytes = (level.witt_length() / 8) as usize;
4120    if bytes.len() != expected_bytes {
4121        return Err(ShapeViolation {
4122            shape_iri: "https://uor.foundation/u/Datum",
4123            constraint_iri: "https://uor.foundation/u/DatumByteWidth",
4124            property_iri: "https://uor.foundation/u/datumBytes",
4125            expected_range: "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
4126            min_count: expected_bytes as u32,
4127            max_count: expected_bytes as u32,
4128            kind: crate::ViolationKind::CardinalityViolation,
4129        });
4130    }
4131    let inner = match level.witt_length() {
4132        8 => {
4133            let mut buf = [0u8; 1];
4134            let mut i = 0;
4135            while i < 1 {
4136                buf[i] = bytes[i];
4137                i += 1;
4138            }
4139            DatumInner::W8(buf)
4140        }
4141        16 => {
4142            let mut buf = [0u8; 2];
4143            let mut i = 0;
4144            while i < 2 {
4145                buf[i] = bytes[i];
4146                i += 1;
4147            }
4148            DatumInner::W16(buf)
4149        }
4150        24 => {
4151            let mut buf = [0u8; 3];
4152            let mut i = 0;
4153            while i < 3 {
4154                buf[i] = bytes[i];
4155                i += 1;
4156            }
4157            DatumInner::W24(buf)
4158        }
4159        32 => {
4160            let mut buf = [0u8; 4];
4161            let mut i = 0;
4162            while i < 4 {
4163                buf[i] = bytes[i];
4164                i += 1;
4165            }
4166            DatumInner::W32(buf)
4167        }
4168        40 => {
4169            let mut buf = [0u8; 5];
4170            let mut i = 0;
4171            while i < 5 {
4172                buf[i] = bytes[i];
4173                i += 1;
4174            }
4175            DatumInner::W40(buf)
4176        }
4177        48 => {
4178            let mut buf = [0u8; 6];
4179            let mut i = 0;
4180            while i < 6 {
4181                buf[i] = bytes[i];
4182                i += 1;
4183            }
4184            DatumInner::W48(buf)
4185        }
4186        56 => {
4187            let mut buf = [0u8; 7];
4188            let mut i = 0;
4189            while i < 7 {
4190                buf[i] = bytes[i];
4191                i += 1;
4192            }
4193            DatumInner::W56(buf)
4194        }
4195        64 => {
4196            let mut buf = [0u8; 8];
4197            let mut i = 0;
4198            while i < 8 {
4199                buf[i] = bytes[i];
4200                i += 1;
4201            }
4202            DatumInner::W64(buf)
4203        }
4204        72 => {
4205            let mut buf = [0u8; 9];
4206            let mut i = 0;
4207            while i < 9 {
4208                buf[i] = bytes[i];
4209                i += 1;
4210            }
4211            DatumInner::W72(buf)
4212        }
4213        80 => {
4214            let mut buf = [0u8; 10];
4215            let mut i = 0;
4216            while i < 10 {
4217                buf[i] = bytes[i];
4218                i += 1;
4219            }
4220            DatumInner::W80(buf)
4221        }
4222        88 => {
4223            let mut buf = [0u8; 11];
4224            let mut i = 0;
4225            while i < 11 {
4226                buf[i] = bytes[i];
4227                i += 1;
4228            }
4229            DatumInner::W88(buf)
4230        }
4231        96 => {
4232            let mut buf = [0u8; 12];
4233            let mut i = 0;
4234            while i < 12 {
4235                buf[i] = bytes[i];
4236                i += 1;
4237            }
4238            DatumInner::W96(buf)
4239        }
4240        104 => {
4241            let mut buf = [0u8; 13];
4242            let mut i = 0;
4243            while i < 13 {
4244                buf[i] = bytes[i];
4245                i += 1;
4246            }
4247            DatumInner::W104(buf)
4248        }
4249        112 => {
4250            let mut buf = [0u8; 14];
4251            let mut i = 0;
4252            while i < 14 {
4253                buf[i] = bytes[i];
4254                i += 1;
4255            }
4256            DatumInner::W112(buf)
4257        }
4258        120 => {
4259            let mut buf = [0u8; 15];
4260            let mut i = 0;
4261            while i < 15 {
4262                buf[i] = bytes[i];
4263                i += 1;
4264            }
4265            DatumInner::W120(buf)
4266        }
4267        128 => {
4268            let mut buf = [0u8; 16];
4269            let mut i = 0;
4270            while i < 16 {
4271                buf[i] = bytes[i];
4272                i += 1;
4273            }
4274            DatumInner::W128(buf)
4275        }
4276        _ => {
4277            return Err(ShapeViolation {
4278                shape_iri: "https://uor.foundation/u/Datum",
4279                constraint_iri: "https://uor.foundation/u/DatumLevel",
4280                property_iri: "https://uor.foundation/u/datumLevel",
4281                expected_range: "https://uor.foundation/schema/WittLevel",
4282                min_count: 1,
4283                max_count: 1,
4284                kind: crate::ViolationKind::ValueCheck,
4285            })
4286        }
4287    };
4288    Ok(Datum { inner })
4289}
4290
4291/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Triad<L>`.
4292/// Takes three coordinate values that satisfy the Triad shape constraint and
4293/// mints them into a sealed `Triad<L>` at the level marker `L`.
4294#[must_use]
4295pub const fn mint_triad<L>(stratum: u64, spectrum: u64, address: u64) -> Triad<L> {
4296    Triad::new(stratum, spectrum, address)
4297}
4298
4299/// Wiki ADR-016 mint primitive: cross-crate construction surface for `Derivation`.
4300/// Takes the precursor's step count + Witt level + content fingerprint and mints
4301/// a sealed `Derivation` carrying the typed transition witness.
4302#[must_use]
4303pub const fn mint_derivation(
4304    step_count: u32,
4305    witt_level_bits: u16,
4306    content_fingerprint: ContentFingerprint,
4307) -> Derivation {
4308    Derivation::new(step_count, witt_level_bits, content_fingerprint)
4309}
4310
4311/// Wiki ADR-016 mint primitive: cross-crate construction surface for `FreeRank`.
4312/// Takes a natural-number rank witness (total site capacity at the Witt level plus
4313/// the number of currently pinned sites) and mints it into a sealed `FreeRank`.
4314#[must_use]
4315pub const fn mint_freerank(total: u32, pinned: u32) -> FreeRank {
4316    FreeRank::new(total, pinned)
4317}
4318
4319/// Evaluate a binary ring operation at compile time.
4320/// One helper is emitted per `schema:WittLevel` individual. The `uor!`
4321/// proc macro delegates to these helpers; it never performs ring
4322/// arithmetic itself.
4323/// # Examples
4324/// ```rust
4325/// use uor_foundation::enforcement::{const_ring_eval_w8, const_ring_eval_unary_w8};
4326/// use uor_foundation::PrimitiveOp;
4327///
4328/// // Ring arithmetic in Z/256Z: all operations wrap modulo 256.
4329///
4330/// // Addition wraps: 200 + 100 = 300 -> 300 - 256 = 44
4331/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Add, 200, 100), 44);
4332///
4333/// // Multiplication: 3 * 5 = 15 (no wrap needed)
4334/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Mul, 3, 5), 15);
4335///
4336/// // XOR: bitwise exclusive-or
4337/// assert_eq!(const_ring_eval_w8(PrimitiveOp::Xor, 0b1010, 0b1100), 0b0110);
4338///
4339/// // Negation: neg(x) = 256 - x (additive inverse in Z/256Z)
4340/// assert_eq!(const_ring_eval_unary_w8(PrimitiveOp::Neg, 1), 255);
4341///
4342/// // The critical identity: neg(bnot(x)) = succ(x) for all x
4343/// let x = 42u8;
4344/// let lhs = const_ring_eval_unary_w8(PrimitiveOp::Neg,
4345///     const_ring_eval_unary_w8(PrimitiveOp::Bnot, x));
4346/// let rhs = const_ring_eval_unary_w8(PrimitiveOp::Succ, x);
4347/// assert_eq!(lhs, rhs);
4348/// ```
4349#[inline]
4350#[must_use]
4351#[allow(clippy::manual_checked_ops)]
4352pub const fn const_ring_eval_w8(op: PrimitiveOp, a: u8, b: u8) -> u8 {
4353    match op {
4354        PrimitiveOp::Add => a.wrapping_add(b),
4355        PrimitiveOp::Sub => a.wrapping_sub(b),
4356        PrimitiveOp::Mul => a.wrapping_mul(b),
4357        PrimitiveOp::Xor => a ^ b,
4358        PrimitiveOp::And => a & b,
4359        PrimitiveOp::Or => a | b,
4360        PrimitiveOp::Le => (a <= b) as u8,
4361        PrimitiveOp::Lt => (a < b) as u8,
4362        PrimitiveOp::Ge => (a >= b) as u8,
4363        PrimitiveOp::Gt => (a > b) as u8,
4364        PrimitiveOp::Concat => 0,
4365        PrimitiveOp::Div => {
4366            if b == 0 {
4367                0
4368            } else {
4369                a / b
4370            }
4371        }
4372        PrimitiveOp::Mod => {
4373            if b == 0 {
4374                0
4375            } else {
4376                a % b
4377            }
4378        }
4379        PrimitiveOp::Pow => const_pow_w8(a, b),
4380        _ => 0,
4381    }
4382}
4383
4384#[inline]
4385#[must_use]
4386pub const fn const_pow_w8(base: u8, exp: u8) -> u8 {
4387    let mut result: u8 = 1;
4388    let mut b: u8 = base;
4389    let mut e: u8 = exp;
4390    while e > 0 {
4391        if (e & 1) == 1 {
4392            result = result.wrapping_mul(b);
4393        }
4394        b = b.wrapping_mul(b);
4395        e >>= 1;
4396    }
4397    result
4398}
4399
4400#[inline]
4401#[must_use]
4402pub const fn const_ring_eval_unary_w8(op: PrimitiveOp, a: u8) -> u8 {
4403    match op {
4404        PrimitiveOp::Neg => 0u8.wrapping_sub(a),
4405        PrimitiveOp::Bnot => !a,
4406        PrimitiveOp::Succ => a.wrapping_add(1),
4407        PrimitiveOp::Pred => a.wrapping_sub(1),
4408        _ => 0,
4409    }
4410}
4411
4412#[inline]
4413#[must_use]
4414#[allow(clippy::manual_checked_ops)]
4415pub const fn const_ring_eval_w16(op: PrimitiveOp, a: u16, b: u16) -> u16 {
4416    match op {
4417        PrimitiveOp::Add => a.wrapping_add(b),
4418        PrimitiveOp::Sub => a.wrapping_sub(b),
4419        PrimitiveOp::Mul => a.wrapping_mul(b),
4420        PrimitiveOp::Xor => a ^ b,
4421        PrimitiveOp::And => a & b,
4422        PrimitiveOp::Or => a | b,
4423        PrimitiveOp::Le => (a <= b) as u16,
4424        PrimitiveOp::Lt => (a < b) as u16,
4425        PrimitiveOp::Ge => (a >= b) as u16,
4426        PrimitiveOp::Gt => (a > b) as u16,
4427        PrimitiveOp::Concat => 0,
4428        PrimitiveOp::Div => {
4429            if b == 0 {
4430                0
4431            } else {
4432                a / b
4433            }
4434        }
4435        PrimitiveOp::Mod => {
4436            if b == 0 {
4437                0
4438            } else {
4439                a % b
4440            }
4441        }
4442        PrimitiveOp::Pow => const_pow_w16(a, b),
4443        _ => 0,
4444    }
4445}
4446
4447#[inline]
4448#[must_use]
4449pub const fn const_pow_w16(base: u16, exp: u16) -> u16 {
4450    let mut result: u16 = 1;
4451    let mut b: u16 = base;
4452    let mut e: u16 = exp;
4453    while e > 0 {
4454        if (e & 1) == 1 {
4455            result = result.wrapping_mul(b);
4456        }
4457        b = b.wrapping_mul(b);
4458        e >>= 1;
4459    }
4460    result
4461}
4462
4463#[inline]
4464#[must_use]
4465pub const fn const_ring_eval_unary_w16(op: PrimitiveOp, a: u16) -> u16 {
4466    match op {
4467        PrimitiveOp::Neg => 0u16.wrapping_sub(a),
4468        PrimitiveOp::Bnot => !a,
4469        PrimitiveOp::Succ => a.wrapping_add(1),
4470        PrimitiveOp::Pred => a.wrapping_sub(1),
4471        _ => 0,
4472    }
4473}
4474
4475#[inline]
4476#[must_use]
4477#[allow(clippy::manual_checked_ops)]
4478pub const fn const_ring_eval_w24(op: PrimitiveOp, a: u32, b: u32) -> u32 {
4479    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4480    match op {
4481        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4482        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4483        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4484        PrimitiveOp::Xor => (a ^ b) & MASK,
4485        PrimitiveOp::And => (a & b) & MASK,
4486        PrimitiveOp::Or => (a | b) & MASK,
4487        PrimitiveOp::Le => (a <= b) as u32,
4488        PrimitiveOp::Lt => (a < b) as u32,
4489        PrimitiveOp::Ge => (a >= b) as u32,
4490        PrimitiveOp::Gt => (a > b) as u32,
4491        PrimitiveOp::Concat => 0,
4492        PrimitiveOp::Div => {
4493            if b == 0 {
4494                0
4495            } else {
4496                (a / b) & MASK
4497            }
4498        }
4499        PrimitiveOp::Mod => {
4500            if b == 0 {
4501                0
4502            } else {
4503                (a % b) & MASK
4504            }
4505        }
4506        PrimitiveOp::Pow => (const_pow_w24(a, b)) & MASK,
4507        _ => 0,
4508    }
4509}
4510
4511#[inline]
4512#[must_use]
4513pub const fn const_pow_w24(base: u32, exp: u32) -> u32 {
4514    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4515    let mut result: u32 = 1;
4516    let mut b: u32 = (base) & MASK;
4517    let mut e: u32 = exp;
4518    while e > 0 {
4519        if (e & 1) == 1 {
4520            result = (result.wrapping_mul(b)) & MASK;
4521        }
4522        b = (b.wrapping_mul(b)) & MASK;
4523        e >>= 1;
4524    }
4525    result
4526}
4527
4528#[inline]
4529#[must_use]
4530pub const fn const_ring_eval_unary_w24(op: PrimitiveOp, a: u32) -> u32 {
4531    const MASK: u32 = (u64::MAX >> (64 - 24)) as u32;
4532    match op {
4533        PrimitiveOp::Neg => (0u32.wrapping_sub(a)) & MASK,
4534        PrimitiveOp::Bnot => (!a) & MASK,
4535        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4536        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4537        _ => 0,
4538    }
4539}
4540
4541#[inline]
4542#[must_use]
4543#[allow(clippy::manual_checked_ops)]
4544pub const fn const_ring_eval_w32(op: PrimitiveOp, a: u32, b: u32) -> u32 {
4545    match op {
4546        PrimitiveOp::Add => a.wrapping_add(b),
4547        PrimitiveOp::Sub => a.wrapping_sub(b),
4548        PrimitiveOp::Mul => a.wrapping_mul(b),
4549        PrimitiveOp::Xor => a ^ b,
4550        PrimitiveOp::And => a & b,
4551        PrimitiveOp::Or => a | b,
4552        PrimitiveOp::Le => (a <= b) as u32,
4553        PrimitiveOp::Lt => (a < b) as u32,
4554        PrimitiveOp::Ge => (a >= b) as u32,
4555        PrimitiveOp::Gt => (a > b) as u32,
4556        PrimitiveOp::Concat => 0,
4557        PrimitiveOp::Div => {
4558            if b == 0 {
4559                0
4560            } else {
4561                a / b
4562            }
4563        }
4564        PrimitiveOp::Mod => {
4565            if b == 0 {
4566                0
4567            } else {
4568                a % b
4569            }
4570        }
4571        PrimitiveOp::Pow => const_pow_w32(a, b),
4572        _ => 0,
4573    }
4574}
4575
4576#[inline]
4577#[must_use]
4578pub const fn const_pow_w32(base: u32, exp: u32) -> u32 {
4579    let mut result: u32 = 1;
4580    let mut b: u32 = base;
4581    let mut e: u32 = exp;
4582    while e > 0 {
4583        if (e & 1) == 1 {
4584            result = result.wrapping_mul(b);
4585        }
4586        b = b.wrapping_mul(b);
4587        e >>= 1;
4588    }
4589    result
4590}
4591
4592#[inline]
4593#[must_use]
4594pub const fn const_ring_eval_unary_w32(op: PrimitiveOp, a: u32) -> u32 {
4595    match op {
4596        PrimitiveOp::Neg => 0u32.wrapping_sub(a),
4597        PrimitiveOp::Bnot => !a,
4598        PrimitiveOp::Succ => a.wrapping_add(1),
4599        PrimitiveOp::Pred => a.wrapping_sub(1),
4600        _ => 0,
4601    }
4602}
4603
4604#[inline]
4605#[must_use]
4606#[allow(clippy::manual_checked_ops)]
4607pub const fn const_ring_eval_w40(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4608    const MASK: u64 = u64::MAX >> (64 - 40);
4609    match op {
4610        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4611        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4612        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4613        PrimitiveOp::Xor => (a ^ b) & MASK,
4614        PrimitiveOp::And => (a & b) & MASK,
4615        PrimitiveOp::Or => (a | b) & MASK,
4616        PrimitiveOp::Le => (a <= b) as u64,
4617        PrimitiveOp::Lt => (a < b) as u64,
4618        PrimitiveOp::Ge => (a >= b) as u64,
4619        PrimitiveOp::Gt => (a > b) as u64,
4620        PrimitiveOp::Concat => 0,
4621        PrimitiveOp::Div => {
4622            if b == 0 {
4623                0
4624            } else {
4625                (a / b) & MASK
4626            }
4627        }
4628        PrimitiveOp::Mod => {
4629            if b == 0 {
4630                0
4631            } else {
4632                (a % b) & MASK
4633            }
4634        }
4635        PrimitiveOp::Pow => (const_pow_w40(a, b)) & MASK,
4636        _ => 0,
4637    }
4638}
4639
4640#[inline]
4641#[must_use]
4642pub const fn const_pow_w40(base: u64, exp: u64) -> u64 {
4643    const MASK: u64 = u64::MAX >> (64 - 40);
4644    let mut result: u64 = 1;
4645    let mut b: u64 = (base) & MASK;
4646    let mut e: u64 = exp;
4647    while e > 0 {
4648        if (e & 1) == 1 {
4649            result = (result.wrapping_mul(b)) & MASK;
4650        }
4651        b = (b.wrapping_mul(b)) & MASK;
4652        e >>= 1;
4653    }
4654    result
4655}
4656
4657#[inline]
4658#[must_use]
4659pub const fn const_ring_eval_unary_w40(op: PrimitiveOp, a: u64) -> u64 {
4660    const MASK: u64 = u64::MAX >> (64 - 40);
4661    match op {
4662        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4663        PrimitiveOp::Bnot => (!a) & MASK,
4664        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4665        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4666        _ => 0,
4667    }
4668}
4669
4670#[inline]
4671#[must_use]
4672#[allow(clippy::manual_checked_ops)]
4673pub const fn const_ring_eval_w48(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4674    const MASK: u64 = u64::MAX >> (64 - 48);
4675    match op {
4676        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4677        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4678        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4679        PrimitiveOp::Xor => (a ^ b) & MASK,
4680        PrimitiveOp::And => (a & b) & MASK,
4681        PrimitiveOp::Or => (a | b) & MASK,
4682        PrimitiveOp::Le => (a <= b) as u64,
4683        PrimitiveOp::Lt => (a < b) as u64,
4684        PrimitiveOp::Ge => (a >= b) as u64,
4685        PrimitiveOp::Gt => (a > b) as u64,
4686        PrimitiveOp::Concat => 0,
4687        PrimitiveOp::Div => {
4688            if b == 0 {
4689                0
4690            } else {
4691                (a / b) & MASK
4692            }
4693        }
4694        PrimitiveOp::Mod => {
4695            if b == 0 {
4696                0
4697            } else {
4698                (a % b) & MASK
4699            }
4700        }
4701        PrimitiveOp::Pow => (const_pow_w48(a, b)) & MASK,
4702        _ => 0,
4703    }
4704}
4705
4706#[inline]
4707#[must_use]
4708pub const fn const_pow_w48(base: u64, exp: u64) -> u64 {
4709    const MASK: u64 = u64::MAX >> (64 - 48);
4710    let mut result: u64 = 1;
4711    let mut b: u64 = (base) & MASK;
4712    let mut e: u64 = exp;
4713    while e > 0 {
4714        if (e & 1) == 1 {
4715            result = (result.wrapping_mul(b)) & MASK;
4716        }
4717        b = (b.wrapping_mul(b)) & MASK;
4718        e >>= 1;
4719    }
4720    result
4721}
4722
4723#[inline]
4724#[must_use]
4725pub const fn const_ring_eval_unary_w48(op: PrimitiveOp, a: u64) -> u64 {
4726    const MASK: u64 = u64::MAX >> (64 - 48);
4727    match op {
4728        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4729        PrimitiveOp::Bnot => (!a) & MASK,
4730        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4731        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4732        _ => 0,
4733    }
4734}
4735
4736#[inline]
4737#[must_use]
4738#[allow(clippy::manual_checked_ops)]
4739pub const fn const_ring_eval_w56(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4740    const MASK: u64 = u64::MAX >> (64 - 56);
4741    match op {
4742        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4743        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4744        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4745        PrimitiveOp::Xor => (a ^ b) & MASK,
4746        PrimitiveOp::And => (a & b) & MASK,
4747        PrimitiveOp::Or => (a | b) & MASK,
4748        PrimitiveOp::Le => (a <= b) as u64,
4749        PrimitiveOp::Lt => (a < b) as u64,
4750        PrimitiveOp::Ge => (a >= b) as u64,
4751        PrimitiveOp::Gt => (a > b) as u64,
4752        PrimitiveOp::Concat => 0,
4753        PrimitiveOp::Div => {
4754            if b == 0 {
4755                0
4756            } else {
4757                (a / b) & MASK
4758            }
4759        }
4760        PrimitiveOp::Mod => {
4761            if b == 0 {
4762                0
4763            } else {
4764                (a % b) & MASK
4765            }
4766        }
4767        PrimitiveOp::Pow => (const_pow_w56(a, b)) & MASK,
4768        _ => 0,
4769    }
4770}
4771
4772#[inline]
4773#[must_use]
4774pub const fn const_pow_w56(base: u64, exp: u64) -> u64 {
4775    const MASK: u64 = u64::MAX >> (64 - 56);
4776    let mut result: u64 = 1;
4777    let mut b: u64 = (base) & MASK;
4778    let mut e: u64 = exp;
4779    while e > 0 {
4780        if (e & 1) == 1 {
4781            result = (result.wrapping_mul(b)) & MASK;
4782        }
4783        b = (b.wrapping_mul(b)) & MASK;
4784        e >>= 1;
4785    }
4786    result
4787}
4788
4789#[inline]
4790#[must_use]
4791pub const fn const_ring_eval_unary_w56(op: PrimitiveOp, a: u64) -> u64 {
4792    const MASK: u64 = u64::MAX >> (64 - 56);
4793    match op {
4794        PrimitiveOp::Neg => (0u64.wrapping_sub(a)) & MASK,
4795        PrimitiveOp::Bnot => (!a) & MASK,
4796        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4797        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4798        _ => 0,
4799    }
4800}
4801
4802#[inline]
4803#[must_use]
4804#[allow(clippy::manual_checked_ops)]
4805pub const fn const_ring_eval_w64(op: PrimitiveOp, a: u64, b: u64) -> u64 {
4806    match op {
4807        PrimitiveOp::Add => a.wrapping_add(b),
4808        PrimitiveOp::Sub => a.wrapping_sub(b),
4809        PrimitiveOp::Mul => a.wrapping_mul(b),
4810        PrimitiveOp::Xor => a ^ b,
4811        PrimitiveOp::And => a & b,
4812        PrimitiveOp::Or => a | b,
4813        PrimitiveOp::Le => (a <= b) as u64,
4814        PrimitiveOp::Lt => (a < b) as u64,
4815        PrimitiveOp::Ge => (a >= b) as u64,
4816        PrimitiveOp::Gt => (a > b) as u64,
4817        PrimitiveOp::Concat => 0,
4818        PrimitiveOp::Div => {
4819            if b == 0 {
4820                0
4821            } else {
4822                a / b
4823            }
4824        }
4825        PrimitiveOp::Mod => {
4826            if b == 0 {
4827                0
4828            } else {
4829                a % b
4830            }
4831        }
4832        PrimitiveOp::Pow => const_pow_w64(a, b),
4833        _ => 0,
4834    }
4835}
4836
4837#[inline]
4838#[must_use]
4839pub const fn const_pow_w64(base: u64, exp: u64) -> u64 {
4840    let mut result: u64 = 1;
4841    let mut b: u64 = base;
4842    let mut e: u64 = exp;
4843    while e > 0 {
4844        if (e & 1) == 1 {
4845            result = result.wrapping_mul(b);
4846        }
4847        b = b.wrapping_mul(b);
4848        e >>= 1;
4849    }
4850    result
4851}
4852
4853#[inline]
4854#[must_use]
4855pub const fn const_ring_eval_unary_w64(op: PrimitiveOp, a: u64) -> u64 {
4856    match op {
4857        PrimitiveOp::Neg => 0u64.wrapping_sub(a),
4858        PrimitiveOp::Bnot => !a,
4859        PrimitiveOp::Succ => a.wrapping_add(1),
4860        PrimitiveOp::Pred => a.wrapping_sub(1),
4861        _ => 0,
4862    }
4863}
4864
4865#[inline]
4866#[must_use]
4867#[allow(clippy::manual_checked_ops)]
4868pub const fn const_ring_eval_w72(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4869    const MASK: u128 = u128::MAX >> (128 - 72);
4870    match op {
4871        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4872        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4873        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4874        PrimitiveOp::Xor => (a ^ b) & MASK,
4875        PrimitiveOp::And => (a & b) & MASK,
4876        PrimitiveOp::Or => (a | b) & MASK,
4877        PrimitiveOp::Le => (a <= b) as u128,
4878        PrimitiveOp::Lt => (a < b) as u128,
4879        PrimitiveOp::Ge => (a >= b) as u128,
4880        PrimitiveOp::Gt => (a > b) as u128,
4881        PrimitiveOp::Concat => 0,
4882        PrimitiveOp::Div => {
4883            if b == 0 {
4884                0
4885            } else {
4886                (a / b) & MASK
4887            }
4888        }
4889        PrimitiveOp::Mod => {
4890            if b == 0 {
4891                0
4892            } else {
4893                (a % b) & MASK
4894            }
4895        }
4896        PrimitiveOp::Pow => (const_pow_w72(a, b)) & MASK,
4897        _ => 0,
4898    }
4899}
4900
4901#[inline]
4902#[must_use]
4903pub const fn const_pow_w72(base: u128, exp: u128) -> u128 {
4904    const MASK: u128 = u128::MAX >> (128 - 72);
4905    let mut result: u128 = 1;
4906    let mut b: u128 = (base) & MASK;
4907    let mut e: u128 = exp;
4908    while e > 0 {
4909        if (e & 1) == 1 {
4910            result = (result.wrapping_mul(b)) & MASK;
4911        }
4912        b = (b.wrapping_mul(b)) & MASK;
4913        e >>= 1;
4914    }
4915    result
4916}
4917
4918#[inline]
4919#[must_use]
4920pub const fn const_ring_eval_unary_w72(op: PrimitiveOp, a: u128) -> u128 {
4921    const MASK: u128 = u128::MAX >> (128 - 72);
4922    match op {
4923        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
4924        PrimitiveOp::Bnot => (!a) & MASK,
4925        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4926        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4927        _ => 0,
4928    }
4929}
4930
4931#[inline]
4932#[must_use]
4933#[allow(clippy::manual_checked_ops)]
4934pub const fn const_ring_eval_w80(op: PrimitiveOp, a: u128, b: u128) -> u128 {
4935    const MASK: u128 = u128::MAX >> (128 - 80);
4936    match op {
4937        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
4938        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
4939        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
4940        PrimitiveOp::Xor => (a ^ b) & MASK,
4941        PrimitiveOp::And => (a & b) & MASK,
4942        PrimitiveOp::Or => (a | b) & MASK,
4943        PrimitiveOp::Le => (a <= b) as u128,
4944        PrimitiveOp::Lt => (a < b) as u128,
4945        PrimitiveOp::Ge => (a >= b) as u128,
4946        PrimitiveOp::Gt => (a > b) as u128,
4947        PrimitiveOp::Concat => 0,
4948        PrimitiveOp::Div => {
4949            if b == 0 {
4950                0
4951            } else {
4952                (a / b) & MASK
4953            }
4954        }
4955        PrimitiveOp::Mod => {
4956            if b == 0 {
4957                0
4958            } else {
4959                (a % b) & MASK
4960            }
4961        }
4962        PrimitiveOp::Pow => (const_pow_w80(a, b)) & MASK,
4963        _ => 0,
4964    }
4965}
4966
4967#[inline]
4968#[must_use]
4969pub const fn const_pow_w80(base: u128, exp: u128) -> u128 {
4970    const MASK: u128 = u128::MAX >> (128 - 80);
4971    let mut result: u128 = 1;
4972    let mut b: u128 = (base) & MASK;
4973    let mut e: u128 = exp;
4974    while e > 0 {
4975        if (e & 1) == 1 {
4976            result = (result.wrapping_mul(b)) & MASK;
4977        }
4978        b = (b.wrapping_mul(b)) & MASK;
4979        e >>= 1;
4980    }
4981    result
4982}
4983
4984#[inline]
4985#[must_use]
4986pub const fn const_ring_eval_unary_w80(op: PrimitiveOp, a: u128) -> u128 {
4987    const MASK: u128 = u128::MAX >> (128 - 80);
4988    match op {
4989        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
4990        PrimitiveOp::Bnot => (!a) & MASK,
4991        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
4992        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
4993        _ => 0,
4994    }
4995}
4996
4997#[inline]
4998#[must_use]
4999#[allow(clippy::manual_checked_ops)]
5000pub const fn const_ring_eval_w88(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5001    const MASK: u128 = u128::MAX >> (128 - 88);
5002    match op {
5003        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5004        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5005        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5006        PrimitiveOp::Xor => (a ^ b) & MASK,
5007        PrimitiveOp::And => (a & b) & MASK,
5008        PrimitiveOp::Or => (a | b) & MASK,
5009        PrimitiveOp::Le => (a <= b) as u128,
5010        PrimitiveOp::Lt => (a < b) as u128,
5011        PrimitiveOp::Ge => (a >= b) as u128,
5012        PrimitiveOp::Gt => (a > b) as u128,
5013        PrimitiveOp::Concat => 0,
5014        PrimitiveOp::Div => {
5015            if b == 0 {
5016                0
5017            } else {
5018                (a / b) & MASK
5019            }
5020        }
5021        PrimitiveOp::Mod => {
5022            if b == 0 {
5023                0
5024            } else {
5025                (a % b) & MASK
5026            }
5027        }
5028        PrimitiveOp::Pow => (const_pow_w88(a, b)) & MASK,
5029        _ => 0,
5030    }
5031}
5032
5033#[inline]
5034#[must_use]
5035pub const fn const_pow_w88(base: u128, exp: u128) -> u128 {
5036    const MASK: u128 = u128::MAX >> (128 - 88);
5037    let mut result: u128 = 1;
5038    let mut b: u128 = (base) & MASK;
5039    let mut e: u128 = exp;
5040    while e > 0 {
5041        if (e & 1) == 1 {
5042            result = (result.wrapping_mul(b)) & MASK;
5043        }
5044        b = (b.wrapping_mul(b)) & MASK;
5045        e >>= 1;
5046    }
5047    result
5048}
5049
5050#[inline]
5051#[must_use]
5052pub const fn const_ring_eval_unary_w88(op: PrimitiveOp, a: u128) -> u128 {
5053    const MASK: u128 = u128::MAX >> (128 - 88);
5054    match op {
5055        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5056        PrimitiveOp::Bnot => (!a) & MASK,
5057        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5058        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5059        _ => 0,
5060    }
5061}
5062
5063#[inline]
5064#[must_use]
5065#[allow(clippy::manual_checked_ops)]
5066pub const fn const_ring_eval_w96(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5067    const MASK: u128 = u128::MAX >> (128 - 96);
5068    match op {
5069        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5070        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5071        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5072        PrimitiveOp::Xor => (a ^ b) & MASK,
5073        PrimitiveOp::And => (a & b) & MASK,
5074        PrimitiveOp::Or => (a | b) & MASK,
5075        PrimitiveOp::Le => (a <= b) as u128,
5076        PrimitiveOp::Lt => (a < b) as u128,
5077        PrimitiveOp::Ge => (a >= b) as u128,
5078        PrimitiveOp::Gt => (a > b) as u128,
5079        PrimitiveOp::Concat => 0,
5080        PrimitiveOp::Div => {
5081            if b == 0 {
5082                0
5083            } else {
5084                (a / b) & MASK
5085            }
5086        }
5087        PrimitiveOp::Mod => {
5088            if b == 0 {
5089                0
5090            } else {
5091                (a % b) & MASK
5092            }
5093        }
5094        PrimitiveOp::Pow => (const_pow_w96(a, b)) & MASK,
5095        _ => 0,
5096    }
5097}
5098
5099#[inline]
5100#[must_use]
5101pub const fn const_pow_w96(base: u128, exp: u128) -> u128 {
5102    const MASK: u128 = u128::MAX >> (128 - 96);
5103    let mut result: u128 = 1;
5104    let mut b: u128 = (base) & MASK;
5105    let mut e: u128 = exp;
5106    while e > 0 {
5107        if (e & 1) == 1 {
5108            result = (result.wrapping_mul(b)) & MASK;
5109        }
5110        b = (b.wrapping_mul(b)) & MASK;
5111        e >>= 1;
5112    }
5113    result
5114}
5115
5116#[inline]
5117#[must_use]
5118pub const fn const_ring_eval_unary_w96(op: PrimitiveOp, a: u128) -> u128 {
5119    const MASK: u128 = u128::MAX >> (128 - 96);
5120    match op {
5121        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5122        PrimitiveOp::Bnot => (!a) & MASK,
5123        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5124        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5125        _ => 0,
5126    }
5127}
5128
5129#[inline]
5130#[must_use]
5131#[allow(clippy::manual_checked_ops)]
5132pub const fn const_ring_eval_w104(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5133    const MASK: u128 = u128::MAX >> (128 - 104);
5134    match op {
5135        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5136        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5137        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5138        PrimitiveOp::Xor => (a ^ b) & MASK,
5139        PrimitiveOp::And => (a & b) & MASK,
5140        PrimitiveOp::Or => (a | b) & MASK,
5141        PrimitiveOp::Le => (a <= b) as u128,
5142        PrimitiveOp::Lt => (a < b) as u128,
5143        PrimitiveOp::Ge => (a >= b) as u128,
5144        PrimitiveOp::Gt => (a > b) as u128,
5145        PrimitiveOp::Concat => 0,
5146        PrimitiveOp::Div => {
5147            if b == 0 {
5148                0
5149            } else {
5150                (a / b) & MASK
5151            }
5152        }
5153        PrimitiveOp::Mod => {
5154            if b == 0 {
5155                0
5156            } else {
5157                (a % b) & MASK
5158            }
5159        }
5160        PrimitiveOp::Pow => (const_pow_w104(a, b)) & MASK,
5161        _ => 0,
5162    }
5163}
5164
5165#[inline]
5166#[must_use]
5167pub const fn const_pow_w104(base: u128, exp: u128) -> u128 {
5168    const MASK: u128 = u128::MAX >> (128 - 104);
5169    let mut result: u128 = 1;
5170    let mut b: u128 = (base) & MASK;
5171    let mut e: u128 = exp;
5172    while e > 0 {
5173        if (e & 1) == 1 {
5174            result = (result.wrapping_mul(b)) & MASK;
5175        }
5176        b = (b.wrapping_mul(b)) & MASK;
5177        e >>= 1;
5178    }
5179    result
5180}
5181
5182#[inline]
5183#[must_use]
5184pub const fn const_ring_eval_unary_w104(op: PrimitiveOp, a: u128) -> u128 {
5185    const MASK: u128 = u128::MAX >> (128 - 104);
5186    match op {
5187        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5188        PrimitiveOp::Bnot => (!a) & MASK,
5189        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5190        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5191        _ => 0,
5192    }
5193}
5194
5195#[inline]
5196#[must_use]
5197#[allow(clippy::manual_checked_ops)]
5198pub const fn const_ring_eval_w112(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5199    const MASK: u128 = u128::MAX >> (128 - 112);
5200    match op {
5201        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5202        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5203        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5204        PrimitiveOp::Xor => (a ^ b) & MASK,
5205        PrimitiveOp::And => (a & b) & MASK,
5206        PrimitiveOp::Or => (a | b) & MASK,
5207        PrimitiveOp::Le => (a <= b) as u128,
5208        PrimitiveOp::Lt => (a < b) as u128,
5209        PrimitiveOp::Ge => (a >= b) as u128,
5210        PrimitiveOp::Gt => (a > b) as u128,
5211        PrimitiveOp::Concat => 0,
5212        PrimitiveOp::Div => {
5213            if b == 0 {
5214                0
5215            } else {
5216                (a / b) & MASK
5217            }
5218        }
5219        PrimitiveOp::Mod => {
5220            if b == 0 {
5221                0
5222            } else {
5223                (a % b) & MASK
5224            }
5225        }
5226        PrimitiveOp::Pow => (const_pow_w112(a, b)) & MASK,
5227        _ => 0,
5228    }
5229}
5230
5231#[inline]
5232#[must_use]
5233pub const fn const_pow_w112(base: u128, exp: u128) -> u128 {
5234    const MASK: u128 = u128::MAX >> (128 - 112);
5235    let mut result: u128 = 1;
5236    let mut b: u128 = (base) & MASK;
5237    let mut e: u128 = exp;
5238    while e > 0 {
5239        if (e & 1) == 1 {
5240            result = (result.wrapping_mul(b)) & MASK;
5241        }
5242        b = (b.wrapping_mul(b)) & MASK;
5243        e >>= 1;
5244    }
5245    result
5246}
5247
5248#[inline]
5249#[must_use]
5250pub const fn const_ring_eval_unary_w112(op: PrimitiveOp, a: u128) -> u128 {
5251    const MASK: u128 = u128::MAX >> (128 - 112);
5252    match op {
5253        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5254        PrimitiveOp::Bnot => (!a) & MASK,
5255        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5256        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5257        _ => 0,
5258    }
5259}
5260
5261#[inline]
5262#[must_use]
5263#[allow(clippy::manual_checked_ops)]
5264pub const fn const_ring_eval_w120(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5265    const MASK: u128 = u128::MAX >> (128 - 120);
5266    match op {
5267        PrimitiveOp::Add => (a.wrapping_add(b)) & MASK,
5268        PrimitiveOp::Sub => (a.wrapping_sub(b)) & MASK,
5269        PrimitiveOp::Mul => (a.wrapping_mul(b)) & MASK,
5270        PrimitiveOp::Xor => (a ^ b) & MASK,
5271        PrimitiveOp::And => (a & b) & MASK,
5272        PrimitiveOp::Or => (a | b) & MASK,
5273        PrimitiveOp::Le => (a <= b) as u128,
5274        PrimitiveOp::Lt => (a < b) as u128,
5275        PrimitiveOp::Ge => (a >= b) as u128,
5276        PrimitiveOp::Gt => (a > b) as u128,
5277        PrimitiveOp::Concat => 0,
5278        PrimitiveOp::Div => {
5279            if b == 0 {
5280                0
5281            } else {
5282                (a / b) & MASK
5283            }
5284        }
5285        PrimitiveOp::Mod => {
5286            if b == 0 {
5287                0
5288            } else {
5289                (a % b) & MASK
5290            }
5291        }
5292        PrimitiveOp::Pow => (const_pow_w120(a, b)) & MASK,
5293        _ => 0,
5294    }
5295}
5296
5297#[inline]
5298#[must_use]
5299pub const fn const_pow_w120(base: u128, exp: u128) -> u128 {
5300    const MASK: u128 = u128::MAX >> (128 - 120);
5301    let mut result: u128 = 1;
5302    let mut b: u128 = (base) & MASK;
5303    let mut e: u128 = exp;
5304    while e > 0 {
5305        if (e & 1) == 1 {
5306            result = (result.wrapping_mul(b)) & MASK;
5307        }
5308        b = (b.wrapping_mul(b)) & MASK;
5309        e >>= 1;
5310    }
5311    result
5312}
5313
5314#[inline]
5315#[must_use]
5316pub const fn const_ring_eval_unary_w120(op: PrimitiveOp, a: u128) -> u128 {
5317    const MASK: u128 = u128::MAX >> (128 - 120);
5318    match op {
5319        PrimitiveOp::Neg => (0u128.wrapping_sub(a)) & MASK,
5320        PrimitiveOp::Bnot => (!a) & MASK,
5321        PrimitiveOp::Succ => (a.wrapping_add(1)) & MASK,
5322        PrimitiveOp::Pred => (a.wrapping_sub(1)) & MASK,
5323        _ => 0,
5324    }
5325}
5326
5327#[inline]
5328#[must_use]
5329#[allow(clippy::manual_checked_ops)]
5330pub const fn const_ring_eval_w128(op: PrimitiveOp, a: u128, b: u128) -> u128 {
5331    match op {
5332        PrimitiveOp::Add => a.wrapping_add(b),
5333        PrimitiveOp::Sub => a.wrapping_sub(b),
5334        PrimitiveOp::Mul => a.wrapping_mul(b),
5335        PrimitiveOp::Xor => a ^ b,
5336        PrimitiveOp::And => a & b,
5337        PrimitiveOp::Or => a | b,
5338        PrimitiveOp::Le => (a <= b) as u128,
5339        PrimitiveOp::Lt => (a < b) as u128,
5340        PrimitiveOp::Ge => (a >= b) as u128,
5341        PrimitiveOp::Gt => (a > b) as u128,
5342        PrimitiveOp::Concat => 0,
5343        PrimitiveOp::Div => {
5344            if b == 0 {
5345                0
5346            } else {
5347                a / b
5348            }
5349        }
5350        PrimitiveOp::Mod => {
5351            if b == 0 {
5352                0
5353            } else {
5354                a % b
5355            }
5356        }
5357        PrimitiveOp::Pow => const_pow_w128(a, b),
5358        _ => 0,
5359    }
5360}
5361
5362#[inline]
5363#[must_use]
5364pub const fn const_pow_w128(base: u128, exp: u128) -> u128 {
5365    let mut result: u128 = 1;
5366    let mut b: u128 = base;
5367    let mut e: u128 = exp;
5368    while e > 0 {
5369        if (e & 1) == 1 {
5370            result = result.wrapping_mul(b);
5371        }
5372        b = b.wrapping_mul(b);
5373        e >>= 1;
5374    }
5375    result
5376}
5377
5378#[inline]
5379#[must_use]
5380pub const fn const_ring_eval_unary_w128(op: PrimitiveOp, a: u128) -> u128 {
5381    match op {
5382        PrimitiveOp::Neg => 0u128.wrapping_sub(a),
5383        PrimitiveOp::Bnot => !a,
5384        PrimitiveOp::Succ => a.wrapping_add(1),
5385        PrimitiveOp::Pred => a.wrapping_sub(1),
5386        _ => 0,
5387    }
5388}
5389
5390/// v0.2.2 Phase C.3: foundation-internal generic backing for Witt
5391/// levels above W128. Holds an inline `[u64; N]` array with no heap
5392/// allocation, no global state, and `const fn` arithmetic throughout.
5393/// Constructors are `pub(crate)`; downstream cannot fabricate a `Limbs<N>`.
5394/// Multiplication is schoolbook-only at v0.2.2 Phase C.3; the Toom-Cook
5395/// framework with parametric splitting factor `R` ships in Phase C.4 via
5396/// the `resolver::multiplication::certify` resolver, which decides `R`
5397/// per call from a Landauer cost function constrained by stack budget.
5398#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5399pub struct Limbs<const N: usize> {
5400    /// Little-endian limbs: `words[0]` is the low 64 bits.
5401    words: [u64; N],
5402    /// Prevents external construction.
5403    _sealed: (),
5404}
5405
5406impl<const N: usize> Limbs<N> {
5407    /// Crate-internal constructor from a fixed-size limb array.
5408    #[inline]
5409    #[must_use]
5410    #[allow(dead_code)]
5411    pub(crate) const fn from_words(words: [u64; N]) -> Self {
5412        Self { words, _sealed: () }
5413    }
5414
5415    /// All-zeros constructor.
5416    #[inline]
5417    #[must_use]
5418    #[allow(dead_code)]
5419    pub(crate) const fn zero() -> Self {
5420        Self {
5421            words: [0u64; N],
5422            _sealed: (),
5423        }
5424    }
5425
5426    /// Returns a reference to the underlying limb array.
5427    #[inline]
5428    #[must_use]
5429    pub const fn words(&self) -> &[u64; N] {
5430        &self.words
5431    }
5432
5433    /// Wrapping addition mod 2^(64*N). Const-fn schoolbook with carry.
5434    #[inline]
5435    #[must_use]
5436    #[allow(dead_code)]
5437    pub(crate) const fn wrapping_add(self, other: Self) -> Self {
5438        let mut out = [0u64; N];
5439        let mut carry: u64 = 0;
5440        let mut i = 0;
5441        while i < N {
5442            let (s1, c1) = self.words[i].overflowing_add(other.words[i]);
5443            let (s2, c2) = s1.overflowing_add(carry);
5444            out[i] = s2;
5445            carry = (c1 as u64) | (c2 as u64);
5446            i += 1;
5447        }
5448        Self {
5449            words: out,
5450            _sealed: (),
5451        }
5452    }
5453
5454    /// Wrapping subtraction mod 2^(64*N). Const-fn schoolbook with borrow.
5455    #[inline]
5456    #[must_use]
5457    #[allow(dead_code)]
5458    pub(crate) const fn wrapping_sub(self, other: Self) -> Self {
5459        let mut out = [0u64; N];
5460        let mut borrow: u64 = 0;
5461        let mut i = 0;
5462        while i < N {
5463            let (d1, b1) = self.words[i].overflowing_sub(other.words[i]);
5464            let (d2, b2) = d1.overflowing_sub(borrow);
5465            out[i] = d2;
5466            borrow = (b1 as u64) | (b2 as u64);
5467            i += 1;
5468        }
5469        Self {
5470            words: out,
5471            _sealed: (),
5472        }
5473    }
5474
5475    /// Wrapping schoolbook multiplication mod 2^(64*N). The high N limbs of
5476    /// the 2N-limb full product are discarded (mod 2^bits truncation).
5477    /// v0.2.2 Phase C.3: schoolbook only. Phase C.4 adds the Toom-Cook
5478    /// framework with parametric R via `resolver::multiplication::certify`.
5479    #[inline]
5480    #[must_use]
5481    #[allow(dead_code)]
5482    pub(crate) const fn wrapping_mul(self, other: Self) -> Self {
5483        let mut out = [0u64; N];
5484        let mut i = 0;
5485        while i < N {
5486            let mut carry: u128 = 0;
5487            let mut j = 0;
5488            while j < N - i {
5489                let prod = (self.words[i] as u128) * (other.words[j] as u128)
5490                    + (out[i + j] as u128)
5491                    + carry;
5492                out[i + j] = prod as u64;
5493                carry = prod >> 64;
5494                j += 1;
5495            }
5496            i += 1;
5497        }
5498        Self {
5499            words: out,
5500            _sealed: (),
5501        }
5502    }
5503
5504    /// Bitwise XOR.
5505    #[inline]
5506    #[must_use]
5507    #[allow(dead_code)]
5508    pub(crate) const fn xor(self, other: Self) -> Self {
5509        let mut out = [0u64; N];
5510        let mut i = 0;
5511        while i < N {
5512            out[i] = self.words[i] ^ other.words[i];
5513            i += 1;
5514        }
5515        Self {
5516            words: out,
5517            _sealed: (),
5518        }
5519    }
5520
5521    /// Bitwise AND.
5522    #[inline]
5523    #[must_use]
5524    #[allow(dead_code)]
5525    pub(crate) const fn and(self, other: Self) -> Self {
5526        let mut out = [0u64; N];
5527        let mut i = 0;
5528        while i < N {
5529            out[i] = self.words[i] & other.words[i];
5530            i += 1;
5531        }
5532        Self {
5533            words: out,
5534            _sealed: (),
5535        }
5536    }
5537
5538    /// Bitwise OR.
5539    #[inline]
5540    #[must_use]
5541    #[allow(dead_code)]
5542    pub(crate) const fn or(self, other: Self) -> Self {
5543        let mut out = [0u64; N];
5544        let mut i = 0;
5545        while i < N {
5546            out[i] = self.words[i] | other.words[i];
5547            i += 1;
5548        }
5549        Self {
5550            words: out,
5551            _sealed: (),
5552        }
5553    }
5554
5555    /// Bitwise NOT.
5556    #[inline]
5557    #[must_use]
5558    #[allow(dead_code)]
5559    pub(crate) const fn not(self) -> Self {
5560        let mut out = [0u64; N];
5561        let mut i = 0;
5562        while i < N {
5563            out[i] = !self.words[i];
5564            i += 1;
5565        }
5566        Self {
5567            words: out,
5568            _sealed: (),
5569        }
5570    }
5571
5572    /// Mask the high bits of the value to keep only the low `bits` bits.
5573    /// Used at the arithmetic boundary for non-exact-fit Witt widths (e.g.,
5574    /// W160 over `Limbs<3>`: 64+64+32 bits = mask the upper 32 bits of words[2]).
5575    #[inline]
5576    #[must_use]
5577    #[allow(dead_code)]
5578    pub(crate) const fn mask_high_bits(self, bits: u32) -> Self {
5579        let mut out = self.words;
5580        let high_word_idx = (bits / 64) as usize;
5581        let low_bits_in_high_word = bits % 64;
5582        if low_bits_in_high_word != 0 && high_word_idx < N {
5583            let mask = (1u64 << low_bits_in_high_word) - 1;
5584            out[high_word_idx] &= mask;
5585            // Zero everything above the high word.
5586            let mut i = high_word_idx + 1;
5587            while i < N {
5588                out[i] = 0;
5589                i += 1;
5590            }
5591        } else if low_bits_in_high_word == 0 && high_word_idx < N {
5592            // bits is exactly a multiple of 64; zero everything from high_word_idx.
5593            let mut i = high_word_idx;
5594            while i < N {
5595                out[i] = 0;
5596                i += 1;
5597            }
5598        }
5599        Self {
5600            words: out,
5601            _sealed: (),
5602        }
5603    }
5604}
5605
5606/// Sealed marker trait identifying types produced by the foundation crate's
5607/// conformance/reduction pipeline. v0.2.1 bounds `Validated<T>` on this trait
5608/// so downstream crates cannot fabricate `Validated<UserType>` — user types
5609/// cannot impl `OntologyTarget` because the supertrait is private.
5610pub trait OntologyTarget: ontology_target_sealed::Sealed {}
5611
5612/// Sealed shim for `cert:GroundingCertificate`. Produced by GroundingAwareResolver.
5613#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5614pub struct GroundingCertificate<const FP_MAX: usize = 32> {
5615    witt_bits: u16,
5616    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5617    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5618    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5619    /// are never equal even when leading bytes coincide. `FP_MAX` is the
5620    /// application's `<B as HostBounds>::FINGERPRINT_MAX_BYTES` (ADR-018);
5621    /// threaded, not pinned, so any `Hasher<FP_MAX>` width flows.
5622    content_fingerprint: ContentFingerprint<FP_MAX>,
5623}
5624
5625impl<const FP_MAX: usize> GroundingCertificate<FP_MAX> {
5626    /// Returns the Witt level the certificate was issued for. Sourced
5627    /// from the pipeline's substrate hash output at minting time.
5628    #[inline]
5629    #[must_use]
5630    pub const fn witt_bits(&self) -> u16 {
5631        self.witt_bits
5632    }
5633
5634    /// v0.2.2 T5: returns the parametric content fingerprint of the
5635    /// source state, computed at mint time by the consumer-supplied
5636    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5637    /// certificates from different hashers are never equal because
5638    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5639    #[inline]
5640    #[must_use]
5641    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
5642        self.content_fingerprint
5643    }
5644
5645    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5646    /// witt-bits value AND the parametric content fingerprint. Used by
5647    /// `pipeline::run` and `certify_*_const` to mint a certificate
5648    /// carrying the substrate-computed fingerprint of the source state.
5649    #[inline]
5650    #[must_use]
5651    #[allow(dead_code)]
5652    pub(crate) const fn with_level_and_fingerprint_const(
5653        witt_bits: u16,
5654        content_fingerprint: ContentFingerprint<FP_MAX>,
5655    ) -> Self {
5656        Self {
5657            witt_bits,
5658            content_fingerprint,
5659        }
5660    }
5661}
5662
5663/// Sealed shim for `cert:LiftChainCertificate`. Carries the v0.2.1 `target_level()` accessor populated from the pipeline's StageOutcome.
5664#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5665pub struct LiftChainCertificate<const FP_MAX: usize = 32> {
5666    witt_bits: u16,
5667    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5668    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5669    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5670    /// are never equal even when leading bytes coincide. `FP_MAX` is the
5671    /// application's `<B as HostBounds>::FINGERPRINT_MAX_BYTES` (ADR-018);
5672    /// threaded, not pinned, so any `Hasher<FP_MAX>` width flows.
5673    content_fingerprint: ContentFingerprint<FP_MAX>,
5674}
5675
5676impl<const FP_MAX: usize> LiftChainCertificate<FP_MAX> {
5677    /// Returns the Witt level the certificate was issued for. Sourced
5678    /// from the pipeline's substrate hash output at minting time.
5679    #[inline]
5680    #[must_use]
5681    pub const fn witt_bits(&self) -> u16 {
5682        self.witt_bits
5683    }
5684
5685    /// v0.2.2 T5: returns the parametric content fingerprint of the
5686    /// source state, computed at mint time by the consumer-supplied
5687    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5688    /// certificates from different hashers are never equal because
5689    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5690    #[inline]
5691    #[must_use]
5692    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
5693        self.content_fingerprint
5694    }
5695
5696    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5697    /// witt-bits value AND the parametric content fingerprint. Used by
5698    /// `pipeline::run` and `certify_*_const` to mint a certificate
5699    /// carrying the substrate-computed fingerprint of the source state.
5700    #[inline]
5701    #[must_use]
5702    #[allow(dead_code)]
5703    pub(crate) const fn with_level_and_fingerprint_const(
5704        witt_bits: u16,
5705        content_fingerprint: ContentFingerprint<FP_MAX>,
5706    ) -> Self {
5707        Self {
5708            witt_bits,
5709            content_fingerprint,
5710        }
5711    }
5712}
5713
5714/// Sealed shim for `cert:InhabitanceCertificate` (v0.2.1).
5715#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5716pub struct InhabitanceCertificate<const FP_MAX: usize = 32> {
5717    witt_bits: u16,
5718    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5719    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5720    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5721    /// are never equal even when leading bytes coincide. `FP_MAX` is the
5722    /// application's `<B as HostBounds>::FINGERPRINT_MAX_BYTES` (ADR-018);
5723    /// threaded, not pinned, so any `Hasher<FP_MAX>` width flows.
5724    content_fingerprint: ContentFingerprint<FP_MAX>,
5725}
5726
5727impl<const FP_MAX: usize> InhabitanceCertificate<FP_MAX> {
5728    /// Returns the Witt level the certificate was issued for. Sourced
5729    /// from the pipeline's substrate hash output at minting time.
5730    #[inline]
5731    #[must_use]
5732    pub const fn witt_bits(&self) -> u16 {
5733        self.witt_bits
5734    }
5735
5736    /// v0.2.2 T5: returns the parametric content fingerprint of the
5737    /// source state, computed at mint time by the consumer-supplied
5738    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5739    /// certificates from different hashers are never equal because
5740    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5741    #[inline]
5742    #[must_use]
5743    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
5744        self.content_fingerprint
5745    }
5746
5747    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5748    /// witt-bits value AND the parametric content fingerprint. Used by
5749    /// `pipeline::run` and `certify_*_const` to mint a certificate
5750    /// carrying the substrate-computed fingerprint of the source state.
5751    #[inline]
5752    #[must_use]
5753    #[allow(dead_code)]
5754    pub(crate) const fn with_level_and_fingerprint_const(
5755        witt_bits: u16,
5756        content_fingerprint: ContentFingerprint<FP_MAX>,
5757    ) -> Self {
5758        Self {
5759            witt_bits,
5760            content_fingerprint,
5761        }
5762    }
5763}
5764
5765/// Sealed shim for `cert:CompletenessCertificate`.
5766#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5767pub struct CompletenessCertificate<const FP_MAX: usize = 32> {
5768    witt_bits: u16,
5769    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5770    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5771    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5772    /// are never equal even when leading bytes coincide. `FP_MAX` is the
5773    /// application's `<B as HostBounds>::FINGERPRINT_MAX_BYTES` (ADR-018);
5774    /// threaded, not pinned, so any `Hasher<FP_MAX>` width flows.
5775    content_fingerprint: ContentFingerprint<FP_MAX>,
5776}
5777
5778impl<const FP_MAX: usize> CompletenessCertificate<FP_MAX> {
5779    /// Returns the Witt level the certificate was issued for. Sourced
5780    /// from the pipeline's substrate hash output at minting time.
5781    #[inline]
5782    #[must_use]
5783    pub const fn witt_bits(&self) -> u16 {
5784        self.witt_bits
5785    }
5786
5787    /// v0.2.2 T5: returns the parametric content fingerprint of the
5788    /// source state, computed at mint time by the consumer-supplied
5789    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5790    /// certificates from different hashers are never equal because
5791    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5792    #[inline]
5793    #[must_use]
5794    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
5795        self.content_fingerprint
5796    }
5797
5798    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5799    /// witt-bits value AND the parametric content fingerprint. Used by
5800    /// `pipeline::run` and `certify_*_const` to mint a certificate
5801    /// carrying the substrate-computed fingerprint of the source state.
5802    #[inline]
5803    #[must_use]
5804    #[allow(dead_code)]
5805    pub(crate) const fn with_level_and_fingerprint_const(
5806        witt_bits: u16,
5807        content_fingerprint: ContentFingerprint<FP_MAX>,
5808    ) -> Self {
5809        Self {
5810            witt_bits,
5811            content_fingerprint,
5812        }
5813    }
5814}
5815
5816/// 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.
5817#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5818pub struct MultiplicationCertificate<const FP_MAX: usize = 32> {
5819    witt_bits: u16,
5820    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5821    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5822    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5823    /// are never equal even when leading bytes coincide. `FP_MAX` is the
5824    /// application's `<B as HostBounds>::FINGERPRINT_MAX_BYTES` (ADR-018);
5825    /// threaded, not pinned, so any `Hasher<FP_MAX>` width flows.
5826    content_fingerprint: ContentFingerprint<FP_MAX>,
5827}
5828
5829impl<const FP_MAX: usize> MultiplicationCertificate<FP_MAX> {
5830    /// Returns the Witt level the certificate was issued for. Sourced
5831    /// from the pipeline's substrate hash output at minting time.
5832    #[inline]
5833    #[must_use]
5834    pub const fn witt_bits(&self) -> u16 {
5835        self.witt_bits
5836    }
5837
5838    /// v0.2.2 T5: returns the parametric content fingerprint of the
5839    /// source state, computed at mint time by the consumer-supplied
5840    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5841    /// certificates from different hashers are never equal because
5842    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5843    #[inline]
5844    #[must_use]
5845    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
5846        self.content_fingerprint
5847    }
5848
5849    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5850    /// witt-bits value AND the parametric content fingerprint. Used by
5851    /// `pipeline::run` and `certify_*_const` to mint a certificate
5852    /// carrying the substrate-computed fingerprint of the source state.
5853    #[inline]
5854    #[must_use]
5855    #[allow(dead_code)]
5856    pub(crate) const fn with_level_and_fingerprint_const(
5857        witt_bits: u16,
5858        content_fingerprint: ContentFingerprint<FP_MAX>,
5859    ) -> Self {
5860        Self {
5861            witt_bits,
5862            content_fingerprint,
5863        }
5864    }
5865}
5866
5867/// Sealed shim for `cert:PartitionCertificate` (v0.2.2 Phase E). Attests the partition component classification of a Datum.
5868#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5869pub struct PartitionCertificate<const FP_MAX: usize = 32> {
5870    witt_bits: u16,
5871    /// v0.2.2 T5: parametric content fingerprint computed at mint time
5872    /// by the consumer-supplied `Hasher`. Bit-equality on the full
5873    /// buffer + width tag, so two certs with different `OUTPUT_BYTES`
5874    /// are never equal even when leading bytes coincide. `FP_MAX` is the
5875    /// application's `<B as HostBounds>::FINGERPRINT_MAX_BYTES` (ADR-018);
5876    /// threaded, not pinned, so any `Hasher<FP_MAX>` width flows.
5877    content_fingerprint: ContentFingerprint<FP_MAX>,
5878}
5879
5880impl<const FP_MAX: usize> PartitionCertificate<FP_MAX> {
5881    /// Returns the Witt level the certificate was issued for. Sourced
5882    /// from the pipeline's substrate hash output at minting time.
5883    #[inline]
5884    #[must_use]
5885    pub const fn witt_bits(&self) -> u16 {
5886        self.witt_bits
5887    }
5888
5889    /// v0.2.2 T5: returns the parametric content fingerprint of the
5890    /// source state, computed at mint time by the consumer-supplied
5891    /// `Hasher`. Active width recoverable via `width_bytes()`. Two
5892    /// certificates from different hashers are never equal because
5893    /// `ContentFingerprint::Eq` compares the full buffer + width tag.
5894    #[inline]
5895    #[must_use]
5896    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
5897        self.content_fingerprint
5898    }
5899
5900    /// v0.2.2 T5 C3.g + T6.7: the only constructor — takes both the
5901    /// witt-bits value AND the parametric content fingerprint. Used by
5902    /// `pipeline::run` and `certify_*_const` to mint a certificate
5903    /// carrying the substrate-computed fingerprint of the source state.
5904    #[inline]
5905    #[must_use]
5906    #[allow(dead_code)]
5907    pub(crate) const fn with_level_and_fingerprint_const(
5908        witt_bits: u16,
5909        content_fingerprint: ContentFingerprint<FP_MAX>,
5910    ) -> Self {
5911        Self {
5912            witt_bits,
5913            content_fingerprint,
5914        }
5915    }
5916}
5917
5918/// Sealed shim for `proof:ImpossibilityWitness`. Returned by completeness and grounding resolvers on failure.
5919#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5920pub struct GenericImpossibilityWitness {
5921    /// Optional theorem / invariant IRI identifying the failed identity.
5922    /// `None` for legacy call sites minting via `Default::default()`;
5923    /// `Some(iri)` when the witness is constructed via `for_identity`
5924    /// (Product/Coproduct Completion Amendment §2.3a).
5925    identity: Option<&'static str>,
5926}
5927
5928impl Default for GenericImpossibilityWitness {
5929    #[inline]
5930    fn default() -> Self {
5931        Self { identity: None }
5932    }
5933}
5934
5935impl GenericImpossibilityWitness {
5936    /// Construct a witness citing a specific theorem / invariant IRI.
5937    /// Introduced by the Product/Coproduct Completion Amendment §2.3a
5938    /// so mint primitives can emit typed failures against `op/*` theorems
5939    /// and `foundation/*` layout invariants.
5940    #[inline]
5941    #[must_use]
5942    pub const fn for_identity(identity: &'static str) -> Self {
5943        Self {
5944            identity: Some(identity),
5945        }
5946    }
5947
5948    /// Returns the theorem / invariant IRI this witness cites, if any.
5949    #[inline]
5950    #[must_use]
5951    pub const fn identity(&self) -> Option<&'static str> {
5952        self.identity
5953    }
5954}
5955
5956/// Sealed shim for `proof:InhabitanceImpossibilityWitness` (v0.2.1).
5957#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5958pub struct InhabitanceImpossibilityWitness {
5959    _private: (),
5960}
5961
5962/// Input shim for `type:ConstrainedType`. Used as `Certify::Input` for InhabitanceResolver, TowerCompletenessResolver, and IncrementalCompletenessResolver.
5963#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
5964pub struct ConstrainedTypeInput {
5965    _private: (),
5966}
5967
5968impl core::fmt::Display for GenericImpossibilityWitness {
5969    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5970        match self.identity {
5971            Some(iri) => write!(f, "GenericImpossibilityWitness({iri})"),
5972            None => f.write_str("GenericImpossibilityWitness"),
5973        }
5974    }
5975}
5976impl core::error::Error for GenericImpossibilityWitness {}
5977
5978impl core::fmt::Display for InhabitanceImpossibilityWitness {
5979    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5980        f.write_str("InhabitanceImpossibilityWitness")
5981    }
5982}
5983impl core::error::Error for InhabitanceImpossibilityWitness {}
5984
5985impl LiftChainCertificate {
5986    /// Returns the Witt level the certificate was issued for.
5987    #[inline]
5988    #[must_use]
5989    pub const fn target_level(&self) -> WittLevel {
5990        WittLevel::new(self.witt_bits as u32)
5991    }
5992}
5993
5994impl InhabitanceCertificate {
5995    /// Returns the witness value tuple bytes when `verified` is true.
5996    /// The sealed shim returns `None`; real witnesses flow through the
5997    /// macro back-door path.
5998    #[inline]
5999    #[must_use]
6000    pub const fn witness(&self) -> Option<&'static [u8]> {
6001        None
6002    }
6003}
6004
6005pub(crate) mod ontology_target_sealed {
6006    /// Private supertrait. Not implementable outside this crate.
6007    pub trait Sealed {}
6008    impl<const FP_MAX: usize> Sealed for super::GroundingCertificate<FP_MAX> {}
6009    impl<const FP_MAX: usize> Sealed for super::LiftChainCertificate<FP_MAX> {}
6010    impl<const FP_MAX: usize> Sealed for super::InhabitanceCertificate<FP_MAX> {}
6011    impl<const FP_MAX: usize> Sealed for super::CompletenessCertificate<FP_MAX> {}
6012    impl<const FP_MAX: usize> Sealed for super::MultiplicationCertificate<FP_MAX> {}
6013    impl<const FP_MAX: usize> Sealed for super::PartitionCertificate<FP_MAX> {}
6014    impl Sealed for super::GenericImpossibilityWitness {}
6015    impl Sealed for super::InhabitanceImpossibilityWitness {}
6016    impl Sealed for super::ConstrainedTypeInput {}
6017    impl Sealed for super::PartitionProductWitness {}
6018    impl Sealed for super::PartitionCoproductWitness {}
6019    impl Sealed for super::CartesianProductWitness {}
6020    impl<const INLINE_BYTES: usize> Sealed for super::CompileUnit<'_, INLINE_BYTES> {}
6021}
6022
6023impl<const FP_MAX: usize> OntologyTarget for GroundingCertificate<FP_MAX> {}
6024impl<const FP_MAX: usize> OntologyTarget for LiftChainCertificate<FP_MAX> {}
6025impl<const FP_MAX: usize> OntologyTarget for InhabitanceCertificate<FP_MAX> {}
6026impl<const FP_MAX: usize> OntologyTarget for CompletenessCertificate<FP_MAX> {}
6027impl<const FP_MAX: usize> OntologyTarget for MultiplicationCertificate<FP_MAX> {}
6028impl<const FP_MAX: usize> OntologyTarget for PartitionCertificate<FP_MAX> {}
6029impl OntologyTarget for GenericImpossibilityWitness {}
6030impl OntologyTarget for InhabitanceImpossibilityWitness {}
6031impl OntologyTarget for ConstrainedTypeInput {}
6032impl OntologyTarget for PartitionProductWitness {}
6033impl OntologyTarget for PartitionCoproductWitness {}
6034impl OntologyTarget for CartesianProductWitness {}
6035impl<const INLINE_BYTES: usize> OntologyTarget for CompileUnit<'_, INLINE_BYTES> {}
6036
6037/// v0.2.2 W11: supporting evidence type for `CompletenessCertificate`.
6038/// Linked from the certificate via the `Certificate::Evidence` associated type.
6039#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6040pub struct CompletenessAuditTrail {
6041    _private: (),
6042}
6043
6044/// v0.2.2 W11: supporting evidence type for `LiftChainCertificate`.
6045#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6046pub struct ChainAuditTrail {
6047    _private: (),
6048}
6049
6050/// v0.2.2 W11: supporting evidence type for `GeodesicCertificate`.
6051#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6052pub struct GeodesicEvidenceBundle {
6053    _private: (),
6054}
6055
6056/// v0.2.2 W11: sealed carrier for `cert:TransformCertificate`.
6057/// Phase X.1: minted with a Witt level and content fingerprint so the
6058/// resolver whose `resolver:CertifyMapping` produces this class can fold
6059/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6060/// constructor matches every other `cert:Certificate` subclass.
6061#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6062pub struct TransformCertificate<const FP_MAX: usize = 32> {
6063    witt_bits: u16,
6064    content_fingerprint: ContentFingerprint<FP_MAX>,
6065    _private: (),
6066}
6067
6068impl<const FP_MAX: usize> TransformCertificate<FP_MAX> {
6069    /// Phase X.1: content-addressed constructor. Mints a certificate
6070    /// carrying the Witt level and substrate-hasher fingerprint of the
6071    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6072    #[inline]
6073    #[must_use]
6074    #[allow(dead_code)]
6075    pub(crate) const fn with_level_and_fingerprint_const(
6076        witt_bits: u16,
6077        content_fingerprint: ContentFingerprint<FP_MAX>,
6078    ) -> Self {
6079        Self {
6080            witt_bits,
6081            content_fingerprint,
6082            _private: (),
6083        }
6084    }
6085
6086    /// Phase X.1: legacy zero-fingerprint constructor retained for
6087    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6088    #[inline]
6089    #[must_use]
6090    #[allow(dead_code)]
6091    pub(crate) const fn empty_const() -> Self {
6092        Self {
6093            witt_bits: 0,
6094            content_fingerprint: ContentFingerprint::zero(),
6095            _private: (),
6096        }
6097    }
6098
6099    /// Phase X.1: the Witt level at which this certificate was minted.
6100    #[inline]
6101    #[must_use]
6102    pub const fn witt_bits(&self) -> u16 {
6103        self.witt_bits
6104    }
6105
6106    /// Phase X.1: the content fingerprint of the resolver decision.
6107    #[inline]
6108    #[must_use]
6109    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
6110        self.content_fingerprint
6111    }
6112}
6113
6114/// v0.2.2 W11: sealed carrier for `cert:IsometryCertificate`.
6115/// Phase X.1: minted with a Witt level and content fingerprint so the
6116/// resolver whose `resolver:CertifyMapping` produces this class can fold
6117/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6118/// constructor matches every other `cert:Certificate` subclass.
6119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6120pub struct IsometryCertificate<const FP_MAX: usize = 32> {
6121    witt_bits: u16,
6122    content_fingerprint: ContentFingerprint<FP_MAX>,
6123    _private: (),
6124}
6125
6126impl<const FP_MAX: usize> IsometryCertificate<FP_MAX> {
6127    /// Phase X.1: content-addressed constructor. Mints a certificate
6128    /// carrying the Witt level and substrate-hasher fingerprint of the
6129    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6130    #[inline]
6131    #[must_use]
6132    #[allow(dead_code)]
6133    pub(crate) const fn with_level_and_fingerprint_const(
6134        witt_bits: u16,
6135        content_fingerprint: ContentFingerprint<FP_MAX>,
6136    ) -> Self {
6137        Self {
6138            witt_bits,
6139            content_fingerprint,
6140            _private: (),
6141        }
6142    }
6143
6144    /// Phase X.1: legacy zero-fingerprint constructor retained for
6145    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6146    #[inline]
6147    #[must_use]
6148    #[allow(dead_code)]
6149    pub(crate) const fn empty_const() -> Self {
6150        Self {
6151            witt_bits: 0,
6152            content_fingerprint: ContentFingerprint::zero(),
6153            _private: (),
6154        }
6155    }
6156
6157    /// Phase X.1: the Witt level at which this certificate was minted.
6158    #[inline]
6159    #[must_use]
6160    pub const fn witt_bits(&self) -> u16 {
6161        self.witt_bits
6162    }
6163
6164    /// Phase X.1: the content fingerprint of the resolver decision.
6165    #[inline]
6166    #[must_use]
6167    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
6168        self.content_fingerprint
6169    }
6170}
6171
6172/// v0.2.2 W11: sealed carrier for `cert:InvolutionCertificate`.
6173/// Phase X.1: minted with a Witt level and content fingerprint so the
6174/// resolver whose `resolver:CertifyMapping` produces this class can fold
6175/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6176/// constructor matches every other `cert:Certificate` subclass.
6177#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6178pub struct InvolutionCertificate<const FP_MAX: usize = 32> {
6179    witt_bits: u16,
6180    content_fingerprint: ContentFingerprint<FP_MAX>,
6181    _private: (),
6182}
6183
6184impl<const FP_MAX: usize> InvolutionCertificate<FP_MAX> {
6185    /// Phase X.1: content-addressed constructor. Mints a certificate
6186    /// carrying the Witt level and substrate-hasher fingerprint of the
6187    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6188    #[inline]
6189    #[must_use]
6190    #[allow(dead_code)]
6191    pub(crate) const fn with_level_and_fingerprint_const(
6192        witt_bits: u16,
6193        content_fingerprint: ContentFingerprint<FP_MAX>,
6194    ) -> Self {
6195        Self {
6196            witt_bits,
6197            content_fingerprint,
6198            _private: (),
6199        }
6200    }
6201
6202    /// Phase X.1: legacy zero-fingerprint constructor retained for
6203    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6204    #[inline]
6205    #[must_use]
6206    #[allow(dead_code)]
6207    pub(crate) const fn empty_const() -> Self {
6208        Self {
6209            witt_bits: 0,
6210            content_fingerprint: ContentFingerprint::zero(),
6211            _private: (),
6212        }
6213    }
6214
6215    /// Phase X.1: the Witt level at which this certificate was minted.
6216    #[inline]
6217    #[must_use]
6218    pub const fn witt_bits(&self) -> u16 {
6219        self.witt_bits
6220    }
6221
6222    /// Phase X.1: the content fingerprint of the resolver decision.
6223    #[inline]
6224    #[must_use]
6225    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
6226        self.content_fingerprint
6227    }
6228}
6229
6230/// v0.2.2 W11: sealed carrier for `cert:GeodesicCertificate`.
6231/// Phase X.1: minted with a Witt level and content fingerprint so the
6232/// resolver whose `resolver:CertifyMapping` produces this class can fold
6233/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6234/// constructor matches every other `cert:Certificate` subclass.
6235#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6236pub struct GeodesicCertificate<const FP_MAX: usize = 32> {
6237    witt_bits: u16,
6238    content_fingerprint: ContentFingerprint<FP_MAX>,
6239    _private: (),
6240}
6241
6242impl<const FP_MAX: usize> GeodesicCertificate<FP_MAX> {
6243    /// Phase X.1: content-addressed constructor. Mints a certificate
6244    /// carrying the Witt level and substrate-hasher fingerprint of the
6245    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6246    #[inline]
6247    #[must_use]
6248    #[allow(dead_code)]
6249    pub(crate) const fn with_level_and_fingerprint_const(
6250        witt_bits: u16,
6251        content_fingerprint: ContentFingerprint<FP_MAX>,
6252    ) -> Self {
6253        Self {
6254            witt_bits,
6255            content_fingerprint,
6256            _private: (),
6257        }
6258    }
6259
6260    /// Phase X.1: legacy zero-fingerprint constructor retained for
6261    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6262    #[inline]
6263    #[must_use]
6264    #[allow(dead_code)]
6265    pub(crate) const fn empty_const() -> Self {
6266        Self {
6267            witt_bits: 0,
6268            content_fingerprint: ContentFingerprint::zero(),
6269            _private: (),
6270        }
6271    }
6272
6273    /// Phase X.1: the Witt level at which this certificate was minted.
6274    #[inline]
6275    #[must_use]
6276    pub const fn witt_bits(&self) -> u16 {
6277        self.witt_bits
6278    }
6279
6280    /// Phase X.1: the content fingerprint of the resolver decision.
6281    #[inline]
6282    #[must_use]
6283    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
6284        self.content_fingerprint
6285    }
6286}
6287
6288/// v0.2.2 W11: sealed carrier for `cert:MeasurementCertificate`.
6289/// Phase X.1: minted with a Witt level and content fingerprint so the
6290/// resolver whose `resolver:CertifyMapping` produces this class can fold
6291/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6292/// constructor matches every other `cert:Certificate` subclass.
6293#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6294pub struct MeasurementCertificate<const FP_MAX: usize = 32> {
6295    witt_bits: u16,
6296    content_fingerprint: ContentFingerprint<FP_MAX>,
6297    _private: (),
6298}
6299
6300impl<const FP_MAX: usize> MeasurementCertificate<FP_MAX> {
6301    /// Phase X.1: content-addressed constructor. Mints a certificate
6302    /// carrying the Witt level and substrate-hasher fingerprint of the
6303    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6304    #[inline]
6305    #[must_use]
6306    #[allow(dead_code)]
6307    pub(crate) const fn with_level_and_fingerprint_const(
6308        witt_bits: u16,
6309        content_fingerprint: ContentFingerprint<FP_MAX>,
6310    ) -> Self {
6311        Self {
6312            witt_bits,
6313            content_fingerprint,
6314            _private: (),
6315        }
6316    }
6317
6318    /// Phase X.1: legacy zero-fingerprint constructor retained for
6319    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6320    #[inline]
6321    #[must_use]
6322    #[allow(dead_code)]
6323    pub(crate) const fn empty_const() -> Self {
6324        Self {
6325            witt_bits: 0,
6326            content_fingerprint: ContentFingerprint::zero(),
6327            _private: (),
6328        }
6329    }
6330
6331    /// Phase X.1: the Witt level at which this certificate was minted.
6332    #[inline]
6333    #[must_use]
6334    pub const fn witt_bits(&self) -> u16 {
6335        self.witt_bits
6336    }
6337
6338    /// Phase X.1: the content fingerprint of the resolver decision.
6339    #[inline]
6340    #[must_use]
6341    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
6342        self.content_fingerprint
6343    }
6344}
6345
6346/// v0.2.2 W11: sealed carrier for `cert:BornRuleVerification`.
6347/// Phase X.1: minted with a Witt level and content fingerprint so the
6348/// resolver whose `resolver:CertifyMapping` produces this class can fold
6349/// its decision into a content-addressed witness. The `with_level_and_fingerprint_const`
6350/// constructor matches every other `cert:Certificate` subclass.
6351#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6352pub struct BornRuleVerification<const FP_MAX: usize = 32> {
6353    witt_bits: u16,
6354    content_fingerprint: ContentFingerprint<FP_MAX>,
6355    _private: (),
6356}
6357
6358impl<const FP_MAX: usize> BornRuleVerification<FP_MAX> {
6359    /// Phase X.1: content-addressed constructor. Mints a certificate
6360    /// carrying the Witt level and substrate-hasher fingerprint of the
6361    /// resolver decision. Crate-sealed so that only resolver kernels mint.
6362    #[inline]
6363    #[must_use]
6364    #[allow(dead_code)]
6365    pub(crate) const fn with_level_and_fingerprint_const(
6366        witt_bits: u16,
6367        content_fingerprint: ContentFingerprint<FP_MAX>,
6368    ) -> Self {
6369        Self {
6370            witt_bits,
6371            content_fingerprint,
6372            _private: (),
6373        }
6374    }
6375
6376    /// Phase X.1: legacy zero-fingerprint constructor retained for
6377    /// `certify_*_const` callers that pre-date the X.1 cert-discrimination pass.
6378    #[inline]
6379    #[must_use]
6380    #[allow(dead_code)]
6381    pub(crate) const fn empty_const() -> Self {
6382        Self {
6383            witt_bits: 0,
6384            content_fingerprint: ContentFingerprint::zero(),
6385            _private: (),
6386        }
6387    }
6388
6389    /// Phase X.1: the Witt level at which this certificate was minted.
6390    #[inline]
6391    #[must_use]
6392    pub const fn witt_bits(&self) -> u16 {
6393        self.witt_bits
6394    }
6395
6396    /// Phase X.1: the content fingerprint of the resolver decision.
6397    #[inline]
6398    #[must_use]
6399    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
6400        self.content_fingerprint
6401    }
6402}
6403
6404/// v0.2.2 W11: sealed marker trait for foundation-supplied certificate kinds.
6405/// Implemented by every `cert:Certificate` subclass via codegen; not
6406/// implementable outside this crate.
6407pub trait Certificate: certificate_sealed::Sealed {
6408    /// The ontology IRI of this certificate class.
6409    const IRI: &'static str;
6410    /// The structured evidence carried by this certificate (or `()` if none).
6411    type Evidence;
6412}
6413
6414pub(crate) mod certificate_sealed {
6415    /// Private supertrait. Not implementable outside this crate.
6416    pub trait Sealed {}
6417    impl<const FP_MAX: usize> Sealed for super::GroundingCertificate<FP_MAX> {}
6418    impl<const FP_MAX: usize> Sealed for super::LiftChainCertificate<FP_MAX> {}
6419    impl<const FP_MAX: usize> Sealed for super::InhabitanceCertificate<FP_MAX> {}
6420    impl<const FP_MAX: usize> Sealed for super::CompletenessCertificate<FP_MAX> {}
6421    impl<const FP_MAX: usize> Sealed for super::TransformCertificate<FP_MAX> {}
6422    impl<const FP_MAX: usize> Sealed for super::IsometryCertificate<FP_MAX> {}
6423    impl<const FP_MAX: usize> Sealed for super::InvolutionCertificate<FP_MAX> {}
6424    impl<const FP_MAX: usize> Sealed for super::GeodesicCertificate<FP_MAX> {}
6425    impl<const FP_MAX: usize> Sealed for super::MeasurementCertificate<FP_MAX> {}
6426    impl<const FP_MAX: usize> Sealed for super::BornRuleVerification<FP_MAX> {}
6427    impl<const FP_MAX: usize> Sealed for super::MultiplicationCertificate<FP_MAX> {}
6428    impl<const FP_MAX: usize> Sealed for super::PartitionCertificate<FP_MAX> {}
6429    impl Sealed for super::GenericImpossibilityWitness {}
6430    impl Sealed for super::InhabitanceImpossibilityWitness {}
6431    impl Sealed for super::PartitionProductWitness {}
6432    impl Sealed for super::PartitionCoproductWitness {}
6433    impl Sealed for super::CartesianProductWitness {}
6434}
6435
6436impl<const FP_MAX: usize> Certificate for GroundingCertificate<FP_MAX> {
6437    const IRI: &'static str = "https://uor.foundation/cert/GroundingCertificate";
6438    type Evidence = ();
6439}
6440
6441impl<const FP_MAX: usize> Certificate for LiftChainCertificate<FP_MAX> {
6442    const IRI: &'static str = "https://uor.foundation/cert/LiftChainCertificate";
6443    type Evidence = ChainAuditTrail;
6444}
6445
6446impl<const FP_MAX: usize> Certificate for InhabitanceCertificate<FP_MAX> {
6447    const IRI: &'static str = "https://uor.foundation/cert/InhabitanceCertificate";
6448    type Evidence = ();
6449}
6450
6451impl<const FP_MAX: usize> Certificate for CompletenessCertificate<FP_MAX> {
6452    const IRI: &'static str = "https://uor.foundation/cert/CompletenessCertificate";
6453    type Evidence = CompletenessAuditTrail;
6454}
6455
6456impl<const FP_MAX: usize> Certificate for TransformCertificate<FP_MAX> {
6457    const IRI: &'static str = "https://uor.foundation/cert/TransformCertificate";
6458    type Evidence = ();
6459}
6460
6461impl<const FP_MAX: usize> Certificate for IsometryCertificate<FP_MAX> {
6462    const IRI: &'static str = "https://uor.foundation/cert/IsometryCertificate";
6463    type Evidence = ();
6464}
6465
6466impl<const FP_MAX: usize> Certificate for InvolutionCertificate<FP_MAX> {
6467    const IRI: &'static str = "https://uor.foundation/cert/InvolutionCertificate";
6468    type Evidence = ();
6469}
6470
6471impl<const FP_MAX: usize> Certificate for GeodesicCertificate<FP_MAX> {
6472    const IRI: &'static str = "https://uor.foundation/cert/GeodesicCertificate";
6473    type Evidence = GeodesicEvidenceBundle;
6474}
6475
6476impl<const FP_MAX: usize> Certificate for MeasurementCertificate<FP_MAX> {
6477    const IRI: &'static str = "https://uor.foundation/cert/MeasurementCertificate";
6478    type Evidence = ();
6479}
6480
6481impl<const FP_MAX: usize> Certificate for BornRuleVerification<FP_MAX> {
6482    const IRI: &'static str = "https://uor.foundation/cert/BornRuleVerification";
6483    type Evidence = ();
6484}
6485
6486impl<const FP_MAX: usize> Certificate for MultiplicationCertificate<FP_MAX> {
6487    const IRI: &'static str = "https://uor.foundation/cert/MultiplicationCertificate";
6488    type Evidence = MultiplicationEvidence;
6489}
6490
6491impl<const FP_MAX: usize> Certificate for PartitionCertificate<FP_MAX> {
6492    const IRI: &'static str = "https://uor.foundation/cert/PartitionCertificate";
6493    type Evidence = ();
6494}
6495
6496impl Certificate for GenericImpossibilityWitness {
6497    const IRI: &'static str = "https://uor.foundation/cert/GenericImpossibilityCertificate";
6498    type Evidence = ();
6499}
6500
6501impl Certificate for InhabitanceImpossibilityWitness {
6502    const IRI: &'static str = "https://uor.foundation/cert/InhabitanceImpossibilityCertificate";
6503    type Evidence = ();
6504}
6505
6506/// Phase X.1: uniform mint interface over cert subclasses. Each
6507/// `Certificate` implementer that accepts `(witt_bits, ContentFingerprint)`
6508/// at construction time implements this trait. Lives inside a
6509/// `certify_const_mint` module so the symbol doesn't leak into top-level
6510/// documentation alongside `Certificate`.
6511pub(crate) mod certify_const_mint {
6512    use super::{Certificate, ContentFingerprint};
6513    pub trait MintWithLevelFingerprint<const FP_MAX: usize>: Certificate {
6514        fn mint_with_level_fingerprint(
6515            witt_bits: u16,
6516            content_fingerprint: ContentFingerprint<FP_MAX>,
6517        ) -> Self;
6518    }
6519    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX> for super::GroundingCertificate<FP_MAX> {
6520        #[inline]
6521        fn mint_with_level_fingerprint(
6522            witt_bits: u16,
6523            content_fingerprint: ContentFingerprint<FP_MAX>,
6524        ) -> Self {
6525            super::GroundingCertificate::with_level_and_fingerprint_const(
6526                witt_bits,
6527                content_fingerprint,
6528            )
6529        }
6530    }
6531    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX> for super::LiftChainCertificate<FP_MAX> {
6532        #[inline]
6533        fn mint_with_level_fingerprint(
6534            witt_bits: u16,
6535            content_fingerprint: ContentFingerprint<FP_MAX>,
6536        ) -> Self {
6537            super::LiftChainCertificate::with_level_and_fingerprint_const(
6538                witt_bits,
6539                content_fingerprint,
6540            )
6541        }
6542    }
6543    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX>
6544        for super::InhabitanceCertificate<FP_MAX>
6545    {
6546        #[inline]
6547        fn mint_with_level_fingerprint(
6548            witt_bits: u16,
6549            content_fingerprint: ContentFingerprint<FP_MAX>,
6550        ) -> Self {
6551            super::InhabitanceCertificate::with_level_and_fingerprint_const(
6552                witt_bits,
6553                content_fingerprint,
6554            )
6555        }
6556    }
6557    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX>
6558        for super::CompletenessCertificate<FP_MAX>
6559    {
6560        #[inline]
6561        fn mint_with_level_fingerprint(
6562            witt_bits: u16,
6563            content_fingerprint: ContentFingerprint<FP_MAX>,
6564        ) -> Self {
6565            super::CompletenessCertificate::with_level_and_fingerprint_const(
6566                witt_bits,
6567                content_fingerprint,
6568            )
6569        }
6570    }
6571    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX>
6572        for super::MultiplicationCertificate<FP_MAX>
6573    {
6574        #[inline]
6575        fn mint_with_level_fingerprint(
6576            witt_bits: u16,
6577            content_fingerprint: ContentFingerprint<FP_MAX>,
6578        ) -> Self {
6579            super::MultiplicationCertificate::with_level_and_fingerprint_const(
6580                witt_bits,
6581                content_fingerprint,
6582            )
6583        }
6584    }
6585    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX> for super::PartitionCertificate<FP_MAX> {
6586        #[inline]
6587        fn mint_with_level_fingerprint(
6588            witt_bits: u16,
6589            content_fingerprint: ContentFingerprint<FP_MAX>,
6590        ) -> Self {
6591            super::PartitionCertificate::with_level_and_fingerprint_const(
6592                witt_bits,
6593                content_fingerprint,
6594            )
6595        }
6596    }
6597    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX> for super::TransformCertificate<FP_MAX> {
6598        #[inline]
6599        fn mint_with_level_fingerprint(
6600            witt_bits: u16,
6601            content_fingerprint: ContentFingerprint<FP_MAX>,
6602        ) -> Self {
6603            super::TransformCertificate::with_level_and_fingerprint_const(
6604                witt_bits,
6605                content_fingerprint,
6606            )
6607        }
6608    }
6609    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX> for super::IsometryCertificate<FP_MAX> {
6610        #[inline]
6611        fn mint_with_level_fingerprint(
6612            witt_bits: u16,
6613            content_fingerprint: ContentFingerprint<FP_MAX>,
6614        ) -> Self {
6615            super::IsometryCertificate::with_level_and_fingerprint_const(
6616                witt_bits,
6617                content_fingerprint,
6618            )
6619        }
6620    }
6621    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX>
6622        for super::InvolutionCertificate<FP_MAX>
6623    {
6624        #[inline]
6625        fn mint_with_level_fingerprint(
6626            witt_bits: u16,
6627            content_fingerprint: ContentFingerprint<FP_MAX>,
6628        ) -> Self {
6629            super::InvolutionCertificate::with_level_and_fingerprint_const(
6630                witt_bits,
6631                content_fingerprint,
6632            )
6633        }
6634    }
6635    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX> for super::GeodesicCertificate<FP_MAX> {
6636        #[inline]
6637        fn mint_with_level_fingerprint(
6638            witt_bits: u16,
6639            content_fingerprint: ContentFingerprint<FP_MAX>,
6640        ) -> Self {
6641            super::GeodesicCertificate::with_level_and_fingerprint_const(
6642                witt_bits,
6643                content_fingerprint,
6644            )
6645        }
6646    }
6647    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX>
6648        for super::MeasurementCertificate<FP_MAX>
6649    {
6650        #[inline]
6651        fn mint_with_level_fingerprint(
6652            witt_bits: u16,
6653            content_fingerprint: ContentFingerprint<FP_MAX>,
6654        ) -> Self {
6655            super::MeasurementCertificate::with_level_and_fingerprint_const(
6656                witt_bits,
6657                content_fingerprint,
6658            )
6659        }
6660    }
6661    impl<const FP_MAX: usize> MintWithLevelFingerprint<FP_MAX> for super::BornRuleVerification<FP_MAX> {
6662        #[inline]
6663        fn mint_with_level_fingerprint(
6664            witt_bits: u16,
6665            content_fingerprint: ContentFingerprint<FP_MAX>,
6666        ) -> Self {
6667            super::BornRuleVerification::with_level_and_fingerprint_const(
6668                witt_bits,
6669                content_fingerprint,
6670            )
6671        }
6672    }
6673}
6674
6675/// v0.2.2 W11: parametric carrier for any foundation-supplied certificate.
6676/// Replaces the v0.2.1 per-class shim duplication. The `Certificate` trait
6677/// is sealed and the `_private` field prevents external construction; only
6678/// the foundation's pipeline / resolver paths produce `Certified<C>` values.
6679#[derive(Debug, Clone)]
6680pub struct Certified<C: Certificate> {
6681    /// The certificate kind value carried by this wrapper.
6682    inner: C,
6683    /// Phase A.1: the foundation-internal two-clock value read at witness issuance.
6684    uor_time: UorTime,
6685    /// Prevents external construction.
6686    _private: (),
6687}
6688
6689impl<C: Certificate> Certified<C> {
6690    /// Returns a reference to the carried certificate kind value.
6691    #[inline]
6692    #[must_use]
6693    pub const fn certificate(&self) -> &C {
6694        &self.inner
6695    }
6696
6697    /// Returns the ontology IRI of this certificate's kind.
6698    #[inline]
6699    #[must_use]
6700    pub const fn iri(&self) -> &'static str {
6701        C::IRI
6702    }
6703
6704    /// Phase A.1: the foundation-internal two-clock value read at witness issuance.
6705    /// Maps `rewrite_steps` to `derivation:stepCount` and `landauer_nats` to
6706    /// `observable:LandauerCost`. Content-deterministic: same computation →
6707    /// same `UorTime`. Composable against wall-clock bounds via
6708    /// [`UorTime::min_wall_clock`] and a downstream-supplied `Calibration`.
6709    #[inline]
6710    #[must_use]
6711    pub const fn uor_time(&self) -> UorTime {
6712        self.uor_time
6713    }
6714
6715    /// Crate-internal constructor. Reachable only from the pipeline / resolver paths.
6716    /// The `uor_time` is computed deterministically from the certificate kind's `IRI`
6717    /// length: the rewrite-step count is the IRI byte length, and the Landauer cost
6718    /// is `rewrite_steps × ln 2` (the Landauer-temperature cost of traversing that
6719    /// many orthogonal states). Two `Certified<C>` values with the same `C` share the
6720    /// same `UorTime`, preserving content-determinism across pipeline invocations.
6721    #[inline]
6722    #[allow(dead_code)]
6723    pub(crate) const fn new(inner: C) -> Self {
6724        // IRI length is the deterministic proxy for the cert class's structural
6725        // complexity. Phase D threads real resolver-counted steps through.
6726        let steps = C::IRI.len() as u64;
6727        let landauer = LandauerBudget::new((steps as f64) * core::f64::consts::LN_2);
6728        let uor_time = UorTime::new(landauer, steps);
6729        Self {
6730            inner,
6731            uor_time,
6732            _private: (),
6733        }
6734    }
6735}
6736
6737/// v0.2.2 Phase C.4: call-site context consumed by the multiplication
6738/// resolver. Carries the stack budget (`linear:stackBudgetBytes`), the
6739/// const-eval regime, and the limb count of the operand's `Limbs<N>`
6740/// backing. The resolver picks the cost-optimal Toom-Cook splitting
6741/// factor R based on this context.
6742#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6743pub struct MulContext {
6744    /// Stack budget available at the call site, in bytes. Zero is
6745    /// inadmissible; the resolver returns an impossibility witness.
6746    pub stack_budget_bytes: u64,
6747    /// True if this call is in const-eval context. In const-eval, only
6748    /// R = 1 (schoolbook) is admissible because deeper recursion blows
6749    /// the const-eval depth limit.
6750    pub const_eval: bool,
6751    /// Number of 64-bit limbs in the operand's `Limbs<N>` backing.
6752    /// Schoolbook cost is proportional to `N^2`; Karatsuba cost is
6753    /// proportional to `3 · (N/2)^2`. For native-backed levels
6754    /// (W8..W128), pass the equivalent limb count.
6755    pub limb_count: usize,
6756}
6757
6758impl MulContext {
6759    /// Construct a new `MulContext` for the call site.
6760    #[inline]
6761    #[must_use]
6762    pub const fn new(stack_budget_bytes: u64, const_eval: bool, limb_count: usize) -> Self {
6763        Self {
6764            stack_budget_bytes,
6765            const_eval,
6766            limb_count,
6767        }
6768    }
6769}
6770
6771/// v0.2.2 Phase C.4: evidence returned alongside a `MultiplicationCertificate`.
6772/// The certificate is a sealed handle; its evidence (chosen splitting factor,
6773/// sub-multiplication count, accumulated Landauer cost in nats) lives here.
6774#[derive(Debug, Clone, Copy, PartialEq)]
6775pub struct MultiplicationEvidence {
6776    splitting_factor: u32,
6777    sub_multiplication_count: u32,
6778    landauer_cost_nats_bits: u64,
6779}
6780
6781impl MultiplicationEvidence {
6782    /// The Toom-Cook splitting factor R chosen by the resolver.
6783    #[inline]
6784    #[must_use]
6785    pub const fn splitting_factor(&self) -> u32 {
6786        self.splitting_factor
6787    }
6788
6789    /// The recursive sub-multiplication count for one multiplication.
6790    #[inline]
6791    #[must_use]
6792    pub const fn sub_multiplication_count(&self) -> u32 {
6793        self.sub_multiplication_count
6794    }
6795
6796    /// 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(_)`.
6797    #[inline]
6798    #[must_use]
6799    pub const fn landauer_cost_nats_bits(&self) -> u64 {
6800        self.landauer_cost_nats_bits
6801    }
6802}
6803
6804impl<const FP_MAX: usize> MultiplicationCertificate<FP_MAX> {
6805    /// v0.2.2 T6.7: construct a `MultiplicationCertificate` with substrate-
6806    /// computed evidence. Crate-internal only; downstream obtains certificates
6807    /// via `resolver::multiplication::certify::<H>`.
6808    #[inline]
6809    #[must_use]
6810    pub(crate) fn with_evidence(
6811        splitting_factor: u32,
6812        sub_multiplication_count: u32,
6813        landauer_cost_nats_bits: u64,
6814        content_fingerprint: ContentFingerprint<FP_MAX>,
6815    ) -> Self {
6816        let _ = MultiplicationEvidence {
6817            splitting_factor,
6818            sub_multiplication_count,
6819            landauer_cost_nats_bits,
6820        };
6821        Self::with_level_and_fingerprint_const(32, content_fingerprint)
6822    }
6823}
6824
6825/// v0.2.2 Phase E: maximum simplicial dimension tracked by the
6826/// constraint-nerve Betti-numbers vector. The bound is 8 for the
6827/// currently-supported WittLevel set per the existing partition:FreeRank
6828/// capacity properties; the constant is `pub` (part of the public-API
6829/// snapshot) so future expansions require explicit review.
6830/// Wiki ADR-037: a foundation-fixed conservative default for
6831/// [`crate::HostBounds::BETTI_DIMENSION_MAX`].
6832pub const MAX_BETTI_DIMENSION: usize = 8;
6833
6834/// Sealed newtype for the grounding completion ratio σ ∈
6835/// [0.0, 1.0]. σ = 1 indicates the ground state; σ = 0 the
6836/// unbound state. Backs observable:GroundingSigma. Phase 9: parametric over
6837/// the host's `H::Decimal` precision.
6838#[derive(Debug)]
6839pub struct SigmaValue<H: HostTypes = crate::DefaultHostTypes> {
6840    value: H::Decimal,
6841    _phantom: core::marker::PhantomData<H>,
6842    _sealed: (),
6843}
6844
6845impl<H: HostTypes> Copy for SigmaValue<H> {}
6846impl<H: HostTypes> Clone for SigmaValue<H> {
6847    #[inline]
6848    fn clone(&self) -> Self {
6849        *self
6850    }
6851}
6852impl<H: HostTypes> PartialEq for SigmaValue<H> {
6853    #[inline]
6854    fn eq(&self, other: &Self) -> bool {
6855        self.value == other.value
6856    }
6857}
6858
6859impl<H: HostTypes> SigmaValue<H> {
6860    /// Returns the stored σ value in the range [0.0, 1.0].
6861    #[inline]
6862    #[must_use]
6863    pub const fn value(&self) -> H::Decimal {
6864        self.value
6865    }
6866
6867    /// Crate-internal constructor. Caller guarantees `value` is in
6868    /// the closed range [0.0, 1.0] and is not NaN.
6869    #[inline]
6870    #[must_use]
6871    #[allow(dead_code)]
6872    pub(crate) const fn new_unchecked(value: H::Decimal) -> Self {
6873        Self {
6874            value,
6875            _phantom: core::marker::PhantomData,
6876            _sealed: (),
6877        }
6878    }
6879}
6880
6881/// Phase A.3: sealed stratum coordinate (the v₂ valuation of a `Datum` at level `L`).
6882/// Backs `schema:stratum`. The value is non-negative and bounded by `L`'s `bit_width`
6883/// per the ontology's `nonNegativeInteger` range. Constructed only by foundation code
6884/// at grounding time; no public constructor — the `Stratum<W8>` / `Stratum<W16>` / ...
6885/// type family is closed under the WittLevel individual set.
6886#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6887pub struct Stratum<L> {
6888    value: u32,
6889    _level: PhantomData<L>,
6890    _sealed: (),
6891}
6892
6893impl<L> Stratum<L> {
6894    /// Returns the raw v₂ valuation as a `u32`. The value is bounded by `L`'s bit_width.
6895    #[inline]
6896    #[must_use]
6897    pub const fn as_u32(&self) -> u32 {
6898        self.value
6899    }
6900
6901    /// Crate-internal constructor. Reachable only from grounding-time minting.
6902    #[inline]
6903    #[must_use]
6904    #[allow(dead_code)]
6905    pub(crate) const fn new(value: u32) -> Self {
6906        Self {
6907            value,
6908            _level: PhantomData,
6909            _sealed: (),
6910        }
6911    }
6912}
6913
6914/// Phase A.4: sealed carrier for `observable:d_delta_metric` (metric incompatibility).
6915#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6916pub struct DDeltaMetric {
6917    value: i64,
6918    _sealed: (),
6919}
6920
6921impl DDeltaMetric {
6922    /// Returns the signed incompatibility magnitude (ring distance minus Hamming distance).
6923    #[inline]
6924    #[must_use]
6925    pub const fn as_i64(&self) -> i64 {
6926        self.value
6927    }
6928
6929    /// Crate-internal constructor.
6930    #[inline]
6931    #[must_use]
6932    #[allow(dead_code)]
6933    pub(crate) const fn new(value: i64) -> Self {
6934        Self { value, _sealed: () }
6935    }
6936}
6937
6938/// Phase A.4: sealed carrier for `observable:euler_metric` (Euler characteristic).
6939#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6940pub struct EulerMetric {
6941    value: i64,
6942    _sealed: (),
6943}
6944
6945impl EulerMetric {
6946    /// Returns the Euler characteristic χ of the constraint nerve.
6947    #[inline]
6948    #[must_use]
6949    pub const fn as_i64(&self) -> i64 {
6950        self.value
6951    }
6952
6953    /// Crate-internal constructor.
6954    #[inline]
6955    #[must_use]
6956    #[allow(dead_code)]
6957    pub(crate) const fn new(value: i64) -> Self {
6958        Self { value, _sealed: () }
6959    }
6960}
6961
6962/// Phase A.4: sealed carrier for `observable:residual_metric` (free-site count r).
6963#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6964pub struct ResidualMetric {
6965    value: u32,
6966    _sealed: (),
6967}
6968
6969impl ResidualMetric {
6970    /// Returns the free-site count r at grounding time.
6971    #[inline]
6972    #[must_use]
6973    pub const fn as_u32(&self) -> u32 {
6974        self.value
6975    }
6976
6977    /// Crate-internal constructor.
6978    #[inline]
6979    #[must_use]
6980    #[allow(dead_code)]
6981    pub(crate) const fn new(value: u32) -> Self {
6982        Self { value, _sealed: () }
6983    }
6984}
6985
6986/// Phase A.4: sealed carrier for `observable:betti_metric` (Betti-number vector).
6987/// Fixed-capacity `[u32; MAX_BETTI_DIMENSION]` backing; no heap.
6988#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6989pub struct BettiMetric {
6990    values: [u32; MAX_BETTI_DIMENSION],
6991    _sealed: (),
6992}
6993
6994impl BettiMetric {
6995    /// Returns the Betti-number vector as a fixed-size array reference.
6996    #[inline]
6997    #[must_use]
6998    pub const fn as_array(&self) -> &[u32; MAX_BETTI_DIMENSION] {
6999        &self.values
7000    }
7001
7002    /// Returns the individual Betti number βₖ for dimension k.
7003    /// Returns 0 when k >= MAX_BETTI_DIMENSION.
7004    #[inline]
7005    #[must_use]
7006    pub const fn beta(&self, k: usize) -> u32 {
7007        if k < MAX_BETTI_DIMENSION {
7008            self.values[k]
7009        } else {
7010            0
7011        }
7012    }
7013
7014    /// Crate-internal constructor.
7015    #[inline]
7016    #[must_use]
7017    #[allow(dead_code)]
7018    pub(crate) const fn new(values: [u32; MAX_BETTI_DIMENSION]) -> Self {
7019        Self {
7020            values,
7021            _sealed: (),
7022        }
7023    }
7024}
7025
7026/// Maximum site count of the Jacobian row per Datum at any supported
7027/// WittLevel. Sourced from the partition:FreeRank capacity bound.
7028/// v0.2.2 T2.6 (cleanup): reduced from 64 to 8 to keep `Grounded` under
7029/// the 256-byte size budget enforced by `phantom_tag::grounded_sealed_field_count_unchanged`.
7030/// 8 matches `MAX_BETTI_DIMENSION` and is sufficient for the v0.2.2 partition rank set.
7031/// Wiki ADR-037: a foundation-fixed conservative default for
7032/// [`crate::HostBounds::JACOBIAN_SITES_MAX`].
7033pub const JACOBIAN_MAX_SITES: usize = 8;
7034
7035/// v0.2.2 Phase E: sealed Jacobian row carrier, parametric over the
7036/// WittLevel marker. Fixed-size `[i64; JACOBIAN_MAX_SITES]` backing; no
7037/// heap. The row records the per-site partial derivative of the ring
7038/// operation that produced the Datum. Backs observable:JacobianObservable.
7039#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7040pub struct JacobianMetric<L> {
7041    entries: [i64; JACOBIAN_MAX_SITES],
7042    len: u16,
7043    _level: PhantomData<L>,
7044    _sealed: (),
7045}
7046
7047impl<L> JacobianMetric<L> {
7048    /// Construct a zeroed Jacobian row with the given active length.
7049    #[inline]
7050    #[must_use]
7051    #[allow(dead_code)]
7052    pub(crate) const fn zero(len: u16) -> Self {
7053        Self {
7054            entries: [0i64; JACOBIAN_MAX_SITES],
7055            len,
7056            _level: PhantomData,
7057            _sealed: (),
7058        }
7059    }
7060
7061    /// v0.2.2 T2.6 (cleanup): crate-internal constructor used by the
7062    /// BaseMetric accessor on `Grounded` to return a `JacobianMetric`
7063    /// backed by stored field values.
7064    #[inline]
7065    #[must_use]
7066    #[allow(dead_code)]
7067    pub(crate) const fn from_entries(entries: [i64; JACOBIAN_MAX_SITES], len: u16) -> Self {
7068        Self {
7069            entries,
7070            len,
7071            _level: PhantomData,
7072            _sealed: (),
7073        }
7074    }
7075
7076    /// Access the Jacobian row entries.
7077    #[inline]
7078    #[must_use]
7079    pub const fn entries(&self) -> &[i64; JACOBIAN_MAX_SITES] {
7080        &self.entries
7081    }
7082
7083    /// Number of active sites (the row's logical length).
7084    #[inline]
7085    #[must_use]
7086    pub const fn len(&self) -> u16 {
7087        self.len
7088    }
7089
7090    /// Whether the Jacobian row is empty.
7091    #[inline]
7092    #[must_use]
7093    pub const fn is_empty(&self) -> bool {
7094        self.len == 0
7095    }
7096}
7097
7098/// v0.2.2 Phase E: sealed Partition component classification.
7099/// Closed enumeration mirroring the partition:PartitionComponent
7100/// ontology class.
7101#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7102#[non_exhaustive]
7103pub enum PartitionComponent {
7104    /// The irreducible component.
7105    Irreducible,
7106    /// The reducible component.
7107    Reducible,
7108    /// The unit component.
7109    Units,
7110    /// The exterior component.
7111    Exterior,
7112}
7113
7114/// Sealed marker trait identifying type:ConstrainedType subclasses that may
7115/// appear as the parameter of `Grounded<T>`.
7116/// Per wiki ADR-027, the seal is the same `__sdk_seal::Sealed` supertrait
7117/// foundation uses for `FoundationClosed`, `PrismModel`, and
7118/// `IntoBindingValue`: only foundation and the SDK shape macros emit
7119/// impls. The foundation-sanctioned identity output `ConstrainedTypeInput`
7120/// retains its direct impl; application authors declaring custom Output
7121/// shapes invoke the `output_shape!` SDK macro, which emits
7122/// `__sdk_seal::Sealed`, `GroundedShape`, `IntoBindingValue`, and
7123/// `ConstrainedTypeShape` together.
7124pub trait GroundedShape: crate::pipeline::__sdk_seal::Sealed {}
7125impl GroundedShape for ConstrainedTypeInput {}
7126
7127/// v0.2.2 T4.2: sealed content-addressed handle.
7128/// Wraps a 128-bit identity used for `BindingsTable` lookups and as a
7129/// compact identity handle for `Grounded` values. The underlying `u128`
7130/// is visible via `as_u128()` for interop. Distinct from
7131/// `ContentFingerprint` (the parametric-width fingerprint computed by
7132/// the substrate `Hasher` — see T5.C3.d below): `ContentAddress` is a
7133/// fixed 16-byte sortable handle, while `ContentFingerprint` is the full
7134/// substrate-computed identity that round-trips through `verify_trace`.
7135#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7136pub struct ContentAddress {
7137    raw: u128,
7138    _sealed: (),
7139}
7140
7141impl ContentAddress {
7142    /// The zero content address. Used as the "unset" placeholder in
7143    /// `BindingsTable` lookups, the default state of an uninitialised
7144    /// `Grounded::unit_address`, and the initial seed of replay folds.
7145    #[inline]
7146    #[must_use]
7147    pub const fn zero() -> Self {
7148        Self {
7149            raw: 0,
7150            _sealed: (),
7151        }
7152    }
7153
7154    /// Returns the underlying 128-bit content hash.
7155    #[inline]
7156    #[must_use]
7157    pub const fn as_u128(&self) -> u128 {
7158        self.raw
7159    }
7160
7161    /// Whether this content address is the zero handle.
7162    #[inline]
7163    #[must_use]
7164    pub const fn is_zero(&self) -> bool {
7165        self.raw == 0
7166    }
7167
7168    /// v0.2.2 T5.C1: public ctor. Promoted from `pub(crate)` in T5 so
7169    /// downstream tests can construct deterministic `ContentAddress` values
7170    /// for fixture data without going through the foundation pipeline.
7171    #[inline]
7172    #[must_use]
7173    pub const fn from_u128(raw: u128) -> Self {
7174        Self { raw, _sealed: () }
7175    }
7176
7177    /// v0.2.2 Phase P.3: construct a `ContentAddress` from a `u64` FNV-1a fingerprint
7178    /// by right-padding the value into the 128-bit address space. Used by
7179    /// `Binding::to_binding_entry` to bridge the `Binding.content_address: u64`
7180    /// carrier to the `BindingEntry.address: ContentAddress` (`u128`-backed) shape.
7181    /// The lift is `raw = (fingerprint as u128) << 64` — upper 64 bits carry the
7182    /// FNV-1a value; lower 64 bits are zero. Content-deterministic; round-trips via
7183    /// `ContentAddress::as_u128() >> 64` back to the original `u64`.
7184    #[inline]
7185    #[must_use]
7186    pub const fn from_u64_fingerprint(fingerprint: u64) -> Self {
7187        Self {
7188            raw: (fingerprint as u128) << 64,
7189            _sealed: (),
7190        }
7191    }
7192}
7193
7194impl Default for ContentAddress {
7195    #[inline]
7196    fn default() -> Self {
7197        Self::zero()
7198    }
7199}
7200
7201/// Trace wire-format identifier. Per the wiki's ADR-018, wire-format
7202/// identifiers are explicitly carved out of the `HostBounds` rule because
7203/// cross-implementation interop requires a single shared format identifier.
7204/// Increment when the layout changes (event ordering, trailing fields,
7205/// primitive-op discriminant table, certificate-kind discriminant table).
7206/// Pinned by the `rust/trace_byte_layout_pinned` conformance validator.
7207pub const TRACE_REPLAY_FORMAT_VERSION: u16 = 10;
7208
7209/// v0.2.2 T5: pluggable content hasher with parametric output width.
7210/// The foundation does not ship an implementation. Downstream substrate
7211/// consumers (PRISM, application crates) supply their own `Hasher` impl
7212/// — BLAKE3, SHA-256, SHA-512, BLAKE2b, SipHash 2-4, FNV-1a, or any
7213/// other byte-stream hash whose output width satisfies the foundation's
7214/// derived collision-bound minimum.
7215/// # Foundation recommendation
7216/// The foundation **recommends BLAKE3** as the default substrate hash for
7217/// production deployments. BLAKE3 is fast, well-audited, has no known
7218/// cryptographic weaknesses, supports parallel and SIMD-accelerated
7219/// implementations, and has a flexible output length. PRISM ships a BLAKE3
7220/// `Hasher` impl as its production substrate; application crates should
7221/// use it unless they have a specific reason to deviate.
7222/// The recommendation is non-binding: any conforming `Hasher` impl works
7223/// with the foundation's pipeline and verify path. The foundation never
7224/// invokes a hash function itself, so the choice is fully a downstream
7225/// decision.
7226/// # Architecture
7227/// The architectural shape mirrors `Calibration`: the foundation defines
7228/// the abstract quantity (`ContentFingerprint`) and the substitution point
7229/// (`Hasher`); downstream provides the concrete substrate AND chooses the
7230/// output width within the foundation's correctness budget.
7231/// # Required laws
7232/// 1. **Width-in-budget**: `OUTPUT_BYTES` must be in
7233///    `[<B as HostBounds>::FINGERPRINT_MIN_BYTES, FP_MAX]` where `FP_MAX`
7234///    is the const-generic carrying `<B as HostBounds>::FINGERPRINT_MAX_BYTES`.
7235///    Enforced at codegen time via a `const _: () = assert!(...)` block
7236///    emitted inside every `pipeline::run::<T, _, H>` body.
7237/// 2. **Determinism**: identical byte sequences produce bit-identical outputs
7238///    across program runs, builds, target architectures, and rustc versions.
7239/// 3. **Sensitivity**: hashing two byte sequences that differ in any byte
7240///    produces two distinct outputs with probability bounded by the hasher's
7241///    documented collision rate.
7242/// 4. **No interior mutability**: `fold_byte` consumes `self` and returns a
7243///    new state. Impls that depend on hidden mutable state violate the contract.
7244/// # Example
7245/// ```
7246/// use uor_foundation::enforcement::Hasher;
7247/// /// Minimal 128-bit (16-byte) FNV-1a substrate — two 64-bit lanes.
7248/// #[derive(Clone, Copy)]
7249/// pub struct Fnv1a16 { a: u64, b: u64 }
7250/// impl Hasher for Fnv1a16 {
7251///     const OUTPUT_BYTES: usize = 16;
7252///     fn initial() -> Self {
7253///         Self { a: 0xcbf29ce484222325, b: 0x84222325cbf29ce4 }
7254///     }
7255///     fn fold_byte(mut self, x: u8) -> Self {
7256///         self.a ^= x as u64;
7257///         self.a = self.a.wrapping_mul(0x100000001b3);
7258///         self.b ^= (x as u64).rotate_left(8);
7259///         self.b = self.b.wrapping_mul(0x100000001b3);
7260///         self
7261///     }
7262///     fn finalize(self) -> [u8; 32] {
7263///         let mut buf = [0u8; 32];
7264///         buf[..8].copy_from_slice(&self.a.to_be_bytes());
7265///         buf[8..16].copy_from_slice(&self.b.to_be_bytes());
7266///         buf
7267///     }
7268/// }
7269/// ```
7270/// Above, `Hasher` is reached through its default const-generic
7271/// `<FP_MAX = 32>` (the conventional 32-byte fingerprint width).
7272/// Applications that select a different `HostBounds` impl write
7273/// `impl Hasher<{<MyBounds as HostBounds>::FINGERPRINT_MAX_BYTES}> for MyHasher`.
7274pub trait Hasher<const FP_MAX: usize = 32> {
7275    /// Active output width in bytes. Must lie within the bounds
7276    /// the application's selected `HostBounds` declares —
7277    /// `[<B as HostBounds>::FINGERPRINT_MIN_BYTES, FP_MAX]`.
7278    const OUTPUT_BYTES: usize;
7279
7280    /// Initial hasher state.
7281    fn initial() -> Self;
7282
7283    /// Fold a single byte into the running state.
7284    #[must_use]
7285    fn fold_byte(self, b: u8) -> Self;
7286
7287    /// Fold a slice of bytes (default impl: byte-by-byte).
7288    #[inline]
7289    #[must_use]
7290    fn fold_bytes(mut self, bytes: &[u8]) -> Self
7291    where
7292        Self: Sized,
7293    {
7294        let mut i = 0;
7295        while i < bytes.len() {
7296            self = self.fold_byte(bytes[i]);
7297            i += 1;
7298        }
7299        self
7300    }
7301
7302    /// Finalize into the canonical max-width buffer of `FP_MAX` bytes.
7303    /// Bytes `0..OUTPUT_BYTES` carry the hash result; bytes
7304    /// `OUTPUT_BYTES..FP_MAX` MUST be zero.
7305    fn finalize(self) -> [u8; FP_MAX];
7306}
7307
7308/// ADR-030 adapter: wrap any [`Hasher`] impl as an
7309/// [`crate::pipeline::AxisExtension`]. The lone supported kernel id
7310/// is [`HashAxis::KERNEL_HASH`] = 0, which folds the input bytes
7311/// through the wrapped Hasher and writes the first `OUTPUT_BYTES`
7312/// digest bytes to the caller-provided buffer.
7313#[derive(Debug, Clone, Copy)]
7314pub struct HashAxis<H>(core::marker::PhantomData<H>);
7315
7316impl<H> HashAxis<H> {
7317    /// Canonical kernel id for the hash operation. The closure-body
7318    /// grammar G19 form `hash(input)` lowers to
7319    /// `Term::AxisInvocation { axis_index: 0, kernel_id: HashAxis::KERNEL_HASH, input_index }`.
7320    pub const KERNEL_HASH: u32 = 0;
7321}
7322
7323impl<H> crate::pipeline::__sdk_seal::Sealed for HashAxis<H> {}
7324impl<const INLINE_BYTES: usize, H> crate::pipeline::SubstrateTermBody<INLINE_BYTES>
7325    for HashAxis<H>
7326{
7327    fn body_arena() -> &'static [Term<'static, INLINE_BYTES>] {
7328        &[]
7329    }
7330}
7331impl<const INLINE_BYTES: usize, const FP_MAX: usize, H: Hasher<FP_MAX>>
7332    crate::pipeline::AxisExtension<INLINE_BYTES, FP_MAX> for HashAxis<H>
7333{
7334    const AXIS_ADDRESS: &'static str = "https://uor.foundation/axis/HashAxis";
7335    const MAX_OUTPUT_BYTES: usize = <H as Hasher<FP_MAX>>::OUTPUT_BYTES;
7336    fn dispatch_kernel(
7337        kernel_id: u32,
7338        input: &[u8],
7339        out: &mut [u8],
7340    ) -> Result<usize, ShapeViolation> {
7341        if kernel_id != Self::KERNEL_HASH {
7342            return Err(ShapeViolation {
7343                shape_iri: "https://uor.foundation/axis/HashAxis",
7344                constraint_iri: "https://uor.foundation/axis/HashAxis/kernelId",
7345                property_iri: "https://uor.foundation/axis/kernelId",
7346                expected_range: "https://uor.foundation/axis/HashAxis/KERNEL_HASH",
7347                min_count: 0,
7348                max_count: 1,
7349                kind: crate::ViolationKind::ValueCheck,
7350            });
7351        }
7352        let mut hasher = <H as Hasher<FP_MAX>>::initial();
7353        hasher = hasher.fold_bytes(input);
7354        let digest = hasher.finalize();
7355        let n = <H as Hasher<FP_MAX>>::OUTPUT_BYTES
7356            .min(out.len())
7357            .min(digest.len());
7358        let mut i = 0;
7359        while i < n {
7360            out[i] = digest[i];
7361            i += 1;
7362        }
7363        Ok(n)
7364    }
7365}
7366
7367/// Sealed parametric content fingerprint.
7368/// Wraps a fixed-capacity byte buffer of `FP_MAX` bytes plus the
7369/// active width in bytes. `FP_MAX` is the const-generic that carries
7370/// the application's selected `HostBounds::FINGERPRINT_MAX_BYTES`
7371/// (default = 32, the conventional fingerprint width). The active width
7372/// is set by the producing `Hasher::OUTPUT_BYTES` and recorded so
7373/// downstream can distinguish "this is a 128-bit fingerprint" from
7374/// "this is a 256-bit fingerprint" without inspecting trailing zeros.
7375/// Equality is bit-equality on the full buffer + width tag, so two
7376/// fingerprints from different hashers (different widths) are never
7377/// equal even if their leading bytes happen to coincide. This prevents
7378/// silent collisions when downstream consumers mix substrate hashers.
7379#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7380pub struct ContentFingerprint<const FP_MAX: usize = 32> {
7381    bytes: [u8; FP_MAX],
7382    width_bytes: u8,
7383    _sealed: (),
7384}
7385
7386impl<const FP_MAX: usize> ContentFingerprint<FP_MAX> {
7387    /// Crate-internal zero placeholder. Used internally as the
7388    /// `Trace::empty()` field initializer and the `Default` impl. Not
7389    /// publicly constructible; downstream that needs a `ContentFingerprint`
7390    /// constructs one via `Hasher::finalize()` followed by `from_buffer()`.
7391    #[inline]
7392    #[must_use]
7393    #[allow(dead_code)]
7394    pub(crate) const fn zero() -> Self {
7395        Self {
7396            bytes: [0u8; FP_MAX],
7397            width_bytes: 0,
7398            _sealed: (),
7399        }
7400    }
7401
7402    /// Whether this fingerprint is the all-zero placeholder.
7403    #[inline]
7404    #[must_use]
7405    pub const fn is_zero(&self) -> bool {
7406        self.width_bytes == 0
7407    }
7408
7409    /// Active width in bytes (set by the producing hasher).
7410    #[inline]
7411    #[must_use]
7412    pub const fn width_bytes(&self) -> u8 {
7413        self.width_bytes
7414    }
7415
7416    /// Active width in bits (`width_bytes * 8`).
7417    #[inline]
7418    #[must_use]
7419    pub const fn width_bits(&self) -> u16 {
7420        (self.width_bytes as u16) * 8
7421    }
7422
7423    /// The full buffer. Bytes `0..width_bytes` are the hash; bytes
7424    /// `width_bytes..FP_MAX` are zero.
7425    #[inline]
7426    #[must_use]
7427    pub const fn as_bytes(&self) -> &[u8; FP_MAX] {
7428        &self.bytes
7429    }
7430
7431    /// Construct a fingerprint from a hasher's finalize buffer + width tag.
7432    /// Production paths reach this via `pipeline::run::<T, _, H>`; test
7433    /// paths via the `__test_helpers` back-door.
7434    #[inline]
7435    #[must_use]
7436    pub const fn from_buffer(bytes: [u8; FP_MAX], width_bytes: u8) -> Self {
7437        Self {
7438            bytes,
7439            width_bytes,
7440            _sealed: (),
7441        }
7442    }
7443}
7444
7445impl<const FP_MAX: usize> Default for ContentFingerprint<FP_MAX> {
7446    #[inline]
7447    fn default() -> Self {
7448        Self::zero()
7449    }
7450}
7451
7452/// v0.2.2 T5: stable u8 discriminant for `PrimitiveOp`. Locked to the
7453/// codegen output order; do not reorder `PrimitiveOp` variants without
7454/// bumping `TRACE_REPLAY_FORMAT_VERSION`. Folded into the canonical byte
7455/// layout of every `TraceEvent` so substrate hashers produce stable
7456/// fingerprints across builds.
7457#[inline]
7458#[must_use]
7459pub const fn primitive_op_discriminant(op: crate::PrimitiveOp) -> u8 {
7460    match op {
7461        crate::PrimitiveOp::Neg => 0,
7462        crate::PrimitiveOp::Bnot => 1,
7463        crate::PrimitiveOp::Succ => 2,
7464        crate::PrimitiveOp::Pred => 3,
7465        crate::PrimitiveOp::Add => 4,
7466        crate::PrimitiveOp::Sub => 5,
7467        crate::PrimitiveOp::Mul => 6,
7468        crate::PrimitiveOp::Xor => 7,
7469        crate::PrimitiveOp::And => 8,
7470        crate::PrimitiveOp::Or => 9,
7471        // ADR-013/TR-08 substrate amendment: byte-level ops 10..15.
7472        crate::PrimitiveOp::Le => 10,
7473        crate::PrimitiveOp::Lt => 11,
7474        crate::PrimitiveOp::Ge => 12,
7475        crate::PrimitiveOp::Gt => 13,
7476        crate::PrimitiveOp::Concat => 14,
7477        // ADR-053 substrate amendment: ring-axis arithmetic completion.
7478        crate::PrimitiveOp::Div => 15,
7479        crate::PrimitiveOp::Mod => 16,
7480        crate::PrimitiveOp::Pow => 17,
7481    }
7482}
7483
7484/// v0.2.2 T5: stable u8 discriminant tag distinguishing the certificate
7485/// kinds the foundation pipeline mints. Folded into the trailing byte of
7486/// every canonical digest so two certificates over the same source unit
7487/// but of different kinds produce distinct fingerprints. Locked at v0.2.2;
7488/// reordering or inserting variants requires bumping
7489/// `TRACE_REPLAY_FORMAT_VERSION`.
7490#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7491#[non_exhaustive]
7492pub enum CertificateKind {
7493    /// Cert minted by `pipeline::run` and `run_const` (retained for
7494    /// `run_grounding_aware`).
7495    Grounding,
7496    /// Cert minted by `certify_tower_completeness_const`.
7497    TowerCompleteness,
7498    /// Cert minted by `certify_incremental_completeness_const`.
7499    IncrementalCompleteness,
7500    /// Cert minted by `certify_inhabitance_const` / `run_inhabitance`.
7501    Inhabitance,
7502    /// Cert minted by `certify_multiplication_const`.
7503    Multiplication,
7504    /// Cert minted by `resolver::two_sat_decider::certify`.
7505    TwoSat,
7506    /// Cert minted by `resolver::horn_sat_decider::certify`.
7507    HornSat,
7508    /// Cert minted by `resolver::residual_verdict::certify`.
7509    ResidualVerdict,
7510    /// Cert minted by `resolver::canonical_form::certify`.
7511    CanonicalForm,
7512    /// Cert minted by `resolver::type_synthesis::certify`.
7513    TypeSynthesis,
7514    /// Cert minted by `resolver::homotopy::certify`.
7515    Homotopy,
7516    /// Cert minted by `resolver::monodromy::certify`.
7517    Monodromy,
7518    /// Cert minted by `resolver::moduli::certify`.
7519    Moduli,
7520    /// Cert minted by `resolver::jacobian_guided::certify`.
7521    JacobianGuided,
7522    /// Cert minted by `resolver::evaluation::certify`.
7523    Evaluation,
7524    /// Cert minted by `resolver::session::certify`.
7525    Session,
7526    /// Cert minted by `resolver::superposition::certify`.
7527    Superposition,
7528    /// Cert minted by `resolver::measurement::certify`.
7529    Measurement,
7530    /// Cert minted by `resolver::witt_level_resolver::certify`.
7531    WittLevel,
7532    /// Cert minted by `resolver::dihedral_factorization::certify`.
7533    DihedralFactorization,
7534    /// Cert minted by `resolver::completeness::certify`.
7535    Completeness,
7536    /// Cert minted by `resolver::geodesic_validator::certify`.
7537    GeodesicValidator,
7538}
7539
7540/// v0.2.2 T5: stable u8 discriminant for `CertificateKind`. Folded into
7541/// the trailing byte of canonical digests via the `*Digest` types so two
7542/// distinct certificate kinds over the same source unit produce distinct
7543/// fingerprints. Locked at v0.2.2.
7544#[inline]
7545#[must_use]
7546pub const fn certificate_kind_discriminant(kind: CertificateKind) -> u8 {
7547    match kind {
7548        CertificateKind::Grounding => 1,
7549        CertificateKind::TowerCompleteness => 2,
7550        CertificateKind::IncrementalCompleteness => 3,
7551        CertificateKind::Inhabitance => 4,
7552        CertificateKind::Multiplication => 5,
7553        CertificateKind::TwoSat => 6,
7554        CertificateKind::HornSat => 7,
7555        CertificateKind::ResidualVerdict => 8,
7556        CertificateKind::CanonicalForm => 9,
7557        CertificateKind::TypeSynthesis => 10,
7558        CertificateKind::Homotopy => 11,
7559        CertificateKind::Monodromy => 12,
7560        CertificateKind::Moduli => 13,
7561        CertificateKind::JacobianGuided => 14,
7562        CertificateKind::Evaluation => 15,
7563        CertificateKind::Session => 16,
7564        CertificateKind::Superposition => 17,
7565        CertificateKind::Measurement => 18,
7566        CertificateKind::WittLevel => 19,
7567        CertificateKind::DihedralFactorization => 20,
7568        CertificateKind::Completeness => 21,
7569        CertificateKind::GeodesicValidator => 22,
7570    }
7571}
7572
7573/// v0.2.2 T5: fold a `ConstraintRef` into a `Hasher` via the canonical
7574/// byte layout. Each variant emits a discriminant byte (1..=9) followed by
7575/// its payload bytes in big-endian order. Locked at v0.2.2; reordering
7576/// variants requires bumping `TRACE_REPLAY_FORMAT_VERSION`.
7577/// Used by `pipeline::run`, `run_const`, and the four `certify_*` entry
7578/// points to fold a unit's constraint set into the substrate fingerprint.
7579pub fn fold_constraint_ref<const FP_MAX: usize, H: Hasher<FP_MAX>>(
7580    mut hasher: H,
7581    c: &crate::pipeline::ConstraintRef,
7582) -> H {
7583    use crate::pipeline::ConstraintRef as C;
7584    match c {
7585        C::Residue { modulus, residue } => {
7586            hasher = hasher.fold_byte(1);
7587            hasher = hasher.fold_bytes(&modulus.to_be_bytes());
7588            hasher = hasher.fold_bytes(&residue.to_be_bytes());
7589        }
7590        C::Hamming { bound } => {
7591            hasher = hasher.fold_byte(2);
7592            hasher = hasher.fold_bytes(&bound.to_be_bytes());
7593        }
7594        C::Depth { min, max } => {
7595            hasher = hasher.fold_byte(3);
7596            hasher = hasher.fold_bytes(&min.to_be_bytes());
7597            hasher = hasher.fold_bytes(&max.to_be_bytes());
7598        }
7599        C::Carry { site } => {
7600            hasher = hasher.fold_byte(4);
7601            hasher = hasher.fold_bytes(&site.to_be_bytes());
7602        }
7603        C::Site { position } => {
7604            hasher = hasher.fold_byte(5);
7605            hasher = hasher.fold_bytes(&position.to_be_bytes());
7606        }
7607        C::Affine {
7608            coefficients,
7609            coefficient_count,
7610            bias,
7611        } => {
7612            hasher = hasher.fold_byte(6);
7613            hasher = hasher.fold_bytes(&coefficient_count.to_be_bytes());
7614            let count = *coefficient_count as usize;
7615            let mut i = 0;
7616            while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS {
7617                hasher = hasher.fold_bytes(&coefficients[i].to_be_bytes());
7618                i += 1;
7619            }
7620            hasher = hasher.fold_bytes(&bias.to_be_bytes());
7621        }
7622        C::SatClauses { clauses, num_vars } => {
7623            hasher = hasher.fold_byte(7);
7624            hasher = hasher.fold_bytes(&num_vars.to_be_bytes());
7625            hasher = hasher.fold_bytes(&(clauses.len() as u32).to_be_bytes());
7626            let mut i = 0;
7627            while i < clauses.len() {
7628                let clause = clauses[i];
7629                hasher = hasher.fold_bytes(&(clause.len() as u32).to_be_bytes());
7630                let mut j = 0;
7631                while j < clause.len() {
7632                    let (var, neg) = clause[j];
7633                    hasher = hasher.fold_bytes(&var.to_be_bytes());
7634                    hasher = hasher.fold_byte(if neg { 1 } else { 0 });
7635                    j += 1;
7636                }
7637                i += 1;
7638            }
7639        }
7640        C::Bound {
7641            observable_iri,
7642            bound_shape_iri,
7643            args_repr,
7644        } => {
7645            hasher = hasher.fold_byte(8);
7646            hasher = hasher.fold_bytes(observable_iri.as_bytes());
7647            hasher = hasher.fold_byte(0);
7648            hasher = hasher.fold_bytes(bound_shape_iri.as_bytes());
7649            hasher = hasher.fold_byte(0);
7650            hasher = hasher.fold_bytes(args_repr.as_bytes());
7651            hasher = hasher.fold_byte(0);
7652        }
7653        C::Conjunction {
7654            conjuncts,
7655            conjunct_count,
7656        } => {
7657            hasher = hasher.fold_byte(9);
7658            hasher = hasher.fold_bytes(&conjunct_count.to_be_bytes());
7659            let count = *conjunct_count as usize;
7660            let mut i = 0;
7661            while i < count && i < crate::pipeline::CONJUNCTION_MAX_TERMS {
7662                let lifted = conjuncts[i].into_constraint();
7663                hasher = fold_constraint_ref(hasher, &lifted);
7664                i += 1;
7665            }
7666        }
7667        // ADR-057 wire-format: discriminant byte 10 + content-addressed
7668        // shape_iri + descent_bound. The discriminant table extension
7669        // requires TRACE_REPLAY_FORMAT_VERSION bump per ADR-013/TR-08.
7670        C::Recurse {
7671            shape_iri,
7672            descent_bound,
7673        } => {
7674            hasher = hasher.fold_byte(10);
7675            hasher = hasher.fold_bytes(shape_iri.as_bytes());
7676            hasher = hasher.fold_byte(0);
7677            hasher = hasher.fold_bytes(&descent_bound.to_be_bytes());
7678        }
7679    }
7680    hasher
7681}
7682
7683/// v0.2.2 T5: fold the canonical CompileUnit byte layout into a `Hasher`.
7684/// Layout: `level_bits (2 BE) || budget (8 BE) || iri bytes || 0x00 ||
7685/// site_count (8 BE) || for each constraint: fold_constraint_ref ||
7686/// certificate_kind_discriminant (1 byte trailing)`.
7687/// Locked at v0.2.2 by the `rust/trace_byte_layout_pinned` conformance
7688/// validator. Used by `pipeline::run`, `run_const`, and the four
7689/// `certify_*` entry points.
7690pub fn fold_unit_digest<const FP_MAX: usize, H: Hasher<FP_MAX>>(
7691    mut hasher: H,
7692    level_bits: u16,
7693    budget: u64,
7694    iri: &str,
7695    site_count: usize,
7696    constraints: &[crate::pipeline::ConstraintRef],
7697    kind: CertificateKind,
7698) -> H {
7699    hasher = hasher.fold_bytes(&level_bits.to_be_bytes());
7700    hasher = hasher.fold_bytes(&budget.to_be_bytes());
7701    hasher = hasher.fold_bytes(iri.as_bytes());
7702    hasher = hasher.fold_byte(0);
7703    hasher = hasher.fold_bytes(&(site_count as u64).to_be_bytes());
7704    let mut i = 0;
7705    while i < constraints.len() {
7706        hasher = fold_constraint_ref(hasher, &constraints[i]);
7707        i += 1;
7708    }
7709    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7710    hasher
7711}
7712
7713/// v0.2.2 T5: fold the canonical ParallelDeclaration byte layout into a `Hasher`.
7714/// Layout: `site_count (8 BE) || iri bytes || 0x00 || decl_site_count (8 BE) ||
7715/// for each constraint: fold_constraint_ref || certificate_kind_discriminant`.
7716pub fn fold_parallel_digest<const FP_MAX: usize, H: Hasher<FP_MAX>>(
7717    mut hasher: H,
7718    decl_site_count: u64,
7719    iri: &str,
7720    type_site_count: usize,
7721    constraints: &[crate::pipeline::ConstraintRef],
7722    kind: CertificateKind,
7723) -> H {
7724    hasher = hasher.fold_bytes(&decl_site_count.to_be_bytes());
7725    hasher = hasher.fold_bytes(iri.as_bytes());
7726    hasher = hasher.fold_byte(0);
7727    hasher = hasher.fold_bytes(&(type_site_count as u64).to_be_bytes());
7728    let mut i = 0;
7729    while i < constraints.len() {
7730        hasher = fold_constraint_ref(hasher, &constraints[i]);
7731        i += 1;
7732    }
7733    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7734    hasher
7735}
7736
7737/// v0.2.2 T5: fold the canonical StreamDeclaration byte layout into a `Hasher`.
7738pub fn fold_stream_digest<const FP_MAX: usize, H: Hasher<FP_MAX>>(
7739    mut hasher: H,
7740    productivity_bound: u64,
7741    iri: &str,
7742    constraints: &[crate::pipeline::ConstraintRef],
7743    kind: CertificateKind,
7744) -> H {
7745    hasher = hasher.fold_bytes(&productivity_bound.to_be_bytes());
7746    hasher = hasher.fold_bytes(iri.as_bytes());
7747    hasher = hasher.fold_byte(0);
7748    let mut i = 0;
7749    while i < constraints.len() {
7750        hasher = fold_constraint_ref(hasher, &constraints[i]);
7751        i += 1;
7752    }
7753    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7754    hasher
7755}
7756
7757/// v0.2.2 T5: fold the canonical InteractionDeclaration byte layout into a `Hasher`.
7758pub fn fold_interaction_digest<const FP_MAX: usize, H: Hasher<FP_MAX>>(
7759    mut hasher: H,
7760    convergence_seed: u64,
7761    iri: &str,
7762    constraints: &[crate::pipeline::ConstraintRef],
7763    kind: CertificateKind,
7764) -> H {
7765    hasher = hasher.fold_bytes(&convergence_seed.to_be_bytes());
7766    hasher = hasher.fold_bytes(iri.as_bytes());
7767    hasher = hasher.fold_byte(0);
7768    let mut i = 0;
7769    while i < constraints.len() {
7770        hasher = fold_constraint_ref(hasher, &constraints[i]);
7771        i += 1;
7772    }
7773    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
7774    hasher
7775}
7776
7777/// v0.2.2 Phase J primitive: `reduction:ReductionStep` / `recursion:BoundedRecursion`.
7778/// Content-deterministic reduction signature: `(witt_bits, constraint_count, satisfiable_bit)`.
7779pub(crate) fn primitive_terminal_reduction<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
7780    witt_bits: u16,
7781) -> Result<(u16, u32, u8), PipelineFailure> {
7782    let outcome = crate::pipeline::run_reduction_stages::<T>(witt_bits)?;
7783    let satisfiable_bit: u8 = if outcome.satisfiable { 1 } else { 0 };
7784    Ok((
7785        outcome.witt_bits,
7786        T::CONSTRAINTS.len() as u32,
7787        satisfiable_bit,
7788    ))
7789}
7790
7791/// v0.2.2 Phase J: fold the TerminalReduction triple into the hasher.
7792pub(crate) fn fold_terminal_reduction<const FP_MAX: usize, H: Hasher<FP_MAX>>(
7793    mut hasher: H,
7794    witt_bits: u16,
7795    constraint_count: u32,
7796    satisfiable_bit: u8,
7797) -> H {
7798    hasher = hasher.fold_bytes(&witt_bits.to_be_bytes());
7799    hasher = hasher.fold_bytes(&constraint_count.to_be_bytes());
7800    hasher = hasher.fold_byte(satisfiable_bit);
7801    hasher
7802}
7803
7804/// Phase X.4: `resolver:CechNerve` / `homology:ChainComplex`.
7805/// Computes the content-deterministic Betti tuple `[b_0, b_1, b_2, 0, .., 0]`
7806/// from the 2-complex constraint-nerve over `T::CONSTRAINTS`:
7807/// vertices = constraints, 1-simplices = pairs of constraints with intersecting
7808/// site support, 2-simplices = triples of constraints with a common site.
7809/// `b_k = dim ker(∂_k) - dim im(∂_{k+1})` for k ∈ {0,1,2}; `b_3..b_7 = 0`.
7810/// Ranks of the boundary operators ∂_1, ∂_2 are computed over ℤ/p (p prime,
7811/// `NERVE_RANK_MOD_P = 1_000_000_007`) by `integer_matrix_rank`. Nerve boundary
7812/// matrices have ±1/0 entries and are totally unimodular, so rank over ℤ/p
7813/// equals rank over ℚ equals rank over ℤ for any prime p not dividing a minor.
7814/// Phase 1a (orphan-closure): inputs larger than `NERVE_CONSTRAINTS_CAP = 8`
7815/// constraints or `NERVE_SITES_CAP = 8` sites return
7816/// `Err(GenericImpossibilityWitness::for_identity("NERVE_CAPACITY_EXCEEDED"))`
7817/// rather than silently truncating — truncation produced Betti numbers for a
7818/// differently-shaped complex than the caller asked about. Callers propagate
7819/// the witness via `?` (pattern mirrored on `primitive_terminal_reduction`).
7820/// ADR-057: `T::CONSTRAINTS` may contain `ConstraintRef::Recurse` entries
7821/// referencing shapes by IRI. This primitive expands Recurse references
7822/// through the **foundation built-in shape-IRI registry** (`lookup_shape`),
7823/// decrementing the descent budget on each Recurse encountered and
7824/// terminating when the budget reaches zero. Applications that register
7825/// their own shapes (via the SDK `register_shape!` macro) use
7826/// [`primitive_simplicial_nerve_betti_in`] which is generic over the
7827/// application's `ShapeRegistryProvider`. The structural reading at ψ_1
7828/// reflects the expanded constraint geometry — Recurse entries are not
7829/// opaque anonymous Sites but their structurally-substituted body per the
7830/// registered shape's `CONSTRAINTS` array.
7831/// # Errors
7832/// Returns `NERVE_CAPACITY_EXCEEDED` when either cap is exceeded after
7833/// expansion. Returns `RECURSE_SHAPE_UNREGISTERED` when a `Recurse`
7834/// entry references an IRI not present in the consulted registry
7835/// (non-zero descent budget).
7836pub fn primitive_simplicial_nerve_betti<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
7837) -> Result<[u32; MAX_BETTI_DIMENSION], GenericImpossibilityWitness> {
7838    // ADR-057: foundation-default registry path. EmptyShapeRegistry's
7839    // REGISTRY is the empty slice, so lookup_shape_in falls through to
7840    // foundation's built-in FOUNDATION_REGISTRY (the canonical stdlib path).
7841    primitive_simplicial_nerve_betti_in::<T, crate::pipeline::shape_iri_registry::EmptyShapeRegistry>(
7842    )
7843}
7844
7845/// ADR-057: registry-parameterized variant of
7846/// [`primitive_simplicial_nerve_betti`]. Walks `T::CONSTRAINTS` and expands
7847/// every `ConstraintRef::Recurse { shape_iri, descent_bound }` entry by
7848/// looking up `shape_iri` through `R`'s registry plus foundation's
7849/// built-in registry, decrementing the descent budget on each recursive
7850/// walk, and terminating when the budget reaches zero. The expanded
7851/// constraint sequence is the input to the nerve computation — the
7852/// structural reading at ψ_1 reflects the recursive grammar.
7853/// This is the entry point ψ_1 `NerveResolver` impls call from the
7854/// application's resolver-tuple — `R` is the ResolverTuple's
7855/// `ShapeRegistry` associated type per ADR-036+ADR-057.
7856/// # Errors
7857/// Returns `NERVE_CAPACITY_EXCEEDED` when the expanded constraint set
7858/// exceeds `NERVE_CONSTRAINTS_CAP` or `NERVE_SITES_CAP`. Returns
7859/// `RECURSE_SHAPE_UNREGISTERED` when a `Recurse` entry references an
7860/// IRI not present in either `R::REGISTRY` or foundation's built-in.
7861pub fn primitive_simplicial_nerve_betti_in<
7862    T: crate::pipeline::ConstrainedTypeShape + ?Sized,
7863    R: crate::pipeline::shape_iri_registry::ShapeRegistryProvider,
7864>() -> Result<[u32; MAX_BETTI_DIMENSION], GenericImpossibilityWitness> {
7865    // ADR-057 step 3: expand T::CONSTRAINTS, walking ConstraintRef::Recurse
7866    // through R's registry with bounded descent.
7867    let mut expanded: [crate::pipeline::ConstraintRef; NERVE_CONSTRAINTS_CAP] =
7868        [crate::pipeline::ConstraintRef::Site { position: 0 }; NERVE_CONSTRAINTS_CAP];
7869    let mut n_expanded: usize = 0;
7870    expand_constraints_in::<R>(T::CONSTRAINTS, u32::MAX, &mut expanded, &mut n_expanded)?;
7871    let n_constraints = n_expanded;
7872    if n_constraints > NERVE_CONSTRAINTS_CAP {
7873        return Err(GenericImpossibilityWitness::for_identity(
7874            "NERVE_CAPACITY_EXCEEDED",
7875        ));
7876    }
7877    let s_all = T::SITE_COUNT;
7878    if s_all > NERVE_SITES_CAP {
7879        return Err(GenericImpossibilityWitness::for_identity(
7880            "NERVE_CAPACITY_EXCEEDED",
7881        ));
7882    }
7883    let n_sites = s_all;
7884    let mut out = [0u32; MAX_BETTI_DIMENSION];
7885    if n_constraints == 0 {
7886        out[0] = 1;
7887        return Ok(out);
7888    }
7889    // Compute site-support bitmask per constraint (bit `s` set iff constraint touches site `s`).
7890    let mut support = [0u16; NERVE_CONSTRAINTS_CAP];
7891    let mut c = 0;
7892    while c < n_constraints {
7893        support[c] = constraint_site_support_mask_of(&expanded[c], n_sites);
7894        c += 1;
7895    }
7896    // Enumerate 1-simplices: pairs (i,j) with i<j and support[i] & support[j] != 0.
7897    // Index in c1_pairs_lo/hi corresponds to the column in ∂_1 / row in ∂_2.
7898    let mut c1_pairs_lo = [0u8; NERVE_C1_MAX];
7899    let mut c1_pairs_hi = [0u8; NERVE_C1_MAX];
7900    let mut n_c1: usize = 0;
7901    let mut i = 0;
7902    while i < n_constraints {
7903        let mut j = i + 1;
7904        while j < n_constraints {
7905            if (support[i] & support[j]) != 0 && n_c1 < NERVE_C1_MAX {
7906                c1_pairs_lo[n_c1] = i as u8;
7907                c1_pairs_hi[n_c1] = j as u8;
7908                n_c1 += 1;
7909            }
7910            j += 1;
7911        }
7912        i += 1;
7913    }
7914    // Enumerate 2-simplices: triples (i,j,k) with i<j<k and support[i] & support[j] & support[k] != 0.
7915    let mut c2_i = [0u8; NERVE_C2_MAX];
7916    let mut c2_j = [0u8; NERVE_C2_MAX];
7917    let mut c2_k = [0u8; NERVE_C2_MAX];
7918    let mut n_c2: usize = 0;
7919    let mut i2 = 0;
7920    while i2 < n_constraints {
7921        let mut j2 = i2 + 1;
7922        while j2 < n_constraints {
7923            let mut k2 = j2 + 1;
7924            while k2 < n_constraints {
7925                if (support[i2] & support[j2] & support[k2]) != 0 && n_c2 < NERVE_C2_MAX {
7926                    c2_i[n_c2] = i2 as u8;
7927                    c2_j[n_c2] = j2 as u8;
7928                    c2_k[n_c2] = k2 as u8;
7929                    n_c2 += 1;
7930                }
7931                k2 += 1;
7932            }
7933            j2 += 1;
7934        }
7935        i2 += 1;
7936    }
7937    // Build ∂_1: rows = n_constraints (vertices of the nerve), cols = n_c1.
7938    // Convention: ∂(c_i, c_j) = c_j - c_i for i < j.
7939    let mut partial_1 = [[0i64; NERVE_C1_MAX]; NERVE_CONSTRAINTS_CAP];
7940    let mut e = 0;
7941    while e < n_c1 {
7942        let lo = c1_pairs_lo[e] as usize;
7943        let hi = c1_pairs_hi[e] as usize;
7944        partial_1[lo][e] = NERVE_RANK_MOD_P - 1; // -1 mod p
7945        partial_1[hi][e] = 1;
7946        e += 1;
7947    }
7948    let rank_1 = integer_matrix_rank::<NERVE_CONSTRAINTS_CAP, NERVE_C1_MAX>(
7949        &mut partial_1,
7950        n_constraints,
7951        n_c1,
7952    );
7953    // Build ∂_2: rows = n_c1, cols = n_c2.
7954    // Convention: ∂(c_i, c_j, c_k) = (c_j, c_k) - (c_i, c_k) + (c_i, c_j).
7955    let mut partial_2 = [[0i64; NERVE_C2_MAX]; NERVE_C1_MAX];
7956    let mut t = 0;
7957    while t < n_c2 {
7958        let ti = c2_i[t];
7959        let tj = c2_j[t];
7960        let tk = c2_k[t];
7961        let idx_jk = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, tj, tk);
7962        let idx_ik = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, ti, tk);
7963        let idx_ij = find_pair_index(&c1_pairs_lo, &c1_pairs_hi, n_c1, ti, tj);
7964        if idx_jk < NERVE_C1_MAX {
7965            partial_2[idx_jk][t] = 1;
7966        }
7967        if idx_ik < NERVE_C1_MAX {
7968            partial_2[idx_ik][t] = NERVE_RANK_MOD_P - 1;
7969        }
7970        if idx_ij < NERVE_C1_MAX {
7971            partial_2[idx_ij][t] = 1;
7972        }
7973        t += 1;
7974    }
7975    let rank_2 = integer_matrix_rank::<NERVE_C1_MAX, NERVE_C2_MAX>(&mut partial_2, n_c1, n_c2);
7976    // b_0 = |C_0| - rank(∂_1). Always ≥ 1 because partial_1 has at least one all-zero row.
7977    let b0 = (n_constraints - rank_1) as u32;
7978    // b_1 = (|C_1| - rank(∂_1)) - rank(∂_2).
7979    let cycles_1 = n_c1.saturating_sub(rank_1);
7980    let b1 = cycles_1.saturating_sub(rank_2) as u32;
7981    // b_2 = |C_2| - rank(∂_2) (the complex is 2-dimensional; no ∂_3).
7982    let b2 = n_c2.saturating_sub(rank_2) as u32;
7983    out[0] = if b0 == 0 { 1 } else { b0 };
7984    if MAX_BETTI_DIMENSION > 1 {
7985        out[1] = b1;
7986    }
7987    if MAX_BETTI_DIMENSION > 2 {
7988        out[2] = b2;
7989    }
7990    Ok(out)
7991}
7992
7993/// ADR-057 step 3: walk `in_constraints`, copying non-Recurse entries into
7994/// `out_arr` and expanding every `ConstraintRef::Recurse { shape_iri,
7995/// descent_bound }` by looking up `shape_iri` through `R`'s registry plus
7996/// foundation's built-in registry and recursing into the referenced shape's
7997/// `CONSTRAINTS`. The effective descent budget at each Recurse is the min
7998/// of the caller's `descent_remaining` and the constraint's own
7999/// `descent_bound`; on Recurse the budget decrements by 1 before recursion.
8000/// A budget of 0 terminates the descent (the Recurse contributes no
8001/// further constraints — the recursion bottoms out).
8002/// # Errors
8003/// Returns `NERVE_CAPACITY_EXCEEDED` when the expansion would exceed
8004/// `NERVE_CONSTRAINTS_CAP`. Returns `RECURSE_SHAPE_UNREGISTERED` when a
8005/// `Recurse` entry with non-zero effective budget references an IRI not
8006/// present in either `R::REGISTRY` or foundation's built-in registry.
8007pub fn expand_constraints_in<R: crate::pipeline::shape_iri_registry::ShapeRegistryProvider>(
8008    in_constraints: &[crate::pipeline::ConstraintRef],
8009    descent_remaining: u32,
8010    out_arr: &mut [crate::pipeline::ConstraintRef; NERVE_CONSTRAINTS_CAP],
8011    out_n: &mut usize,
8012) -> Result<(), GenericImpossibilityWitness> {
8013    let mut i = 0;
8014    while i < in_constraints.len() {
8015        match in_constraints[i] {
8016            crate::pipeline::ConstraintRef::Recurse {
8017                shape_iri,
8018                descent_bound,
8019            } => {
8020                // Effective budget = min(caller's remaining, this Recurse's bound).
8021                let budget = if descent_remaining < descent_bound {
8022                    descent_remaining
8023                } else {
8024                    descent_bound
8025                };
8026                if budget == 0 {
8027                    // Bottom out — contribute no further constraints.
8028                } else {
8029                    match crate::pipeline::shape_iri_registry::lookup_shape_in::<R>(shape_iri) {
8030                        Some(registered) => {
8031                            expand_constraints_in::<R>(
8032                                registered.constraints,
8033                                budget - 1,
8034                                out_arr,
8035                                out_n,
8036                            )?;
8037                        }
8038                        None => {
8039                            return Err(GenericImpossibilityWitness::for_identity(
8040                                "RECURSE_SHAPE_UNREGISTERED",
8041                            ));
8042                        }
8043                    }
8044                }
8045            }
8046            other => {
8047                if *out_n >= NERVE_CONSTRAINTS_CAP {
8048                    return Err(GenericImpossibilityWitness::for_identity(
8049                        "NERVE_CAPACITY_EXCEEDED",
8050                    ));
8051                }
8052                out_arr[*out_n] = other;
8053                *out_n += 1;
8054            }
8055        }
8056        i += 1;
8057    }
8058    Ok(())
8059}
8060
8061/// Phase X.4: cap on the number of constraints considered by the nerve
8062/// primitive. Phase 1a (orphan-closure): inputs exceeding this cap are
8063/// rejected via `NERVE_CAPACITY_EXCEEDED` (was previously silent truncation).
8064/// Wiki ADR-037: a foundation-fixed conservative default for
8065/// [`crate::HostBounds::NERVE_CONSTRAINTS_MAX`].
8066pub const NERVE_CONSTRAINTS_CAP: usize = 8;
8067
8068/// Phase X.4: cap on site-support bitmask width (matches `u16` storage).
8069/// Phase 1a (orphan-closure): inputs exceeding this cap are rejected via
8070/// `NERVE_CAPACITY_EXCEEDED` (was previously silent truncation).
8071/// Wiki ADR-037: a foundation-fixed conservative default for
8072/// [`crate::HostBounds::NERVE_SITES_MAX`].
8073pub const NERVE_SITES_CAP: usize = 8;
8074
8075/// Phase X.4: maximum number of 1-simplices = C(NERVE_CONSTRAINTS_CAP, 2) = 28.
8076pub const NERVE_C1_MAX: usize = 28;
8077
8078/// Phase X.4: maximum number of 2-simplices = C(NERVE_CONSTRAINTS_CAP, 3) = 56.
8079pub const NERVE_C2_MAX: usize = 56;
8080
8081/// Phase X.4: prime modulus for nerve boundary-matrix rank computation.
8082/// Chosen so `(i64 * i64) mod p` never overflows (`p² < 2⁶³`). Nerve boundary
8083/// matrices have entries in {-1, 0, 1}; rank over ℤ/p equals rank over ℚ.
8084pub(crate) const NERVE_RANK_MOD_P: i64 = 1_000_000_007;
8085
8086/// Phase X.4: per-constraint site-support bitmask. Returns bit `s` set iff
8087/// constraint `c` touches site index `s` (`s < n_sites`).
8088/// `Affine { coefficients, .. }` returns the bitmask of sites whose
8089/// coefficient is non-zero — the natural "site support" of the affine
8090/// relation. Remaining non-site-local variants (Residue, Hamming, Depth,
8091/// Bound, Conjunction, SatClauses) return an all-ones mask over `n_sites`.
8092/// ADR-057: slice-based — operates directly on a `&ConstraintRef` rather
8093/// than indexing a `ConstrainedTypeShape::CONSTRAINTS` slot. ψ_1 calls this
8094/// from [`primitive_simplicial_nerve_betti_in`] after `T::CONSTRAINTS` has
8095/// been expanded into a fixed-size array via [`expand_constraints_in`].
8096pub(crate) const fn constraint_site_support_mask_of(
8097    c: &crate::pipeline::ConstraintRef,
8098    n_sites: usize,
8099) -> u16 {
8100    let all_mask: u16 = if n_sites == 0 {
8101        0
8102    } else {
8103        (1u16 << n_sites) - 1
8104    };
8105    match c {
8106        crate::pipeline::ConstraintRef::Site { position } => {
8107            if n_sites == 0 {
8108                0
8109            } else {
8110                1u16 << (*position as usize % n_sites)
8111            }
8112        }
8113        crate::pipeline::ConstraintRef::Carry { site } => {
8114            if n_sites == 0 {
8115                0
8116            } else {
8117                1u16 << (*site as usize % n_sites)
8118            }
8119        }
8120        crate::pipeline::ConstraintRef::Affine {
8121            coefficients,
8122            coefficient_count,
8123            ..
8124        } => {
8125            if n_sites == 0 {
8126                0
8127            } else {
8128                let mut mask: u16 = 0;
8129                let count = *coefficient_count as usize;
8130                let mut i = 0;
8131                while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS && i < n_sites {
8132                    if coefficients[i] != 0 {
8133                        mask |= 1u16 << i;
8134                    }
8135                    i += 1;
8136                }
8137                if mask == 0 {
8138                    all_mask
8139                } else {
8140                    mask
8141                }
8142            }
8143        }
8144        // ADR-057: any Recurse entry left in the array means
8145        // expand_constraints_in already bottomed out (descent_bound = 0).
8146        // Treat it as a structural placeholder with no specific site support.
8147        _ => all_mask,
8148    }
8149}
8150
8151/// Phase X.4: find the column index of the 1-simplex (lo, hi) in the enumerated
8152/// pair list. Returns `NERVE_C1_MAX` (sentinel = not found) when absent.
8153pub(crate) const fn find_pair_index(
8154    lo_arr: &[u8; NERVE_C1_MAX],
8155    hi_arr: &[u8; NERVE_C1_MAX],
8156    n_c1: usize,
8157    lo: u8,
8158    hi: u8,
8159) -> usize {
8160    let mut i = 0;
8161    while i < n_c1 {
8162        if lo_arr[i] == lo && hi_arr[i] == hi {
8163            return i;
8164        }
8165        i += 1;
8166    }
8167    NERVE_C1_MAX
8168}
8169
8170/// Phase X.4: rank of an integer matrix over ℤ/`NERVE_RANK_MOD_P` via modular
8171/// Gaussian elimination. Entries are reduced mod p and elimination uses
8172/// Fermat-inverse pivot normalization. For ±1/0 boundary matrices this
8173/// coincides with rank over ℤ.
8174pub(crate) const fn integer_matrix_rank<const R: usize, const C: usize>(
8175    matrix: &mut [[i64; C]; R],
8176    rows: usize,
8177    cols: usize,
8178) -> usize {
8179    let p = NERVE_RANK_MOD_P;
8180    // Reduce all entries into [0, p).
8181    let mut r = 0;
8182    while r < rows {
8183        let mut c = 0;
8184        while c < cols {
8185            let v = matrix[r][c] % p;
8186            matrix[r][c] = if v < 0 { v + p } else { v };
8187            c += 1;
8188        }
8189        r += 1;
8190    }
8191    let mut rank: usize = 0;
8192    let mut col: usize = 0;
8193    while col < cols && rank < rows {
8194        // Find a pivot row in column `col`, starting at `rank`.
8195        let mut pivot_row = rank;
8196        while pivot_row < rows && matrix[pivot_row][col] == 0 {
8197            pivot_row += 1;
8198        }
8199        if pivot_row == rows {
8200            col += 1;
8201            continue;
8202        }
8203        // Swap into position.
8204        if pivot_row != rank {
8205            let mut k = 0;
8206            while k < cols {
8207                let tmp = matrix[rank][k];
8208                matrix[rank][k] = matrix[pivot_row][k];
8209                matrix[pivot_row][k] = tmp;
8210                k += 1;
8211            }
8212        }
8213        // Normalize pivot row to have leading 1.
8214        let pivot = matrix[rank][col];
8215        let pivot_inv = mod_pow(pivot, p - 2, p);
8216        let mut k = 0;
8217        while k < cols {
8218            matrix[rank][k] = (matrix[rank][k] * pivot_inv) % p;
8219            k += 1;
8220        }
8221        // Eliminate the column entry from every other row.
8222        let mut r2 = 0;
8223        while r2 < rows {
8224            if r2 != rank {
8225                let factor = matrix[r2][col];
8226                if factor != 0 {
8227                    let mut kk = 0;
8228                    while kk < cols {
8229                        let sub = (matrix[rank][kk] * factor) % p;
8230                        let mut v = matrix[r2][kk] - sub;
8231                        v %= p;
8232                        if v < 0 {
8233                            v += p;
8234                        }
8235                        matrix[r2][kk] = v;
8236                        kk += 1;
8237                    }
8238                }
8239            }
8240            r2 += 1;
8241        }
8242        rank += 1;
8243        col += 1;
8244    }
8245    rank
8246}
8247
8248/// Phase X.4: modular exponentiation `base^exp mod p`, const-fn. Used by
8249/// `integer_matrix_rank` via Fermat's little theorem for modular inverses.
8250pub(crate) const fn mod_pow(base: i64, exp: i64, p: i64) -> i64 {
8251    let mut result: i64 = 1;
8252    let mut b = ((base % p) + p) % p;
8253    let mut e = exp;
8254    while e > 0 {
8255        if e & 1 == 1 {
8256            result = (result * b) % p;
8257        }
8258        b = (b * b) % p;
8259        e >>= 1;
8260    }
8261    result
8262}
8263
8264/// v0.2.2 Phase J: fold the Betti tuple into the hasher.
8265pub(crate) fn fold_betti_tuple<const FP_MAX: usize, H: Hasher<FP_MAX>>(
8266    mut hasher: H,
8267    betti: &[u32; MAX_BETTI_DIMENSION],
8268) -> H {
8269    let mut i = 0;
8270    while i < MAX_BETTI_DIMENSION {
8271        hasher = hasher.fold_bytes(&betti[i].to_be_bytes());
8272        i += 1;
8273    }
8274    hasher
8275}
8276
8277/// v0.2.2 Phase J: Euler characteristic `χ = Σ(-1)^k b_k` from the Betti tuple.
8278#[must_use]
8279pub(crate) fn primitive_euler_characteristic(betti: &[u32; MAX_BETTI_DIMENSION]) -> i64 {
8280    let mut chi: i64 = 0;
8281    let mut k = 0;
8282    while k < MAX_BETTI_DIMENSION {
8283        let term = betti[k] as i64;
8284        if k % 2 == 0 {
8285            chi += term;
8286        } else {
8287            chi -= term;
8288        }
8289        k += 1;
8290    }
8291    chi
8292}
8293
8294/// v0.2.2 Phase J primitive: `op:DihedralGroup` / `op:D_7`.
8295/// Returns `(orbit_size, representative)` under D_{2^n} acting on `T::SITE_COUNT`.
8296/// `orbit_size = 2n` when n ≥ 2, 2 when n == 1, 1 when n == 0 (group identity only).
8297/// `representative` is the lexicographically-minimal element of the orbit of
8298/// site 0 under D_{2n}: rotations `r^k → k mod n` and reflections `s·r^k → (n - k) mod n`.
8299/// For the orbit of site 0, both maps produce 0 as a group element, so the
8300/// representative is always 0; for a non-canonical starting index `i`, the
8301/// representative would be `min(i, (n - i) mod n)`. This helper uses site 0 as the
8302/// canonical starting point (the foundation's convention), so the representative
8303/// reflects the orbit's algebraic content, not a sentinel.
8304pub(crate) fn primitive_dihedral_signature<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8305) -> (u32, u32) {
8306    let n = T::SITE_COUNT as u32;
8307    let orbit_size = if n < 2 {
8308        if n == 0 {
8309            1
8310        } else {
8311            2
8312        }
8313    } else {
8314        2 * n
8315    };
8316    // v0.2.2 Phase S.2: compute the lexicographically-minimal orbit element.
8317    // Orbit of site 0 under D_{2n} contains: rotation images {0, 1, ..., n-1}
8318    // (since r^k maps 0 → k mod n) and reflection images {0, n-1, n-2, ..., 1}
8319    // (since s·r^k maps 0 → (n - k) mod n). The union is {0, 1, ..., n-1}.
8320    // The lex-min is 0 by construction; formalize it by min-walking the orbit.
8321    let mut rep: u32 = 0;
8322    let mut k = 1u32;
8323    while k < n {
8324        let rot = k % n;
8325        let refl = (n - k) % n;
8326        if rot < rep {
8327            rep = rot;
8328        }
8329        if refl < rep {
8330            rep = refl;
8331        }
8332        k += 1;
8333    }
8334    (orbit_size, rep)
8335}
8336
8337/// v0.2.2 Phase J: fold the dihedral `(orbit_size, representative)` pair.
8338pub(crate) fn fold_dihedral_signature<const FP_MAX: usize, H: Hasher<FP_MAX>>(
8339    mut hasher: H,
8340    orbit_size: u32,
8341    representative: u32,
8342) -> H {
8343    hasher = hasher.fold_bytes(&orbit_size.to_be_bytes());
8344    hasher = hasher.fold_bytes(&representative.to_be_bytes());
8345    hasher
8346}
8347
8348/// v0.2.2 Phase J primitive: `observable:Jacobian` / `op:DC_10`.
8349/// Content-deterministic per-site Jacobian profile: for each site `i`, the number
8350/// of constraints that mention site index `i` (derived from the constraint encoding).
8351/// Truncated / zero-padded to `JACOBIAN_MAX_SITES` entries to keep the fold fixed-size.
8352pub(crate) fn primitive_curvature_jacobian<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8353) -> [i32; JACOBIAN_MAX_SITES] {
8354    let mut out = [0i32; JACOBIAN_MAX_SITES];
8355    let mut ci = 0;
8356    while ci < T::CONSTRAINTS.len() {
8357        if let crate::pipeline::ConstraintRef::Site { position } = T::CONSTRAINTS[ci] {
8358            let idx = (position as usize) % JACOBIAN_MAX_SITES;
8359            out[idx] = out[idx].saturating_add(1);
8360        }
8361        ci += 1;
8362    }
8363    // Also account for residue and hamming constraints as contributing uniformly
8364    // across all sites (they are not site-local). Represented as +1 to site 0.
8365    let total = T::CONSTRAINTS.len() as i32;
8366    out[0] = out[0].saturating_add(total);
8367    out
8368}
8369
8370/// v0.2.2 Phase J: DC_10 selects the site with the maximum absolute Jacobian value.
8371#[must_use]
8372pub(crate) fn primitive_dc10_select(jac: &[i32; JACOBIAN_MAX_SITES]) -> usize {
8373    let mut best_idx: usize = 0;
8374    let mut best_abs: i32 = jac[0].unsigned_abs() as i32;
8375    let mut i = 1;
8376    while i < JACOBIAN_MAX_SITES {
8377        let a = jac[i].unsigned_abs() as i32;
8378        if a > best_abs {
8379            best_abs = a;
8380            best_idx = i;
8381        }
8382        i += 1;
8383    }
8384    best_idx
8385}
8386
8387/// v0.2.2 Phase J: fold the Jacobian profile into the hasher.
8388pub(crate) fn fold_jacobian_profile<const FP_MAX: usize, H: Hasher<FP_MAX>>(
8389    mut hasher: H,
8390    jac: &[i32; JACOBIAN_MAX_SITES],
8391) -> H {
8392    let mut i = 0;
8393    while i < JACOBIAN_MAX_SITES {
8394        hasher = hasher.fold_bytes(&jac[i].to_be_bytes());
8395        i += 1;
8396    }
8397    hasher
8398}
8399
8400/// v0.2.2 Phase J primitive: `state:BindingAccumulator` / `state:ContextLease`.
8401/// Returns `(binding_count, fold_address)` — a content-deterministic session signature.
8402/// v0.2.2 Phase S.4: uses an FNV-1a-style order-preserving incremental hash
8403/// (rotate-and-multiply) over each binding's `(name_index, type_index,
8404/// content_address)` tuple, rather than XOR-accumulation (which is commutative
8405/// and collides on reordered-but-otherwise-identical binding sets). Order-dependence
8406/// is intentional: `state:BindingAccumulator` semantics treat the insertion
8407/// sequence as part of the session signature.
8408pub(crate) fn primitive_session_binding_signature(bindings: &[Binding]) -> (u32, u64) {
8409    // FNV-1a-style incremental mix: start from the FNV offset basis,
8410    // multiply-then-XOR each limb. Order-dependent by construction.
8411    let mut fold: u64 = 0xcbf2_9ce4_8422_2325;
8412    const FNV_PRIME: u64 = 0x0000_0100_0000_01b3;
8413    let mut i = 0;
8414    while i < bindings.len() {
8415        let b = &bindings[i];
8416        // Mix in (name_index, type_index, content_address) per binding.
8417        fold = fold.wrapping_mul(FNV_PRIME);
8418        fold ^= b.name_index as u64;
8419        fold = fold.wrapping_mul(FNV_PRIME);
8420        fold ^= b.type_index as u64;
8421        fold = fold.wrapping_mul(FNV_PRIME);
8422        fold ^= b.content_address;
8423        i += 1;
8424    }
8425    (bindings.len() as u32, fold)
8426}
8427
8428/// v0.2.2 Phase J: fold the session-binding signature into the hasher.
8429pub(crate) fn fold_session_signature<const FP_MAX: usize, H: Hasher<FP_MAX>>(
8430    mut hasher: H,
8431    binding_count: u32,
8432    fold_address: u64,
8433) -> H {
8434    hasher = hasher.fold_bytes(&binding_count.to_be_bytes());
8435    hasher = hasher.fold_bytes(&fold_address.to_be_bytes());
8436    hasher
8437}
8438
8439/// v0.2.2 Phase J primitive: `op:QM_1` / `op:QM_5` / `resolver:collapseAmplitude`.
8440/// Seeds a two-state amplitude vector from the CompileUnit's thermodynamic budget,
8441/// computes Born-rule probabilities `P(0) = |α_0|²` and `P(1) = |α_1|²`,
8442/// verifies QM_5 normalization `Σ P = 1`, and returns `(outcome_index, probability)`
8443/// where `outcome_index` is the index of the larger amplitude and `probability` is its value.
8444/// QM_1 Landauer equality: `pre_entropy == post_cost` at β* = ln 2; since both
8445/// sides derive from the same budget the equality holds by construction.
8446/// v0.2.2 Phase S.3: amplitudes are sourced from two decorrelated projections
8447/// of the thermodynamic budget — the high 32 bits become the alpha-0
8448/// magnitude and the low 32 bits become the alpha-1 magnitude. This replaces
8449/// the earlier XOR-with-fixed-constants sourcing, preserving determinism while
8450/// ensuring both amplitudes derive from independent halves of the budget's
8451/// thermodynamic-entropy state. Born normalization and QM_1 Landauer equality
8452/// remain invariant under this sourcing change.
8453pub(crate) fn primitive_measurement_projection(budget: u64) -> (u64, u64) {
8454    // Decorrelated amplitude sourcing: high-32-bits drives alpha_0,
8455    // low-32-bits drives alpha_1. Distinct bit halves yield independent
8456    // magnitudes under any non-degenerate budget.
8457    let alpha0_bits: u32 = (budget >> 32) as u32;
8458    let alpha1_bits: u32 = (budget & 0xFFFF_FFFF) as u32;
8459    type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
8460    let a0 = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(alpha0_bits)
8461        / <DefaultDecimal as crate::DecimalTranscendental>::from_u32(u32::MAX);
8462    let a1 = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(alpha1_bits)
8463        / <DefaultDecimal as crate::DecimalTranscendental>::from_u32(u32::MAX);
8464    let norm = a0 * a0 + a1 * a1;
8465    let zero = <DefaultDecimal as Default>::default();
8466    let half =
8467        <DefaultDecimal as crate::DecimalTranscendental>::from_bits(0x3FE0_0000_0000_0000_u64);
8468    // QM_5 normalization: P(k) = |alpha_k|^2 / norm. Degenerate budget = 0
8469    // yields norm = 0; fall through to the uniform distribution (P(0) = 0.5,
8470    // P(1) = 0.5), which is the maximum-entropy projection under QM_1.
8471    let p0 = if norm > zero { (a0 * a0) / norm } else { half };
8472    let p1 = if norm > zero { (a1 * a1) / norm } else { half };
8473    if p0 >= p1 {
8474        (
8475            0,
8476            <DefaultDecimal as crate::DecimalTranscendental>::to_bits(p0),
8477        )
8478    } else {
8479        (
8480            1,
8481            <DefaultDecimal as crate::DecimalTranscendental>::to_bits(p1),
8482        )
8483    }
8484}
8485
8486/// v0.2.2 Phase J / Phase 9: fold the Born-rule outcome into the hasher.
8487/// `probability_bits` is the IEEE-754 bit pattern (call sites convert via
8488/// `<H::Decimal as DecimalTranscendental>::to_bits` if working in `H::Decimal`).
8489pub(crate) fn fold_born_outcome<const FP_MAX: usize, H: Hasher<FP_MAX>>(
8490    mut hasher: H,
8491    outcome_index: u64,
8492    probability_bits: u64,
8493) -> H {
8494    hasher = hasher.fold_bytes(&outcome_index.to_be_bytes());
8495    hasher = hasher.fold_bytes(&probability_bits.to_be_bytes());
8496    hasher
8497}
8498
8499/// v0.2.2 Phase J primitive: `recursion:DescentMeasure` / `observable:ResidualEntropy`.
8500/// Computes `(residual_count, entropy_bits)` from `T::SITE_COUNT` and the Euler char.
8501/// `residual_count = max(0, site_count - euler_char)` — free sites after constraint contraction.
8502/// `entropy = (residual_count) × ln 2` — Landauer-temperature entropy in nats.
8503/// Phase 9: returns `(residual_count, entropy_bits)` where `entropy_bits` is the
8504/// IEEE-754 bit pattern of `residual × ln 2`. Consumers project to `H::Decimal`
8505/// via `<H::Decimal as DecimalTranscendental>::from_bits`.
8506pub(crate) fn primitive_descent_metrics<T: crate::pipeline::ConstrainedTypeShape + ?Sized>(
8507    betti: &[u32; MAX_BETTI_DIMENSION],
8508) -> (u32, u64) {
8509    let chi = primitive_euler_characteristic(betti);
8510    let n = T::SITE_COUNT as i64;
8511    let residual = if n > chi { (n - chi) as u32 } else { 0u32 };
8512    type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
8513    let residual_d = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(residual);
8514    let ln_2 = <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
8515    let entropy = residual_d * ln_2;
8516    (
8517        residual,
8518        <DefaultDecimal as crate::DecimalTranscendental>::to_bits(entropy),
8519    )
8520}
8521
8522/// v0.2.2 Phase J / Phase 9: fold the descent metrics into the hasher.
8523/// `entropy_bits` is the IEEE-754 bit pattern of the descent entropy.
8524pub(crate) fn fold_descent_metrics<const FP_MAX: usize, H: Hasher<FP_MAX>>(
8525    mut hasher: H,
8526    residual_count: u32,
8527    entropy_bits: u64,
8528) -> H {
8529    hasher = hasher.fold_bytes(&residual_count.to_be_bytes());
8530    hasher = hasher.fold_bytes(&entropy_bits.to_be_bytes());
8531    hasher
8532}
8533
8534/// Phase X.2: upper bound on cohomology class dimension. Cup products
8535/// whose summed dimension exceeds this cap are rejected as
8536/// `CohomologyError::DimensionOverflow`.
8537pub const MAX_COHOMOLOGY_DIMENSION: u32 = 32;
8538
8539/// Phase X.2: a cohomology class `H^n(·)` at dimension `n` with a content
8540/// fingerprint of the underlying cochain representative. Parametric over
8541/// dimension via a runtime field because generic-const-expression arithmetic
8542/// over `N + M` is unstable at the crate's MSRV (Rust 1.81).
8543#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8544pub struct CohomologyClass<const FP_MAX: usize = 32> {
8545    dimension: u32,
8546    fingerprint: ContentFingerprint<FP_MAX>,
8547    _sealed: (),
8548}
8549
8550impl<const FP_MAX: usize> CohomologyClass<FP_MAX> {
8551    /// Phase X.2: crate-sealed constructor. Public callers go through
8552    /// `mint_cohomology_class` so that construction always routes through a
8553    /// validating hash of the cochain representative.
8554    #[inline]
8555    pub(crate) const fn with_dimension_and_fingerprint(
8556        dimension: u32,
8557        fingerprint: ContentFingerprint<FP_MAX>,
8558    ) -> Self {
8559        Self {
8560            dimension,
8561            fingerprint,
8562            _sealed: (),
8563        }
8564    }
8565
8566    /// The dimension `n` of this cohomology class `H^n(·)`.
8567    #[inline]
8568    #[must_use]
8569    pub const fn dimension(&self) -> u32 {
8570        self.dimension
8571    }
8572
8573    /// The content fingerprint of the underlying cochain representative.
8574    #[inline]
8575    #[must_use]
8576    pub const fn fingerprint(&self) -> ContentFingerprint<FP_MAX> {
8577        self.fingerprint
8578    }
8579
8580    /// Phase X.2: cup product `H^n × H^m → H^{n+m}`. The resulting class
8581    /// carries dimension `n + m` and a fingerprint folded from both
8582    /// operand dimensions and fingerprints via `fold_cup_product`. The
8583    /// fold is ordered (lhs-then-rhs) — graded-commutativity of the cup
8584    /// product at the algebraic level is not a fingerprint-level property.
8585    /// # Errors
8586    /// Returns `CohomologyError::DimensionOverflow` when `n + m >
8587    /// MAX_COHOMOLOGY_DIMENSION`.
8588    pub fn cup<H: Hasher<FP_MAX>>(
8589        self,
8590        other: CohomologyClass<FP_MAX>,
8591    ) -> Result<CohomologyClass<FP_MAX>, CohomologyError> {
8592        let sum = self.dimension.saturating_add(other.dimension);
8593        if sum > MAX_COHOMOLOGY_DIMENSION {
8594            return Err(CohomologyError::DimensionOverflow {
8595                lhs: self.dimension,
8596                rhs: other.dimension,
8597            });
8598        }
8599        let hasher = H::initial();
8600        let hasher = fold_cup_product(
8601            hasher,
8602            self.dimension,
8603            &self.fingerprint,
8604            other.dimension,
8605            &other.fingerprint,
8606        );
8607        let buf = hasher.finalize();
8608        let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8609        Ok(Self::with_dimension_and_fingerprint(sum, fp))
8610    }
8611}
8612
8613/// Phase X.2: error returned by `CohomologyClass::cup` when the summed
8614/// dimension exceeds `MAX_COHOMOLOGY_DIMENSION`.
8615#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8616pub enum CohomologyError {
8617    /// Cup product would exceed `MAX_COHOMOLOGY_DIMENSION`.
8618    DimensionOverflow { lhs: u32, rhs: u32 },
8619}
8620
8621impl core::fmt::Display for CohomologyError {
8622    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8623        match self {
8624            Self::DimensionOverflow { lhs, rhs } => write!(
8625                f,
8626                "cup product dimension overflow: {lhs} + {rhs} > MAX_COHOMOLOGY_DIMENSION ({})",
8627                MAX_COHOMOLOGY_DIMENSION
8628            ),
8629        }
8630    }
8631}
8632impl core::error::Error for CohomologyError {}
8633
8634/// Phase X.2: homology class dual to `CohomologyClass`. A homology class
8635/// `H_n(·)` at dimension `n` with a content fingerprint of its chain
8636/// representative. Shares the dimension-as-runtime-field discipline.
8637#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8638pub struct HomologyClass<const FP_MAX: usize = 32> {
8639    dimension: u32,
8640    fingerprint: ContentFingerprint<FP_MAX>,
8641    _sealed: (),
8642}
8643
8644impl<const FP_MAX: usize> HomologyClass<FP_MAX> {
8645    /// Phase X.2: crate-sealed constructor. Public callers go through
8646    /// `mint_homology_class`.
8647    #[inline]
8648    pub(crate) const fn with_dimension_and_fingerprint(
8649        dimension: u32,
8650        fingerprint: ContentFingerprint<FP_MAX>,
8651    ) -> Self {
8652        Self {
8653            dimension,
8654            fingerprint,
8655            _sealed: (),
8656        }
8657    }
8658
8659    /// The dimension `n` of this homology class `H_n(·)`.
8660    #[inline]
8661    #[must_use]
8662    pub const fn dimension(&self) -> u32 {
8663        self.dimension
8664    }
8665
8666    /// The content fingerprint of the underlying chain representative.
8667    #[inline]
8668    #[must_use]
8669    pub const fn fingerprint(&self) -> ContentFingerprint<FP_MAX> {
8670        self.fingerprint
8671    }
8672}
8673
8674/// Phase X.2: fold the cup-product operand pair into the hasher. Ordered
8675/// (lhs dimension + fingerprint, then rhs dimension + fingerprint).
8676pub fn fold_cup_product<const FP_MAX: usize, H: Hasher<FP_MAX>>(
8677    mut hasher: H,
8678    lhs_dim: u32,
8679    lhs_fp: &ContentFingerprint<FP_MAX>,
8680    rhs_dim: u32,
8681    rhs_fp: &ContentFingerprint<FP_MAX>,
8682) -> H {
8683    hasher = hasher.fold_bytes(&lhs_dim.to_be_bytes());
8684    hasher = hasher.fold_bytes(lhs_fp.as_bytes());
8685    hasher = hasher.fold_bytes(&rhs_dim.to_be_bytes());
8686    hasher = hasher.fold_bytes(rhs_fp.as_bytes());
8687    hasher
8688}
8689
8690/// Phase X.2: mint a `CohomologyClass` from a cochain representative `seed`.
8691/// Hashes `seed` through `H` to produce the class fingerprint. The caller's
8692/// choice of `H` determines the fingerprint width.
8693/// # Errors
8694/// Returns `CohomologyError::DimensionOverflow` when `dimension >
8695/// MAX_COHOMOLOGY_DIMENSION`.
8696pub fn mint_cohomology_class<H: Hasher<FP_MAX>, const FP_MAX: usize>(
8697    dimension: u32,
8698    seed: &[u8],
8699) -> Result<CohomologyClass<FP_MAX>, CohomologyError> {
8700    if dimension > MAX_COHOMOLOGY_DIMENSION {
8701        return Err(CohomologyError::DimensionOverflow {
8702            lhs: dimension,
8703            rhs: 0,
8704        });
8705    }
8706    let mut hasher = H::initial();
8707    hasher = hasher.fold_bytes(&dimension.to_be_bytes());
8708    hasher = hasher.fold_bytes(seed);
8709    let buf = hasher.finalize();
8710    let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8711    Ok(CohomologyClass::with_dimension_and_fingerprint(
8712        dimension, fp,
8713    ))
8714}
8715
8716/// Phase X.2: mint a `HomologyClass` from a chain representative `seed`.
8717/// Hashes `seed` through `H` to produce the class fingerprint.
8718/// # Errors
8719/// Returns `CohomologyError::DimensionOverflow` when `dimension >
8720/// MAX_COHOMOLOGY_DIMENSION`.
8721pub fn mint_homology_class<H: Hasher<FP_MAX>, const FP_MAX: usize>(
8722    dimension: u32,
8723    seed: &[u8],
8724) -> Result<HomologyClass<FP_MAX>, CohomologyError> {
8725    if dimension > MAX_COHOMOLOGY_DIMENSION {
8726        return Err(CohomologyError::DimensionOverflow {
8727            lhs: dimension,
8728            rhs: 0,
8729        });
8730    }
8731    let mut hasher = H::initial();
8732    hasher = hasher.fold_bytes(&dimension.to_be_bytes());
8733    hasher = hasher.fold_bytes(seed);
8734    let buf = hasher.finalize();
8735    let fp = ContentFingerprint::from_buffer(buf, H::OUTPUT_BYTES as u8);
8736    Ok(HomologyClass::with_dimension_and_fingerprint(dimension, fp))
8737}
8738
8739/// v0.2.2 T6.1: per-step canonical byte layout for `StreamDriver::next()`.
8740/// Layout: `productivity_remaining (8 BE) || rewrite_steps (8 BE) || seed (8 BE) ||
8741/// iri bytes || 0x00 || certificate_kind_discriminant (1 byte trailing)`.
8742pub fn fold_stream_step_digest<const FP_MAX: usize, H: Hasher<FP_MAX>>(
8743    mut hasher: H,
8744    productivity_remaining: u64,
8745    rewrite_steps: u64,
8746    seed: u64,
8747    iri: &str,
8748    kind: CertificateKind,
8749) -> H {
8750    hasher = hasher.fold_bytes(&productivity_remaining.to_be_bytes());
8751    hasher = hasher.fold_bytes(&rewrite_steps.to_be_bytes());
8752    hasher = hasher.fold_bytes(&seed.to_be_bytes());
8753    hasher = hasher.fold_bytes(iri.as_bytes());
8754    hasher = hasher.fold_byte(0);
8755    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
8756    hasher
8757}
8758
8759/// v0.2.2 T6.1: per-step canonical byte layout for `InteractionDriver::step()`
8760/// and `InteractionDriver::finalize()`.
8761/// Layout: `commutator_acc[0..4] (4 × 8 BE bytes) || peer_step_count (8 BE) ||
8762/// seed (8 BE) || iri bytes || 0x00 || certificate_kind_discriminant (1 byte trailing)`.
8763pub fn fold_interaction_step_digest<const FP_MAX: usize, H: Hasher<FP_MAX>>(
8764    mut hasher: H,
8765    commutator_acc: &[u64; 4],
8766    peer_step_count: u64,
8767    seed: u64,
8768    iri: &str,
8769    kind: CertificateKind,
8770) -> H {
8771    let mut i = 0;
8772    while i < 4 {
8773        hasher = hasher.fold_bytes(&commutator_acc[i].to_be_bytes());
8774        i += 1;
8775    }
8776    hasher = hasher.fold_bytes(&peer_step_count.to_be_bytes());
8777    hasher = hasher.fold_bytes(&seed.to_be_bytes());
8778    hasher = hasher.fold_bytes(iri.as_bytes());
8779    hasher = hasher.fold_byte(0);
8780    hasher = hasher.fold_byte(certificate_kind_discriminant(kind));
8781    hasher
8782}
8783
8784/// Utility — extract the leading 16 bytes of a `Hasher::finalize` buffer
8785/// as a `ContentAddress`. Used by pipeline entry points to derive the
8786/// 16-byte unit_address handle from a freshly-computed substrate
8787/// fingerprint, so two units with distinct fingerprints have distinct
8788/// unit_address handles too.
8789/// Per the wiki's ADR-018 the `FP_MAX` const-generic carries the
8790/// application's selected `<B as HostBounds>::FINGERPRINT_MAX_BYTES`.
8791/// `FP_MAX` MUST be at least 16; smaller buffers cannot supply the
8792/// 16-byte address prefix.
8793#[inline]
8794#[must_use]
8795pub const fn unit_address_from_buffer<const FP_MAX: usize>(
8796    buffer: &[u8; FP_MAX],
8797) -> ContentAddress {
8798    let mut bytes = [0u8; 16];
8799    let mut i = 0;
8800    while i < 16 {
8801        bytes[i] = buffer[i];
8802        i += 1;
8803    }
8804    ContentAddress::from_u128(u128::from_be_bytes(bytes))
8805}
8806
8807/// v0.2.2 T6.11: const-fn equality on `&str` slices. `str::eq` is not
8808/// stable in const eval under MSRV 1.81; this helper provides a
8809/// byte-by-byte equality check for use in `pipeline::run`'s ShapeMismatch
8810/// detection without runtime allocation.
8811#[inline]
8812#[must_use]
8813pub const fn str_eq(a: &str, b: &str) -> bool {
8814    let a = a.as_bytes();
8815    let b = b.as_bytes();
8816    if a.len() != b.len() {
8817        return false;
8818    }
8819    let mut i = 0;
8820    while i < a.len() {
8821        if a[i] != b[i] {
8822            return false;
8823        }
8824        i += 1;
8825    }
8826    true
8827}
8828
8829/// A binding entry in a `BindingsTable`. Pairs a `ContentAddress`
8830/// (hash of the query coordinate) with the bound bytes.
8831#[derive(Debug, Clone, Copy)]
8832pub struct BindingEntry {
8833    /// Content-hashed query address.
8834    pub address: ContentAddress,
8835    /// Bound payload bytes (length determined by the WittLevel of the table).
8836    pub bytes: &'static [u8],
8837}
8838
8839/// A static, sorted-by-address binding table laid out for `op:GS_5` zero-step
8840/// access. Looked up via binary search; the foundation guarantees the table
8841/// is materialized at compile time from the attested `state:GroundedContext`.
8842#[derive(Debug, Clone, Copy)]
8843pub struct BindingsTable {
8844    /// Entries, sorted ascending by `address`.
8845    pub entries: &'static [BindingEntry],
8846}
8847
8848impl BindingsTable {
8849    /// v0.2.2 T5 C4: validating constructor. Checks that `entries` are
8850    /// strictly ascending by `address`, which is the invariant
8851    /// `Grounded::get_binding` relies on for its binary-search lookup.
8852    /// # Errors
8853    /// Returns `BindingsTableError::Unsorted { at }` where `at` is the first
8854    /// index where the order is violated (i.e., `entries[at].address <=
8855    /// entries[at - 1].address`).
8856    pub const fn try_new(entries: &'static [BindingEntry]) -> Result<Self, BindingsTableError> {
8857        let mut i = 1;
8858        while i < entries.len() {
8859            if entries[i].address.as_u128() <= entries[i - 1].address.as_u128() {
8860                return Err(BindingsTableError::Unsorted { at: i });
8861            }
8862            i += 1;
8863        }
8864        Ok(Self { entries })
8865    }
8866}
8867
8868/// v0.2.2 T5 C4: errors returned by `BindingsTable::try_new`.
8869#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8870#[non_exhaustive]
8871pub enum BindingsTableError {
8872    /// Entries at index `at` and `at - 1` are out of order (the slice is
8873    /// not strictly ascending by `address`).
8874    Unsorted {
8875        /// The first index where the order is violated.
8876        at: usize,
8877    },
8878}
8879
8880impl core::fmt::Display for BindingsTableError {
8881    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8882        match self {
8883            Self::Unsorted { at } => write!(
8884                f,
8885                "BindingsTable entries not sorted: address at index {at} <= address at index {}",
8886                at - 1,
8887            ),
8888        }
8889    }
8890}
8891
8892impl core::error::Error for BindingsTableError {}
8893
8894/// The compile-time witness that `op:GS_4` holds for the value it carries:
8895/// σ = 1, freeRank = 0, S = 0, T_ctx = 0. `Grounded<T, Tag>` is constructed
8896/// only by the reduction pipeline and provides `op:GS_5` zero-step binding access.
8897/// v0.2.2 Phase B (Q3): the `Tag` phantom parameter (default `Tag = T`)
8898/// lets downstream code attach a domain marker to a grounded witness without
8899/// any new sealing — e.g., `Grounded<ConstrainedTypeInput, BlockHashTag>` is
8900/// a distinct Rust type from `Grounded<ConstrainedTypeInput, PixelTag>`. The
8901/// inner witness is unchanged; the tag is pure decoration. The foundation
8902/// guarantees ring soundness on the inner witness; the tag is the developer's
8903/// domain claim. Coerce via `Grounded::tag::<NewTag>()` (zero-cost).
8904///
8905/// # Wiki ADR-039 — Inhabitance verdict realization mapping
8906///
8907/// For typed feature hierarchies whose admission relations are
8908/// inhabitance questions, a successful `Grounded<Output>` IS a
8909/// `cert:InhabitanceCertificate` envelope:
8910///
8911/// - The κ-label (homotopy-classification structural witness at ψ_9
8912///   per ADR-035) is the `Term::KInvariants` emission's bytes, exposed
8913///   via [`Grounded::output_bytes`].
8914/// - The concrete `cert:witness` ValueTuple is derivable from
8915///   `Term::Nerve`'s 0-simplices at ψ_1 (the per-value bytes the model's
8916///   NerveResolver consumed).
8917/// - The `cert:searchTrace` is realized as
8918///   [`Grounded::derivation`]`().replay()`.
8919///
8920/// The κ-label and `cert:witness` are different witness granularities
8921/// (homotopy classification vs. concrete ValueTuple); the canonical
8922/// k-invariants branch ψ_1 → ψ_7 → ψ_8 → ψ_9 produces both, at the
8923/// ψ_9 and ψ_1 stages respectively. Ontology references:
8924/// `<https://uor.foundation/cert/InhabitanceCertificate>`,
8925/// `<https://uor.foundation/cert/witness>`,
8926/// `<https://uor.foundation/cert/searchTrace>`.
8927#[derive(Debug, Clone)]
8928pub struct Grounded<
8929    'a,
8930    T: GroundedShape,
8931    const INLINE_BYTES: usize,
8932    const FP_MAX: usize = 32,
8933    Tag = T,
8934> {
8935    /// The validated grounding certificate this wrapper carries.
8936    validated: Validated<GroundingCertificate<FP_MAX>>,
8937    /// The compile-time-materialized bindings table.
8938    bindings: BindingsTable,
8939    /// The Witt level the grounded value was minted at.
8940    witt_level_bits: u16,
8941    /// Content-address of the originating CompileUnit.
8942    unit_address: ContentAddress,
8943    /// Phase A.1: the foundation-internal two-clock value read at witness mint time.
8944    /// Computed deterministically from (witt_level_bits, unit_address, bindings).
8945    uor_time: UorTime,
8946    /// v0.2.2 T2.6 (cleanup): BaseMetric storage — populated by the
8947    /// pipeline at mint time as a deterministic function of witt level,
8948    /// unit address, and bindings. All six fields are read-only from
8949    /// the accessors; downstream cannot mutate them.
8950    /// Grounding completion ratio σ × 10⁶ (parts per million).
8951    sigma_ppm: u32,
8952    /// Metric incompatibility d_Δ.
8953    d_delta: i64,
8954    /// Euler characteristic of the constraint nerve.
8955    euler_characteristic: i64,
8956    /// Free-site count at grounding time.
8957    residual_count: u32,
8958    /// Per-site Jacobian row (fixed capacity, zero-padded).
8959    jacobian_entries: [i64; JACOBIAN_MAX_SITES],
8960    /// Active length of jacobian_entries.
8961    jacobian_len: u16,
8962    /// Betti numbers β_0..β_{MAX_BETTI_DIMENSION-1}.
8963    betti_numbers: [u32; MAX_BETTI_DIMENSION],
8964    /// v0.2.2 T5: parametric content fingerprint of the source unit's
8965    /// full state, computed at grounding time by the consumer-supplied
8966    /// `Hasher`. Width is `ContentFingerprint::width_bytes()`, set by
8967    /// `H::OUTPUT_BYTES` at the call site. Read by `Grounded::derivation()`
8968    /// so the verify path can re-derive the source certificate. The buffer
8969    /// width `FP_MAX` is the application's `<B as HostBounds>::FINGERPRINT_MAX_BYTES`
8970    /// (threaded, not pinned) — any `Hasher<FP_MAX>` width flows.
8971    content_fingerprint: ContentFingerprint<FP_MAX>,
8972    /// Wiki ADR-028 (amended by ADR-060): output-value payload — the
8973    /// catamorphism's evaluation result populated by `pipeline::run_route`
8974    /// per ADR-029's per-variant fold rules, carried as a source-polymorphic
8975    /// [`crate::pipeline::TermValue`] (Inline κ-label for content-addressing
8976    /// routes; Borrowed/Stream for structural/unbounded outputs). There is no
8977    /// fixed output buffer and no output byte-width ceiling. The lifetime
8978    /// `'a` is the borrowed-input-data lifetime a Borrowed/Stream output
8979    /// propagates from the route input. Read via [`Grounded::output_bytes`]
8980    /// (contiguous) or [`Grounded::output_value`] (the carrier).
8981    output: crate::pipeline::TermValue<'a, INLINE_BYTES>,
8982    /// Phantom type tying this `Grounded` to a specific `ConstrainedType`.
8983    _phantom: PhantomData<T>,
8984    /// Phantom domain tag (Q3). Defaults to `T` for backwards-compatible
8985    /// call sites; downstream attaches a custom tag via `tag::<NewTag>()`.
8986    _tag: PhantomData<Tag>,
8987}
8988
8989impl<'a, T: GroundedShape, const INLINE_BYTES: usize, const FP_MAX: usize, Tag>
8990    Grounded<'a, T, INLINE_BYTES, FP_MAX, Tag>
8991{
8992    /// Returns the binding for the given query address, or `None` if not in
8993    /// the table. Resolves in O(log n) via binary search; for true `op:GS_5`
8994    /// zero-step access, downstream code uses statically-known indices.
8995    #[inline]
8996    #[must_use]
8997    pub fn get_binding(&self, address: ContentAddress) -> Option<&'static [u8]> {
8998        self.bindings
8999            .entries
9000            .binary_search_by_key(&address.as_u128(), |e| e.address.as_u128())
9001            .ok()
9002            .map(|i| self.bindings.entries[i].bytes)
9003    }
9004
9005    /// Iterate over all bindings in this grounded context.
9006    #[inline]
9007    pub fn iter_bindings(&self) -> impl Iterator<Item = &BindingEntry> + '_ {
9008        self.bindings.entries.iter()
9009    }
9010
9011    /// Returns the Witt level the grounded value was minted at.
9012    #[inline]
9013    #[must_use]
9014    pub const fn witt_level_bits(&self) -> u16 {
9015        self.witt_level_bits
9016    }
9017
9018    /// Returns the content-address of the originating CompileUnit.
9019    #[inline]
9020    #[must_use]
9021    pub const fn unit_address(&self) -> ContentAddress {
9022        self.unit_address
9023    }
9024
9025    /// Returns the validated grounding certificate this wrapper carries.
9026    #[inline]
9027    #[must_use]
9028    pub const fn certificate(&self) -> &Validated<GroundingCertificate<FP_MAX>> {
9029        &self.validated
9030    }
9031
9032    /// Phase A.4: `observable:d_delta_metric` — sealed metric incompatibility between
9033    /// ring distance and Hamming distance for this datum's neighborhood.
9034    #[inline]
9035    #[must_use]
9036    pub const fn d_delta(&self) -> DDeltaMetric {
9037        DDeltaMetric::new(self.d_delta)
9038    }
9039
9040    /// Phase A.4: `observable:sigma_metric` — sealed grounding completion ratio.
9041    #[inline]
9042    #[must_use]
9043    pub fn sigma(&self) -> SigmaValue<crate::DefaultHostTypes> {
9044        // Default-host (f64) projection; polymorphic consumers
9045        // can re-encode via DecimalTranscendental::from_u32 + Div.
9046        let value = <f64 as crate::DecimalTranscendental>::from_u32(self.sigma_ppm)
9047            / <f64 as crate::DecimalTranscendental>::from_u32(1_000_000);
9048        SigmaValue::<crate::DefaultHostTypes>::new_unchecked(value)
9049    }
9050
9051    /// Phase A.4: `observable:jacobian_metric` — sealed per-site Jacobian row.
9052    #[inline]
9053    #[must_use]
9054    pub fn jacobian(&self) -> JacobianMetric<T> {
9055        JacobianMetric::from_entries(self.jacobian_entries, self.jacobian_len)
9056    }
9057
9058    /// Phase A.4: `observable:betti_metric` — sealed Betti-number vector.
9059    #[inline]
9060    #[must_use]
9061    pub const fn betti(&self) -> BettiMetric {
9062        BettiMetric::new(self.betti_numbers)
9063    }
9064
9065    /// Phase A.4: `observable:euler_metric` — sealed Euler characteristic χ of
9066    /// the constraint nerve.
9067    #[inline]
9068    #[must_use]
9069    pub const fn euler(&self) -> EulerMetric {
9070        EulerMetric::new(self.euler_characteristic)
9071    }
9072
9073    /// Phase A.4: `observable:residual_metric` — sealed free-site count r at grounding.
9074    #[inline]
9075    #[must_use]
9076    pub const fn residual(&self) -> ResidualMetric {
9077        ResidualMetric::new(self.residual_count)
9078    }
9079
9080    /// v0.2.2 T5: returns the parametric content fingerprint of the source
9081    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
9082    /// Width is set by `H::OUTPUT_BYTES` at the call site. Used by
9083    /// `derivation()` to seed the replayed Trace's fingerprint, which
9084    /// `verify_trace` then passes through to the re-derived certificate.
9085    #[inline]
9086    #[must_use]
9087    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
9088        self.content_fingerprint
9089    }
9090
9091    /// v0.2.2 T5 (C2): returns the `Derivation` that produced this grounded
9092    /// value. Use the returned `Derivation` with `Derivation::replay()` and
9093    /// then `uor_foundation_verify::verify_trace` to re-derive the source
9094    /// certificate without re-running the deciders.
9095    /// The round-trip property:
9096    /// ```text
9097    /// verify_trace(&grounded.derivation().replay()).certificate()
9098    ///     == grounded.certificate()
9099    /// ```
9100    /// holds for every conforming substrate `Hasher`.
9101    #[inline]
9102    #[must_use]
9103    pub const fn derivation(&self) -> Derivation<FP_MAX> {
9104        Derivation::new(
9105            (self.jacobian_len as u32) + 1,
9106            self.witt_level_bits,
9107            self.content_fingerprint,
9108        )
9109    }
9110
9111    /// v0.2.2 Phase B (Q3): coerce this `Grounded<T, Tag>` to a different
9112    /// phantom tag. Zero-cost — the inner witness is unchanged; only the
9113    /// type-system view differs. Downstream uses this to attach a domain
9114    /// marker for use in function signatures (e.g., `Grounded<_, BlockHashTag>`
9115    /// vs `Grounded<_, PixelTag>` are distinct Rust types).
9116    /// **The foundation does not validate the tag.** The tag records what
9117    /// the developer is claiming about the witness's domain semantics; the
9118    /// foundation's contract is about ring soundness, not domain semantics.
9119    #[inline]
9120    #[must_use]
9121    pub fn tag<NewTag>(self) -> Grounded<'a, T, INLINE_BYTES, FP_MAX, NewTag> {
9122        Grounded {
9123            validated: self.validated,
9124            bindings: self.bindings,
9125            witt_level_bits: self.witt_level_bits,
9126            unit_address: self.unit_address,
9127            uor_time: self.uor_time,
9128            sigma_ppm: self.sigma_ppm,
9129            d_delta: self.d_delta,
9130            euler_characteristic: self.euler_characteristic,
9131            residual_count: self.residual_count,
9132            jacobian_entries: self.jacobian_entries,
9133            jacobian_len: self.jacobian_len,
9134            betti_numbers: self.betti_numbers,
9135            content_fingerprint: self.content_fingerprint,
9136            output: self.output,
9137            _phantom: PhantomData,
9138            _tag: PhantomData,
9139        }
9140    }
9141
9142    /// Wiki ADR-028: returns the catamorphism's evaluation output bytes — the
9143    /// active prefix of the on-stack output payload `pipeline::run_route`
9144    /// populated per ADR-029's per-variant fold rules.
9145    /// For the foundation-sanctioned identity output (`ConstrainedTypeInput`)
9146    /// the slice is empty (no transformation, identity route). For shapes
9147    /// declared via the `output_shape!` SDK macro the slice carries the
9148    /// route's evaluation result.
9149    #[inline]
9150    #[must_use]
9151    pub fn output_bytes(&self) -> &[u8] {
9152        // Inline/Borrowed carriers expose their contiguous bytes; a Stream
9153        // carrier has no contiguous slice (read it via `output_value()` +
9154        // `TermValue::for_each_chunk`).
9155        self.output.bytes()
9156    }
9157
9158    /// Wiki ADR-028 (amended by ADR-060): returns the output as the
9159    /// source-polymorphic [`crate::pipeline::TermValue`] carrier. Use this
9160    /// (rather than [`Grounded::output_bytes`]) when the route's output may
9161    /// be a `Stream` (unbounded) or `Borrowed` carrier — fold it via
9162    /// [`crate::pipeline::TermValue::for_each_chunk`] for arbitrary sizes.
9163    #[inline]
9164    #[must_use]
9165    pub fn output_value(&self) -> crate::pipeline::TermValue<'a, INLINE_BYTES> {
9166        self.output
9167    }
9168
9169    /// Phase A.1: the foundation-internal two-clock value read at witness mint time.
9170    /// Maps `rewrite_steps` to `derivation:stepCount` and `landauer_nats` to
9171    /// `observable:LandauerCost`. The value is content-deterministic: two `Grounded`
9172    /// witnesses minted from the same inputs share the same `UorTime`.
9173    /// Compose with a `Calibration` via [`UorTime::min_wall_clock`] to
9174    /// bound the provable minimum wall-clock duration the computation required.
9175    #[inline]
9176    #[must_use]
9177    pub const fn uor_time(&self) -> UorTime {
9178        self.uor_time
9179    }
9180
9181    /// Phase A.2: the sealed triadic coordinate `(stratum, spectrum, address)` at the
9182    /// witness's Witt level, projected from the content-addressed unit.
9183    /// `stratum` is the v₂ valuation of the lower unit-address half; `spectrum`
9184    /// is the lower 64 bits of the unit address; `address` is the upper 64 bits.
9185    /// The projection is deterministic and content-addressed, so replay reproduces the
9186    /// same `Triad` bit-for-bit.
9187    #[inline]
9188    #[must_use]
9189    pub const fn triad(&self) -> Triad<T> {
9190        let addr = self.unit_address.as_u128();
9191        let addr_lo = addr as u64;
9192        let addr_hi = (addr >> 64) as u64;
9193        let stratum = if addr_lo == 0 {
9194            0u64
9195        } else {
9196            addr_lo.trailing_zeros() as u64
9197        };
9198        Triad::new(stratum, addr_lo, addr_hi)
9199    }
9200
9201    /// Crate-internal constructor used by the pipeline at mint time.
9202    /// Not callable from outside `uor-foundation`. The tag defaults to `T`
9203    /// (the unparameterized form); downstream attaches a custom tag via `tag()`.
9204    /// v0.2.2 T2.6 (cleanup): BaseMetric fields are computed here from
9205    /// the input witt level, bindings, and unit address. Two `Grounded`
9206    /// values built from the same inputs return identical metrics; two
9207    /// built from different inputs differ in at least three fields.
9208    #[inline]
9209    #[allow(dead_code)]
9210    pub(crate) const fn new_internal(
9211        validated: Validated<GroundingCertificate<FP_MAX>>,
9212        bindings: BindingsTable,
9213        witt_level_bits: u16,
9214        unit_address: ContentAddress,
9215        content_fingerprint: ContentFingerprint<FP_MAX>,
9216    ) -> Self {
9217        let bound_count = bindings.entries.len() as u32;
9218        let declared_sites = if witt_level_bits == 0 {
9219            1u32
9220        } else {
9221            witt_level_bits as u32
9222        };
9223        // sigma = bound / declared, in parts per million.
9224        let sigma_ppm = if bound_count >= declared_sites {
9225            1_000_000u32
9226        } else {
9227            // Integer division, rounded down, cannot exceed 1_000_000.
9228            let num = (bound_count as u64) * 1_000_000u64;
9229            (num / (declared_sites as u64)) as u32
9230        };
9231        // residual_count = declared - bound (saturating).
9232        let residual_count = declared_sites.saturating_sub(bound_count);
9233        // d_delta = witt_bits - bound_count (signed).
9234        let d_delta = (witt_level_bits as i64) - (bound_count as i64);
9235        // Betti numbers: β_0 = 1 (connected); β_k = bit k of witt_level_bits.
9236        let mut betti = [0u32; MAX_BETTI_DIMENSION];
9237        betti[0] = 1;
9238        let mut k = 1usize;
9239        while k < MAX_BETTI_DIMENSION {
9240            betti[k] = ((witt_level_bits as u32) >> (k - 1)) & 1;
9241            k += 1;
9242        }
9243        // Euler characteristic: alternating sum of Betti numbers.
9244        let mut euler: i64 = 0;
9245        let mut k = 0usize;
9246        while k < MAX_BETTI_DIMENSION {
9247            if k & 1 == 0 {
9248                euler += betti[k] as i64;
9249            } else {
9250                euler -= betti[k] as i64;
9251            }
9252            k += 1;
9253        }
9254        // Jacobian row: entry i = (unit_address.as_u128() as i64 XOR (i as i64)) mod witt+1.
9255        let mut jac = [0i64; JACOBIAN_MAX_SITES];
9256        let modulus = (witt_level_bits as i64) + 1;
9257        let ua_lo = unit_address.as_u128() as i64;
9258        let mut i = 0usize;
9259        let jac_len = if (witt_level_bits as usize) < JACOBIAN_MAX_SITES {
9260            witt_level_bits as usize
9261        } else {
9262            JACOBIAN_MAX_SITES
9263        };
9264        while i < jac_len {
9265            let raw = ua_lo ^ (i as i64);
9266            // Rust's % is remainder; ensure non-negative.
9267            let m = if modulus == 0 { 1 } else { modulus };
9268            jac[i] = ((raw % m) + m) % m;
9269            i += 1;
9270        }
9271        // Phase A.1: uor_time is content-deterministic. rewrite_steps counts
9272        // the reduction work proxied by (witt bits + bound count + active jac len);
9273        // Landauer nats = rewrite_steps × ln 2 (Landauer-temperature cost of
9274        // traversing that many orthogonal states). Two Grounded values minted from
9275        // the same inputs share the same UorTime.
9276        let steps = (witt_level_bits as u64) + (bound_count as u64) + (jac_len as u64);
9277        let landauer = LandauerBudget::new((steps as f64) * core::f64::consts::LN_2);
9278        let uor_time = UorTime::new(landauer, steps);
9279        Self {
9280            validated,
9281            bindings,
9282            witt_level_bits,
9283            unit_address,
9284            uor_time,
9285            sigma_ppm,
9286            d_delta,
9287            euler_characteristic: euler,
9288            residual_count,
9289            jacobian_entries: jac,
9290            jacobian_len: jac_len as u16,
9291            betti_numbers: betti,
9292            content_fingerprint,
9293            output: crate::pipeline::TermValue::empty(),
9294            _phantom: PhantomData,
9295            _tag: PhantomData,
9296        }
9297    }
9298
9299    /// Wiki ADR-028 (amended by ADR-060): crate-internal setter for the
9300    /// source-polymorphic output-value carrier.
9301    /// Called by `pipeline::run_route` after the catamorphism evaluates the
9302    /// Term tree per ADR-029. The carrier is stored by move — no copy, no
9303    /// byte-width ceiling: an `Inline` κ-label, a `Borrowed` slice into the
9304    /// route's `'a`-lived input, or a `Stream` of arbitrary size. Returns
9305    /// self for chaining.
9306    #[inline]
9307    #[must_use]
9308    pub(crate) fn with_output(
9309        mut self,
9310        output: crate::pipeline::TermValue<'a, INLINE_BYTES>,
9311    ) -> Self {
9312        self.output = output;
9313        self
9314    }
9315
9316    /// v0.2.2 T6.17: attach a downstream-validated `BindingsTable` to this
9317    /// grounded value. The original `Grounded` was minted by the foundation
9318    /// pipeline with a substrate-computed certificate; this builder lets
9319    /// downstream attach its own binding table without re-grounding.
9320    /// The `bindings` parameter must satisfy the sortedness invariant. Use
9321    /// [`BindingsTable::try_new`] to construct a validated table from a
9322    /// pre-sorted slice.
9323    /// **Trust boundary:** the certificate witnesses the unit's grounding,
9324    /// not the bindings' contents. A downstream consumer that uses the
9325    /// certificate as a trust root for the bindings is wrong.
9326    #[inline]
9327    #[must_use]
9328    pub fn with_bindings(self, bindings: BindingsTable) -> Self {
9329        Self { bindings, ..self }
9330    }
9331
9332    /// Wiki ADR-042: borrow `self` as an
9333    /// [`crate::pipeline::InhabitanceCertificateView`] over the canonical
9334    /// k-invariants branch's verdict envelope.
9335    /// Universal — available for any `Grounded<T, Tag>`; applications whose
9336    /// admission relations are not inhabitance questions simply don't
9337    /// call the typed accessors. The view is zero-cost
9338    /// (`#[repr(transparent)]` over `&'a Grounded<T, Tag>`).
9339    #[inline]
9340    #[must_use]
9341    pub fn as_inhabitance_certificate(
9342        &self,
9343    ) -> crate::pipeline::InhabitanceCertificateView<'_, T, INLINE_BYTES, FP_MAX, Tag> {
9344        crate::pipeline::InhabitanceCertificateView(self)
9345    }
9346}
9347
9348/// v0.2.2 W8: triadic coordinate of a Datum at level `L`. Bundles the
9349/// (stratum, spectrum, address) projection in one structurally-enforced
9350/// type. No public constructor — `Triad<L>` is built only by foundation code
9351/// at grounding time. Field access goes through the named accessors.
9352#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9353pub struct Triad<L> {
9354    /// The stratum coordinate (two-adic valuation).
9355    stratum: u64,
9356    /// The spectrum coordinate (Walsh-Hadamard image).
9357    spectrum: u64,
9358    /// The address coordinate (Braille-glyph address).
9359    address: u64,
9360    /// Phantom marker for the Witt level.
9361    _level: PhantomData<L>,
9362}
9363
9364impl<L> Triad<L> {
9365    /// Returns the stratum component (`query:TwoAdicValuation` coordinate).
9366    #[inline]
9367    #[must_use]
9368    pub const fn stratum(&self) -> u64 {
9369        self.stratum
9370    }
9371
9372    /// Returns the spectrum component (`query:WalshHadamardImage` coordinate).
9373    #[inline]
9374    #[must_use]
9375    pub const fn spectrum(&self) -> u64 {
9376        self.spectrum
9377    }
9378
9379    /// Returns the address component (`query:Address` coordinate).
9380    #[inline]
9381    #[must_use]
9382    pub const fn address(&self) -> u64 {
9383        self.address
9384    }
9385
9386    /// Crate-internal constructor. Reachable only from grounding-time minting.
9387    #[inline]
9388    #[must_use]
9389    #[allow(dead_code)]
9390    pub(crate) const fn new(stratum: u64, spectrum: u64, address: u64) -> Self {
9391        Self {
9392            stratum,
9393            spectrum,
9394            address,
9395            _level: PhantomData,
9396        }
9397    }
9398}
9399
9400/// The Rust-surface rendering of `reduction:PipelineFailureReason` and the
9401/// v0.2.1 cross-namespace failure variants. Variant set and field shapes are
9402/// generated parametrically by walking `reduction:FailureField` individuals;
9403/// adding a new field requires only an ontology edit.
9404///
9405/// # Wiki ADR-039 — Inhabitance verdict realization mapping
9406///
9407/// An `Err(PipelineFailure)` whose structural cause is "the constraint
9408/// nerve has empty Kan completion" realizes a `cert:InhabitanceImpossibilityCertificate`
9409/// envelope, carrying `proof:InhabitanceImpossibilityWitness` as the
9410/// proof payload with `proof:contradictionProof` as the canonical-form
9411/// encoding of the failure trace. The verdict mapping is the dual of
9412/// the `Grounded<Output>` → `cert:InhabitanceCertificate` mapping; the
9413/// two together realize the ontology's three-primitive inhabitance
9414/// verdict structure (success / impossibility-witnessed / unknown).
9415/// Ontology references:
9416/// `<https://uor.foundation/cert/InhabitanceImpossibilityCertificate>`,
9417/// `<https://uor.foundation/proof/InhabitanceImpossibilityWitness>`,
9418/// `<https://uor.foundation/proof/contradictionProof>`.
9419#[derive(Debug, Clone, PartialEq)]
9420#[non_exhaustive]
9421pub enum PipelineFailure {
9422    /// `DispatchMiss` failure variant.
9423    DispatchMiss {
9424        /// query_iri field.
9425        query_iri: &'static str,
9426        /// table_iri field.
9427        table_iri: &'static str,
9428    },
9429    /// `GroundingFailure` failure variant.
9430    GroundingFailure {
9431        /// reason_iri field.
9432        reason_iri: &'static str,
9433    },
9434    /// `ConvergenceStall` failure variant.
9435    ConvergenceStall {
9436        /// stage_iri field.
9437        stage_iri: &'static str,
9438        /// angle_milliradians field.
9439        angle_milliradians: i64,
9440    },
9441    /// `ContradictionDetected` failure variant.
9442    ContradictionDetected {
9443        /// at_step field.
9444        at_step: usize,
9445        /// trace_iri field.
9446        trace_iri: &'static str,
9447    },
9448    /// `CoherenceViolation` failure variant.
9449    CoherenceViolation {
9450        /// site_position field.
9451        site_position: usize,
9452        /// constraint_iri field.
9453        constraint_iri: &'static str,
9454    },
9455    /// `ShapeMismatch` failure variant.
9456    ShapeMismatch {
9457        /// expected field.
9458        expected: &'static str,
9459        /// got field.
9460        got: &'static str,
9461    },
9462    /// `LiftObstructionFailure` failure variant.
9463    LiftObstructionFailure {
9464        /// site_position field.
9465        site_position: usize,
9466        /// obstruction_class_iri field.
9467        obstruction_class_iri: &'static str,
9468    },
9469    /// `ShapeViolation` failure variant.
9470    ShapeViolation {
9471        /// report field.
9472        report: ShapeViolation,
9473    },
9474}
9475
9476impl core::fmt::Display for PipelineFailure {
9477    fn fmt(&self, ff: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9478        match self {
9479            Self::DispatchMiss {
9480                query_iri,
9481                table_iri,
9482            } => write!(
9483                ff,
9484                "DispatchMiss(query_iri={:?}, table_iri={:?})",
9485                query_iri, table_iri
9486            ),
9487            Self::GroundingFailure { reason_iri } => {
9488                write!(ff, "GroundingFailure(reason_iri={:?})", reason_iri)
9489            }
9490            Self::ConvergenceStall {
9491                stage_iri,
9492                angle_milliradians,
9493            } => write!(
9494                ff,
9495                "ConvergenceStall(stage_iri={:?}, angle_milliradians={:?})",
9496                stage_iri, angle_milliradians
9497            ),
9498            Self::ContradictionDetected { at_step, trace_iri } => write!(
9499                ff,
9500                "ContradictionDetected(at_step={:?}, trace_iri={:?})",
9501                at_step, trace_iri
9502            ),
9503            Self::CoherenceViolation {
9504                site_position,
9505                constraint_iri,
9506            } => write!(
9507                ff,
9508                "CoherenceViolation(site_position={:?}, constraint_iri={:?})",
9509                site_position, constraint_iri
9510            ),
9511            Self::ShapeMismatch { expected, got } => {
9512                write!(ff, "ShapeMismatch(expected={:?}, got={:?})", expected, got)
9513            }
9514            Self::LiftObstructionFailure {
9515                site_position,
9516                obstruction_class_iri,
9517            } => write!(
9518                ff,
9519                "LiftObstructionFailure(site_position={:?}, obstruction_class_iri={:?})",
9520                site_position, obstruction_class_iri
9521            ),
9522            Self::ShapeViolation { report } => write!(ff, "ShapeViolation({:?})", report),
9523        }
9524    }
9525}
9526
9527impl core::error::Error for PipelineFailure {}
9528
9529/// Sealed marker for impossibility witnesses returned by the resolver
9530/// free-function path. Every failure return value of every
9531/// `resolver::<name>::certify(...)` call is a member of this set.
9532pub trait ImpossibilityWitnessKind: impossibility_witness_kind_sealed::Sealed {}
9533
9534mod impossibility_witness_kind_sealed {
9535    /// Private supertrait.
9536    pub trait Sealed {}
9537    impl Sealed for super::GenericImpossibilityWitness {}
9538    impl Sealed for super::InhabitanceImpossibilityWitness {}
9539}
9540
9541impl ImpossibilityWitnessKind for GenericImpossibilityWitness {}
9542impl ImpossibilityWitnessKind for InhabitanceImpossibilityWitness {}
9543
9544/// v0.2.2 W12: resolver free functions. Replaces the v0.2.1 unit-struct
9545/// façades with module-per-resolver free functions returning the W11
9546/// `Certified<C>` parametric carrier.
9547pub mod resolver {
9548    use super::{
9549        BornRuleVerification,
9550        Certified,
9551        CompileUnit,
9552        CompletenessCertificate,
9553        GenericImpossibilityWitness,
9554        GeodesicCertificate,
9555        GroundingCertificate,
9556        InhabitanceCertificate,
9557        InhabitanceImpossibilityWitness,
9558        InvolutionCertificate,
9559        IsometryCertificate,
9560        LiftChainCertificate,
9561        MeasurementCertificate,
9562        // Phase X.1: per-resolver cert discrimination.
9563        TransformCertificate,
9564        Validated,
9565        WittLevel,
9566    };
9567
9568    /// v0.2.2 W12: certify tower-completeness for a constrained type.
9569    ///
9570    /// Replaces `TowerCompletenessResolver::new().certify(input)` from v0.2.1.
9571    /// Delegates to `crate::pipeline::run_tower_completeness` and wraps the
9572    /// returned `LiftChainCertificate` in the W11 `Certified<_>` carrier.
9573    ///
9574    /// # Errors
9575    ///
9576    /// Returns `GenericImpossibilityWitness` when no certificate can be issued.
9577    pub mod tower_completeness {
9578        use super::*;
9579        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9580        ///
9581        /// # Errors
9582        ///
9583        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9584        pub fn certify<T, P, H, const FP_MAX: usize>(
9585            input: &Validated<T, P>,
9586        ) -> Result<Certified<LiftChainCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9587        where
9588            T: crate::pipeline::ConstrainedTypeShape,
9589            P: crate::enforcement::ValidationPhase,
9590            H: crate::enforcement::Hasher<FP_MAX>,
9591        {
9592            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
9593        }
9594
9595        /// Certify at an explicit Witt level.
9596        ///
9597        /// # Errors
9598        ///
9599        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9600        pub fn certify_at<T, P, H, const FP_MAX: usize>(
9601            input: &Validated<T, P>,
9602            level: WittLevel,
9603        ) -> Result<Certified<LiftChainCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9604        where
9605            T: crate::pipeline::ConstrainedTypeShape,
9606            P: crate::enforcement::ValidationPhase,
9607            H: crate::enforcement::Hasher<FP_MAX>,
9608        {
9609            crate::pipeline::run_tower_completeness::<T, H, FP_MAX>(input.inner(), level)
9610                .map(|v| Certified::new(*v.inner()))
9611                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9612        }
9613    }
9614
9615    /// v0.2.2 closure: certify incremental completeness for a constrained type.
9616    pub mod incremental_completeness {
9617        use super::*;
9618        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9619        ///
9620        /// # Errors
9621        ///
9622        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9623        pub fn certify<T, P, H, const FP_MAX: usize>(
9624            input: &Validated<T, P>,
9625        ) -> Result<Certified<LiftChainCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9626        where
9627            T: crate::pipeline::ConstrainedTypeShape,
9628            P: crate::enforcement::ValidationPhase,
9629            H: crate::enforcement::Hasher<FP_MAX>,
9630        {
9631            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
9632        }
9633
9634        /// Certify at an explicit Witt level.
9635        ///
9636        /// # Errors
9637        ///
9638        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9639        pub fn certify_at<T, P, H, const FP_MAX: usize>(
9640            input: &Validated<T, P>,
9641            level: WittLevel,
9642        ) -> Result<Certified<LiftChainCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9643        where
9644            T: crate::pipeline::ConstrainedTypeShape,
9645            P: crate::enforcement::ValidationPhase,
9646            H: crate::enforcement::Hasher<FP_MAX>,
9647        {
9648            crate::pipeline::run_incremental_completeness::<T, H, FP_MAX>(input.inner(), level)
9649                .map(|v| Certified::new(*v.inner()))
9650                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9651        }
9652    }
9653
9654    /// v0.2.2 closure: certify grounding-aware reduction for a CompileUnit.
9655    pub mod grounding_aware {
9656        use super::*;
9657        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9658        ///
9659        /// # Errors
9660        ///
9661        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9662        pub fn certify<P, H, const INLINE_BYTES: usize, const FP_MAX: usize>(
9663            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
9664        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9665        where
9666            P: crate::enforcement::ValidationPhase,
9667            H: crate::enforcement::Hasher<FP_MAX>,
9668        {
9669            certify_at::<P, H, INLINE_BYTES, FP_MAX>(input, WittLevel::W32)
9670        }
9671
9672        /// Certify at an explicit Witt level.
9673        ///
9674        /// # Errors
9675        ///
9676        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9677        pub fn certify_at<P, H, const INLINE_BYTES: usize, const FP_MAX: usize>(
9678            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
9679            level: WittLevel,
9680        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9681        where
9682            P: crate::enforcement::ValidationPhase,
9683            H: crate::enforcement::Hasher<FP_MAX>,
9684        {
9685            crate::pipeline::run_grounding_aware::<INLINE_BYTES, H, FP_MAX>(input.inner(), level)
9686                .map(|v| Certified::new(*v.inner()))
9687                .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))
9688        }
9689    }
9690
9691    /// v0.2.2 closure: certify inhabitance for a constrained type.
9692    pub mod inhabitance {
9693        use super::*;
9694        /// v0.2.2 closure (target §4.2): parameterized over phase + hasher.
9695        ///
9696        /// # Errors
9697        ///
9698        /// Returns `Certified<InhabitanceImpossibilityWitness>` on failure.
9699        pub fn certify<T, P, H, const FP_MAX: usize>(
9700            input: &Validated<T, P>,
9701        ) -> Result<
9702            Certified<InhabitanceCertificate<FP_MAX>>,
9703            Certified<InhabitanceImpossibilityWitness>,
9704        >
9705        where
9706            T: crate::pipeline::ConstrainedTypeShape,
9707            P: crate::enforcement::ValidationPhase,
9708            H: crate::enforcement::Hasher<FP_MAX>,
9709        {
9710            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
9711        }
9712
9713        /// Certify at an explicit Witt level.
9714        ///
9715        /// # Errors
9716        ///
9717        /// Returns `Certified<InhabitanceImpossibilityWitness>` on failure.
9718        pub fn certify_at<T, P, H, const FP_MAX: usize>(
9719            input: &Validated<T, P>,
9720            level: WittLevel,
9721        ) -> Result<
9722            Certified<InhabitanceCertificate<FP_MAX>>,
9723            Certified<InhabitanceImpossibilityWitness>,
9724        >
9725        where
9726            T: crate::pipeline::ConstrainedTypeShape,
9727            P: crate::enforcement::ValidationPhase,
9728            H: crate::enforcement::Hasher<FP_MAX>,
9729        {
9730            crate::pipeline::run_inhabitance::<T, H, FP_MAX>(input.inner(), level)
9731                .map(|v: Validated<InhabitanceCertificate<FP_MAX>>| Certified::new(*v.inner()))
9732                .map_err(|_| Certified::new(InhabitanceImpossibilityWitness::default()))
9733        }
9734    }
9735
9736    /// v0.2.2 Phase C.4: multiplication resolver — picks the cost-optimal
9737    /// Toom-Cook splitting factor R for a `Datum<L>` × `Datum<L>`
9738    /// multiplication at a given call-site context. The cost function is
9739    /// closed-form and grounded in `op:OA_5`:
9740    ///
9741    /// ```text
9742    /// sub_mul_count(N, R) = (2R - 1)  for R > 1
9743    ///                     = 1         for R = 1 (schoolbook)
9744    /// landauer_cost(N, R) = sub_mul_count(N, R) · (N/R)² · 64 · ln 2  nats
9745    /// ```
9746    pub mod multiplication {
9747        use super::super::{MulContext, MultiplicationCertificate};
9748        use super::*;
9749
9750        /// v0.2.2 T6.7: parameterized over `H: Hasher`. Pick the cost-optimal
9751        /// splitting factor R for a multiplication at the given call-site
9752        /// context and return a `Certified<MultiplicationCertificate>`
9753        /// recording the choice. The certificate carries a substrate-computed
9754        /// content fingerprint.
9755        ///
9756        /// # Errors
9757        ///
9758        /// Returns `GenericImpossibilityWitness` if the call-site context is
9759        /// inadmissible (`stack_budget_bytes == 0`). The resolver is otherwise
9760        /// total over admissible inputs.
9761        pub fn certify<H: crate::enforcement::Hasher<FP_MAX>, const FP_MAX: usize>(
9762            context: &MulContext,
9763        ) -> Result<Certified<MultiplicationCertificate<FP_MAX>>, GenericImpossibilityWitness>
9764        {
9765            if context.stack_budget_bytes == 0 {
9766                return Err(GenericImpossibilityWitness::default());
9767            }
9768            // Closed-form cost search: R = 1 (schoolbook) vs R = 2 (Karatsuba).
9769            let limb_count = context.limb_count.max(1);
9770            let karatsuba_stack_need = limb_count * 8 * 6;
9771            let choose_karatsuba = !context.const_eval
9772                && (context.stack_budget_bytes as usize) >= karatsuba_stack_need;
9773            // v0.2.2 T6.7: compute substrate fingerprint over the MulContext.
9774            let mut hasher = H::initial();
9775            hasher = hasher.fold_bytes(&context.stack_budget_bytes.to_be_bytes());
9776            hasher = hasher.fold_byte(if context.const_eval { 1 } else { 0 });
9777            hasher = hasher.fold_bytes(&(limb_count as u64).to_be_bytes());
9778            hasher = hasher.fold_byte(crate::enforcement::certificate_kind_discriminant(
9779                crate::enforcement::CertificateKind::Multiplication,
9780            ));
9781            let buffer = hasher.finalize();
9782            let fp =
9783                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9784            let cert = if choose_karatsuba {
9785                MultiplicationCertificate::with_evidence(
9786                    2,
9787                    3,
9788                    karatsuba_landauer_cost(limb_count),
9789                    fp,
9790                )
9791            } else {
9792                MultiplicationCertificate::with_evidence(
9793                    1,
9794                    1,
9795                    schoolbook_landauer_cost(limb_count),
9796                    fp,
9797                )
9798            };
9799            Ok(Certified::new(cert))
9800        }
9801
9802        // Local default-host alias for the Landauer cost helpers below.
9803        type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
9804
9805        /// Schoolbook Landauer cost in nats for an N-limb multiplication:
9806        /// `N² · 64 · ln 2`. Returns the IEEE-754 bit pattern;
9807        /// see `MultiplicationEvidence::landauer_cost_nats_bits`.
9808        fn schoolbook_landauer_cost(limb_count: usize) -> u64 {
9809            let n = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(limb_count as u32);
9810            let sixty_four = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(64);
9811            let ln_2 =
9812                <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
9813            (n * n * sixty_four * ln_2).to_bits()
9814        }
9815
9816        /// Karatsuba Landauer cost: `3 · (N/2)² · 64 · ln 2`.
9817        /// Returns the IEEE-754 bit pattern.
9818        fn karatsuba_landauer_cost(limb_count: usize) -> u64 {
9819            let n = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(limb_count as u32);
9820            let two = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(2);
9821            let three = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(3);
9822            let sixty_four = <DefaultDecimal as crate::DecimalTranscendental>::from_u32(64);
9823            let ln_2 =
9824                <DefaultDecimal as crate::DecimalTranscendental>::from_bits(crate::LN_2_BITS);
9825            let n_half = n / two;
9826            (three * n_half * n_half * sixty_four * ln_2).to_bits()
9827        }
9828    }
9829
9830    /// v0.2.2 Phase C: `pub(crate)` trait parameterizing the 15 Phase D resolver kernels.
9831    /// Each kernel marker supplies a `CertificateKind` discriminant and its
9832    /// ontology-declared certificate type via `type Cert`. The shared
9833    /// `certify_at` bodies (see `emit_phase_d_ct_body` / `emit_phase_d_cu_body`)
9834    /// mint `Certified<Kernel::Cert>` directly — so each resolver's cert class
9835    /// matches its `resolver:CertifyMapping` in the ontology.
9836    pub(crate) trait ResolverKernel {
9837        const KIND: crate::enforcement::CertificateKind;
9838        /// Phase X.1: the ontology-declared certificate class produced by
9839        /// this resolver (per `resolver:CertifyMapping`).
9840        ///
9841        /// ADR-018/060: parameterized over the application's fingerprint
9842        /// width `FP_MAX` (GAT, stable since Rust 1.65) so a resolver minting
9843        /// through an arbitrary-width `Hasher` carries the matching width.
9844        type Cert<const FP_MAX: usize>: crate::enforcement::Certificate;
9845    }
9846
9847    /// 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.
9848    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9849    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9850    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9851    /// failure — the witness itself is certified so downstream can persist it
9852    /// alongside success certs in a uniform `Certified<_>` channel.
9853    /// Phase X.1: the produced cert class is the ontology-declared class for
9854    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9855    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9856    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9857    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9858    /// kernels so each resolver's class discrimination is load-bearing.
9859    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9860    /// kernel's composition spec) whose output is folded into the canonical
9861    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9862    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9863    /// content-addressed per its ontology class.
9864    pub mod two_sat_decider {
9865        use super::*;
9866
9867        #[doc(hidden)]
9868        pub struct Kernel;
9869        impl super::ResolverKernel for Kernel {
9870            type Cert<const FP_MAX: usize> = crate::enforcement::GroundingCertificate<FP_MAX>;
9871            const KIND: crate::enforcement::CertificateKind =
9872                crate::enforcement::CertificateKind::TwoSat;
9873        }
9874
9875        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9876        ///
9877        /// # Errors
9878        ///
9879        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9880        pub fn certify<
9881            T: crate::pipeline::ConstrainedTypeShape,
9882            P: crate::enforcement::ValidationPhase,
9883            H: crate::enforcement::Hasher<FP_MAX>,
9884            const FP_MAX: usize,
9885        >(
9886            input: &Validated<T, P>,
9887        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9888        {
9889            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
9890        }
9891
9892        /// Phase D (target §4.2): certify at an explicit Witt level.
9893        ///
9894        /// # Errors
9895        ///
9896        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9897        pub fn certify_at<
9898            T: crate::pipeline::ConstrainedTypeShape,
9899            P: crate::enforcement::ValidationPhase,
9900            H: crate::enforcement::Hasher<FP_MAX>,
9901            const FP_MAX: usize,
9902        >(
9903            input: &Validated<T, P>,
9904            level: WittLevel,
9905        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9906        {
9907            let _ = input.inner();
9908            let witt_bits = level.witt_length() as u16;
9909            let (tr_bits, tr_constraints, tr_sat) =
9910                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
9911                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
9912            if tr_sat == 0 {
9913                return Err(Certified::new(GenericImpossibilityWitness::default()));
9914            }
9915            let mut hasher = H::initial();
9916            hasher = crate::enforcement::fold_terminal_reduction(
9917                hasher,
9918                tr_bits,
9919                tr_constraints,
9920                tr_sat,
9921            );
9922            hasher = crate::enforcement::fold_unit_digest(
9923                hasher,
9924                witt_bits,
9925                witt_bits as u64,
9926                T::IRI,
9927                T::SITE_COUNT,
9928                T::CONSTRAINTS,
9929                <Kernel as super::ResolverKernel>::KIND,
9930            );
9931            let buffer = hasher.finalize();
9932            let fp =
9933                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
9934            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
9935            Ok(Certified::new(cert))
9936        }
9937    }
9938
9939    /// Phase D (target §4.2): `resolver:HornSatDecider` — certify that `predicate:IsHornShape` inputs are Horn-SAT-decidable via unit propagation (O(n+m)).
9940    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
9941    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
9942    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
9943    /// failure — the witness itself is certified so downstream can persist it
9944    /// alongside success certs in a uniform `Certified<_>` channel.
9945    /// Phase X.1: the produced cert class is the ontology-declared class for
9946    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
9947    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
9948    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
9949    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
9950    /// kernels so each resolver's class discrimination is load-bearing.
9951    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
9952    /// kernel's composition spec) whose output is folded into the canonical
9953    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
9954    /// yield distinct fingerprints — i.e., each kernel's decision is real and
9955    /// content-addressed per its ontology class.
9956    pub mod horn_sat_decider {
9957        use super::*;
9958
9959        #[doc(hidden)]
9960        pub struct Kernel;
9961        impl super::ResolverKernel for Kernel {
9962            type Cert<const FP_MAX: usize> = crate::enforcement::GroundingCertificate<FP_MAX>;
9963            const KIND: crate::enforcement::CertificateKind =
9964                crate::enforcement::CertificateKind::HornSat;
9965        }
9966
9967        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
9968        ///
9969        /// # Errors
9970        ///
9971        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9972        pub fn certify<
9973            T: crate::pipeline::ConstrainedTypeShape,
9974            P: crate::enforcement::ValidationPhase,
9975            H: crate::enforcement::Hasher<FP_MAX>,
9976            const FP_MAX: usize,
9977        >(
9978            input: &Validated<T, P>,
9979        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9980        {
9981            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
9982        }
9983
9984        /// Phase D (target §4.2): certify at an explicit Witt level.
9985        ///
9986        /// # Errors
9987        ///
9988        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
9989        pub fn certify_at<
9990            T: crate::pipeline::ConstrainedTypeShape,
9991            P: crate::enforcement::ValidationPhase,
9992            H: crate::enforcement::Hasher<FP_MAX>,
9993            const FP_MAX: usize,
9994        >(
9995            input: &Validated<T, P>,
9996            level: WittLevel,
9997        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
9998        {
9999            let _ = input.inner();
10000            let witt_bits = level.witt_length() as u16;
10001            let (tr_bits, tr_constraints, tr_sat) =
10002                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10003                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10004            if tr_sat == 0 {
10005                return Err(Certified::new(GenericImpossibilityWitness::default()));
10006            }
10007            let mut hasher = H::initial();
10008            hasher = crate::enforcement::fold_terminal_reduction(
10009                hasher,
10010                tr_bits,
10011                tr_constraints,
10012                tr_sat,
10013            );
10014            hasher = crate::enforcement::fold_unit_digest(
10015                hasher,
10016                witt_bits,
10017                witt_bits as u64,
10018                T::IRI,
10019                T::SITE_COUNT,
10020                T::CONSTRAINTS,
10021                <Kernel as super::ResolverKernel>::KIND,
10022            );
10023            let buffer = hasher.finalize();
10024            let fp =
10025                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10026            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10027            Ok(Certified::new(cert))
10028        }
10029    }
10030
10031    /// 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).
10032    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10033    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10034    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10035    /// failure — the witness itself is certified so downstream can persist it
10036    /// alongside success certs in a uniform `Certified<_>` channel.
10037    /// Phase X.1: the produced cert class is the ontology-declared class for
10038    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10039    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10040    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10041    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10042    /// kernels so each resolver's class discrimination is load-bearing.
10043    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10044    /// kernel's composition spec) whose output is folded into the canonical
10045    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10046    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10047    /// content-addressed per its ontology class.
10048    pub mod residual_verdict {
10049        use super::*;
10050
10051        #[doc(hidden)]
10052        pub struct Kernel;
10053        impl super::ResolverKernel for Kernel {
10054            type Cert<const FP_MAX: usize> = crate::enforcement::GroundingCertificate<FP_MAX>;
10055            const KIND: crate::enforcement::CertificateKind =
10056                crate::enforcement::CertificateKind::ResidualVerdict;
10057        }
10058
10059        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10060        ///
10061        /// # Errors
10062        ///
10063        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10064        pub fn certify<
10065            T: crate::pipeline::ConstrainedTypeShape,
10066            P: crate::enforcement::ValidationPhase,
10067            H: crate::enforcement::Hasher<FP_MAX>,
10068            const FP_MAX: usize,
10069        >(
10070            input: &Validated<T, P>,
10071        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10072        {
10073            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
10074        }
10075
10076        /// Phase D (target §4.2): certify at an explicit Witt level.
10077        ///
10078        /// # Errors
10079        ///
10080        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10081        pub fn certify_at<
10082            T: crate::pipeline::ConstrainedTypeShape,
10083            P: crate::enforcement::ValidationPhase,
10084            H: crate::enforcement::Hasher<FP_MAX>,
10085            const FP_MAX: usize,
10086        >(
10087            input: &Validated<T, P>,
10088            level: WittLevel,
10089        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10090        {
10091            let _ = input.inner();
10092            let witt_bits = level.witt_length() as u16;
10093            let (tr_bits, tr_constraints, tr_sat) =
10094                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10095                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10096            if tr_sat == 0 {
10097                return Err(Certified::new(GenericImpossibilityWitness::default()));
10098            }
10099            let mut hasher = H::initial();
10100            hasher = crate::enforcement::fold_terminal_reduction(
10101                hasher,
10102                tr_bits,
10103                tr_constraints,
10104                tr_sat,
10105            );
10106            hasher = crate::enforcement::fold_unit_digest(
10107                hasher,
10108                witt_bits,
10109                witt_bits as u64,
10110                T::IRI,
10111                T::SITE_COUNT,
10112                T::CONSTRAINTS,
10113                <Kernel as super::ResolverKernel>::KIND,
10114            );
10115            let buffer = hasher.finalize();
10116            let fp =
10117                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10118            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10119            Ok(Certified::new(cert))
10120        }
10121    }
10122
10123    /// 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.
10124    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10125    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10126    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10127    /// failure — the witness itself is certified so downstream can persist it
10128    /// alongside success certs in a uniform `Certified<_>` channel.
10129    /// Phase X.1: the produced cert class is the ontology-declared class for
10130    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10131    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10132    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10133    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10134    /// kernels so each resolver's class discrimination is load-bearing.
10135    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10136    /// kernel's composition spec) whose output is folded into the canonical
10137    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10138    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10139    /// content-addressed per its ontology class.
10140    pub mod canonical_form {
10141        use super::*;
10142
10143        #[doc(hidden)]
10144        pub struct Kernel;
10145        impl super::ResolverKernel for Kernel {
10146            type Cert<const FP_MAX: usize> = crate::enforcement::TransformCertificate<FP_MAX>;
10147            const KIND: crate::enforcement::CertificateKind =
10148                crate::enforcement::CertificateKind::CanonicalForm;
10149        }
10150
10151        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10152        ///
10153        /// # Errors
10154        ///
10155        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10156        pub fn certify<
10157            T: crate::pipeline::ConstrainedTypeShape,
10158            P: crate::enforcement::ValidationPhase,
10159            H: crate::enforcement::Hasher<FP_MAX>,
10160            const FP_MAX: usize,
10161        >(
10162            input: &Validated<T, P>,
10163        ) -> Result<Certified<TransformCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10164        {
10165            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
10166        }
10167
10168        /// Phase D (target §4.2): certify at an explicit Witt level.
10169        ///
10170        /// # Errors
10171        ///
10172        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10173        pub fn certify_at<
10174            T: crate::pipeline::ConstrainedTypeShape,
10175            P: crate::enforcement::ValidationPhase,
10176            H: crate::enforcement::Hasher<FP_MAX>,
10177            const FP_MAX: usize,
10178        >(
10179            input: &Validated<T, P>,
10180            level: WittLevel,
10181        ) -> Result<Certified<TransformCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10182        {
10183            let _ = input.inner();
10184            let witt_bits = level.witt_length() as u16;
10185            let (tr_bits, tr_constraints, tr_sat) =
10186                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10187                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10188            if tr_sat == 0 {
10189                return Err(Certified::new(GenericImpossibilityWitness::default()));
10190            }
10191            let mut hasher = H::initial();
10192            hasher = crate::enforcement::fold_terminal_reduction(
10193                hasher,
10194                tr_bits,
10195                tr_constraints,
10196                tr_sat,
10197            );
10198            let (tr2_bits, tr2_constraints, tr2_sat) =
10199                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10200                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10201            // Church-Rosser: second reduction must agree with the first.
10202            if tr2_bits != tr_bits || tr2_constraints != tr_constraints || tr2_sat != tr_sat {
10203                return Err(Certified::new(GenericImpossibilityWitness::default()));
10204            }
10205            hasher = crate::enforcement::fold_terminal_reduction(
10206                hasher,
10207                tr2_bits,
10208                tr2_constraints,
10209                tr2_sat,
10210            );
10211            hasher = crate::enforcement::fold_unit_digest(
10212                hasher,
10213                witt_bits,
10214                witt_bits as u64,
10215                T::IRI,
10216                T::SITE_COUNT,
10217                T::CONSTRAINTS,
10218                <Kernel as super::ResolverKernel>::KIND,
10219            );
10220            let buffer = hasher.finalize();
10221            let fp =
10222                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10223            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10224            Ok(Certified::new(cert))
10225        }
10226    }
10227
10228    /// 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.
10229    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10230    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10231    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10232    /// failure — the witness itself is certified so downstream can persist it
10233    /// alongside success certs in a uniform `Certified<_>` channel.
10234    /// Phase X.1: the produced cert class is the ontology-declared class for
10235    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10236    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10237    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10238    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10239    /// kernels so each resolver's class discrimination is load-bearing.
10240    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10241    /// kernel's composition spec) whose output is folded into the canonical
10242    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10243    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10244    /// content-addressed per its ontology class.
10245    pub mod type_synthesis {
10246        use super::*;
10247
10248        #[doc(hidden)]
10249        pub struct Kernel;
10250        impl super::ResolverKernel for Kernel {
10251            type Cert<const FP_MAX: usize> = crate::enforcement::TransformCertificate<FP_MAX>;
10252            const KIND: crate::enforcement::CertificateKind =
10253                crate::enforcement::CertificateKind::TypeSynthesis;
10254        }
10255
10256        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10257        ///
10258        /// # Errors
10259        ///
10260        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10261        pub fn certify<
10262            T: crate::pipeline::ConstrainedTypeShape,
10263            P: crate::enforcement::ValidationPhase,
10264            H: crate::enforcement::Hasher<FP_MAX>,
10265            const FP_MAX: usize,
10266        >(
10267            input: &Validated<T, P>,
10268        ) -> Result<Certified<TransformCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10269        {
10270            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
10271        }
10272
10273        /// Phase D (target §4.2): certify at an explicit Witt level.
10274        ///
10275        /// # Errors
10276        ///
10277        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10278        pub fn certify_at<
10279            T: crate::pipeline::ConstrainedTypeShape,
10280            P: crate::enforcement::ValidationPhase,
10281            H: crate::enforcement::Hasher<FP_MAX>,
10282            const FP_MAX: usize,
10283        >(
10284            input: &Validated<T, P>,
10285            level: WittLevel,
10286        ) -> Result<Certified<TransformCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10287        {
10288            let _ = input.inner();
10289            let witt_bits = level.witt_length() as u16;
10290            let (tr_bits, tr_constraints, tr_sat) =
10291                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10292                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10293            if tr_sat == 0 {
10294                return Err(Certified::new(GenericImpossibilityWitness::default()));
10295            }
10296            let mut hasher = H::initial();
10297            hasher = crate::enforcement::fold_terminal_reduction(
10298                hasher,
10299                tr_bits,
10300                tr_constraints,
10301                tr_sat,
10302            );
10303            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10304                .map_err(crate::enforcement::Certified::new)?;
10305            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10306            let (residual, entropy) = crate::enforcement::primitive_descent_metrics::<T>(&betti);
10307            hasher = crate::enforcement::fold_descent_metrics(hasher, residual, entropy);
10308            hasher = crate::enforcement::fold_unit_digest(
10309                hasher,
10310                witt_bits,
10311                witt_bits as u64,
10312                T::IRI,
10313                T::SITE_COUNT,
10314                T::CONSTRAINTS,
10315                <Kernel as super::ResolverKernel>::KIND,
10316            );
10317            let buffer = hasher.finalize();
10318            let fp =
10319                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10320            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10321            Ok(Certified::new(cert))
10322        }
10323    }
10324
10325    /// 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.
10326    /// Returns `Certified<TransformCertificate>` on success carrying the Witt
10327    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10328    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10329    /// failure — the witness itself is certified so downstream can persist it
10330    /// alongside success certs in a uniform `Certified<_>` channel.
10331    /// Phase X.1: the produced cert class is the ontology-declared class for
10332    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10333    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10334    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10335    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10336    /// kernels so each resolver's class discrimination is load-bearing.
10337    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10338    /// kernel's composition spec) whose output is folded into the canonical
10339    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10340    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10341    /// content-addressed per its ontology class.
10342    pub mod homotopy {
10343        use super::*;
10344
10345        #[doc(hidden)]
10346        pub struct Kernel;
10347        impl super::ResolverKernel for Kernel {
10348            type Cert<const FP_MAX: usize> = crate::enforcement::TransformCertificate<FP_MAX>;
10349            const KIND: crate::enforcement::CertificateKind =
10350                crate::enforcement::CertificateKind::Homotopy;
10351        }
10352
10353        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10354        ///
10355        /// # Errors
10356        ///
10357        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10358        pub fn certify<
10359            T: crate::pipeline::ConstrainedTypeShape,
10360            P: crate::enforcement::ValidationPhase,
10361            H: crate::enforcement::Hasher<FP_MAX>,
10362            const FP_MAX: usize,
10363        >(
10364            input: &Validated<T, P>,
10365        ) -> Result<Certified<TransformCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10366        {
10367            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
10368        }
10369
10370        /// Phase D (target §4.2): certify at an explicit Witt level.
10371        ///
10372        /// # Errors
10373        ///
10374        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10375        pub fn certify_at<
10376            T: crate::pipeline::ConstrainedTypeShape,
10377            P: crate::enforcement::ValidationPhase,
10378            H: crate::enforcement::Hasher<FP_MAX>,
10379            const FP_MAX: usize,
10380        >(
10381            input: &Validated<T, P>,
10382            level: WittLevel,
10383        ) -> Result<Certified<TransformCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10384        {
10385            let _ = input.inner();
10386            let witt_bits = level.witt_length() as u16;
10387            let (tr_bits, tr_constraints, tr_sat) =
10388                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10389                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10390            if tr_sat == 0 {
10391                return Err(Certified::new(GenericImpossibilityWitness::default()));
10392            }
10393            let mut hasher = H::initial();
10394            hasher = crate::enforcement::fold_terminal_reduction(
10395                hasher,
10396                tr_bits,
10397                tr_constraints,
10398                tr_sat,
10399            );
10400            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10401                .map_err(crate::enforcement::Certified::new)?;
10402            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10403            hasher = crate::enforcement::fold_unit_digest(
10404                hasher,
10405                witt_bits,
10406                witt_bits as u64,
10407                T::IRI,
10408                T::SITE_COUNT,
10409                T::CONSTRAINTS,
10410                <Kernel as super::ResolverKernel>::KIND,
10411            );
10412            let buffer = hasher.finalize();
10413            let fp =
10414                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10415            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10416            Ok(Certified::new(cert))
10417        }
10418    }
10419
10420    /// Phase D (target §4.2): `resolver:MonodromyResolver` — compute monodromy-group observables by tracing the constraint-nerve boundary cycles at the input's Witt level.
10421    /// Returns `Certified<IsometryCertificate>` on success carrying the Witt
10422    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10423    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10424    /// failure — the witness itself is certified so downstream can persist it
10425    /// alongside success certs in a uniform `Certified<_>` channel.
10426    /// Phase X.1: the produced cert class is the ontology-declared class for
10427    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10428    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10429    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10430    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10431    /// kernels so each resolver's class discrimination is load-bearing.
10432    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10433    /// kernel's composition spec) whose output is folded into the canonical
10434    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10435    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10436    /// content-addressed per its ontology class.
10437    pub mod monodromy {
10438        use super::*;
10439
10440        #[doc(hidden)]
10441        pub struct Kernel;
10442        impl super::ResolverKernel for Kernel {
10443            type Cert<const FP_MAX: usize> = crate::enforcement::IsometryCertificate<FP_MAX>;
10444            const KIND: crate::enforcement::CertificateKind =
10445                crate::enforcement::CertificateKind::Monodromy;
10446        }
10447
10448        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10449        ///
10450        /// # Errors
10451        ///
10452        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10453        pub fn certify<
10454            T: crate::pipeline::ConstrainedTypeShape,
10455            P: crate::enforcement::ValidationPhase,
10456            H: crate::enforcement::Hasher<FP_MAX>,
10457            const FP_MAX: usize,
10458        >(
10459            input: &Validated<T, P>,
10460        ) -> Result<Certified<IsometryCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10461        {
10462            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
10463        }
10464
10465        /// Phase D (target §4.2): certify at an explicit Witt level.
10466        ///
10467        /// # Errors
10468        ///
10469        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10470        pub fn certify_at<
10471            T: crate::pipeline::ConstrainedTypeShape,
10472            P: crate::enforcement::ValidationPhase,
10473            H: crate::enforcement::Hasher<FP_MAX>,
10474            const FP_MAX: usize,
10475        >(
10476            input: &Validated<T, P>,
10477            level: WittLevel,
10478        ) -> Result<Certified<IsometryCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10479        {
10480            let _ = input.inner();
10481            let witt_bits = level.witt_length() as u16;
10482            let (tr_bits, tr_constraints, tr_sat) =
10483                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10484                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10485            if tr_sat == 0 {
10486                return Err(Certified::new(GenericImpossibilityWitness::default()));
10487            }
10488            let mut hasher = H::initial();
10489            hasher = crate::enforcement::fold_terminal_reduction(
10490                hasher,
10491                tr_bits,
10492                tr_constraints,
10493                tr_sat,
10494            );
10495            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10496                .map_err(crate::enforcement::Certified::new)?;
10497            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
10498            let (orbit_size, representative) =
10499                crate::enforcement::primitive_dihedral_signature::<T>();
10500            hasher =
10501                crate::enforcement::fold_dihedral_signature(hasher, orbit_size, representative);
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<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10515            Ok(Certified::new(cert))
10516        }
10517    }
10518
10519    /// Phase D (target §4.2): `resolver:ModuliResolver` — compute the local moduli-space structure at a `CompleteType`: DeformationComplex, HolonomyStratum, tangent/obstruction dimensions.
10520    /// Returns `Certified<TransformCertificate>` 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 moduli {
10537        use super::*;
10538
10539        #[doc(hidden)]
10540        pub struct Kernel;
10541        impl super::ResolverKernel for Kernel {
10542            type Cert<const FP_MAX: usize> = crate::enforcement::TransformCertificate<FP_MAX>;
10543            const KIND: crate::enforcement::CertificateKind =
10544                crate::enforcement::CertificateKind::Moduli;
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<FP_MAX>,
10556            const FP_MAX: usize,
10557        >(
10558            input: &Validated<T, P>,
10559        ) -> Result<Certified<TransformCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10560        {
10561            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
10562        }
10563
10564        /// Phase D (target §4.2): certify at an explicit Witt level.
10565        ///
10566        /// # Errors
10567        ///
10568        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10569        pub fn certify_at<
10570            T: crate::pipeline::ConstrainedTypeShape,
10571            P: crate::enforcement::ValidationPhase,
10572            H: crate::enforcement::Hasher<FP_MAX>,
10573            const FP_MAX: usize,
10574        >(
10575            input: &Validated<T, P>,
10576            level: WittLevel,
10577        ) -> Result<Certified<TransformCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10578        {
10579            let _ = input.inner();
10580            let witt_bits = level.witt_length() as u16;
10581            let (tr_bits, tr_constraints, tr_sat) =
10582                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10583                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10584            if tr_sat == 0 {
10585                return Err(Certified::new(GenericImpossibilityWitness::default()));
10586            }
10587            let mut hasher = H::initial();
10588            hasher = crate::enforcement::fold_terminal_reduction(
10589                hasher,
10590                tr_bits,
10591                tr_constraints,
10592                tr_sat,
10593            );
10594            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
10595                .map_err(crate::enforcement::Certified::new)?;
10596            let automorphisms: u32 = betti[0];
10597            let deformations: u32 = if crate::enforcement::MAX_BETTI_DIMENSION > 1 {
10598                betti[1]
10599            } else {
10600                0
10601            };
10602            let obstructions: u32 = if crate::enforcement::MAX_BETTI_DIMENSION > 2 {
10603                betti[2]
10604            } else {
10605                0
10606            };
10607            hasher = hasher.fold_bytes(&automorphisms.to_be_bytes());
10608            hasher = hasher.fold_bytes(&deformations.to_be_bytes());
10609            hasher = hasher.fold_bytes(&obstructions.to_be_bytes());
10610            hasher = crate::enforcement::fold_unit_digest(
10611                hasher,
10612                witt_bits,
10613                witt_bits as u64,
10614                T::IRI,
10615                T::SITE_COUNT,
10616                T::CONSTRAINTS,
10617                <Kernel as super::ResolverKernel>::KIND,
10618            );
10619            let buffer = hasher.finalize();
10620            let fp =
10621                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10622            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10623            Ok(Certified::new(cert))
10624        }
10625    }
10626
10627    /// 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.
10628    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10629    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10630    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10631    /// failure — the witness itself is certified so downstream can persist it
10632    /// alongside success certs in a uniform `Certified<_>` channel.
10633    /// Phase X.1: the produced cert class is the ontology-declared class for
10634    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10635    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10636    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10637    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10638    /// kernels so each resolver's class discrimination is load-bearing.
10639    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10640    /// kernel's composition spec) whose output is folded into the canonical
10641    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10642    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10643    /// content-addressed per its ontology class.
10644    pub mod jacobian_guided {
10645        use super::*;
10646
10647        #[doc(hidden)]
10648        pub struct Kernel;
10649        impl super::ResolverKernel for Kernel {
10650            type Cert<const FP_MAX: usize> = crate::enforcement::GroundingCertificate<FP_MAX>;
10651            const KIND: crate::enforcement::CertificateKind =
10652                crate::enforcement::CertificateKind::JacobianGuided;
10653        }
10654
10655        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10656        ///
10657        /// # Errors
10658        ///
10659        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10660        pub fn certify<
10661            T: crate::pipeline::ConstrainedTypeShape,
10662            P: crate::enforcement::ValidationPhase,
10663            H: crate::enforcement::Hasher<FP_MAX>,
10664            const FP_MAX: usize,
10665        >(
10666            input: &Validated<T, P>,
10667        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10668        {
10669            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
10670        }
10671
10672        /// Phase D (target §4.2): certify at an explicit Witt level.
10673        ///
10674        /// # Errors
10675        ///
10676        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10677        pub fn certify_at<
10678            T: crate::pipeline::ConstrainedTypeShape,
10679            P: crate::enforcement::ValidationPhase,
10680            H: crate::enforcement::Hasher<FP_MAX>,
10681            const FP_MAX: usize,
10682        >(
10683            input: &Validated<T, P>,
10684            level: WittLevel,
10685        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10686        {
10687            let _ = input.inner();
10688            let witt_bits = level.witt_length() as u16;
10689            let (tr_bits, tr_constraints, tr_sat) =
10690                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10691                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10692            if tr_sat == 0 {
10693                return Err(Certified::new(GenericImpossibilityWitness::default()));
10694            }
10695            let mut hasher = H::initial();
10696            hasher = crate::enforcement::fold_terminal_reduction(
10697                hasher,
10698                tr_bits,
10699                tr_constraints,
10700                tr_sat,
10701            );
10702            let jac = crate::enforcement::primitive_curvature_jacobian::<T>();
10703            hasher = crate::enforcement::fold_jacobian_profile(hasher, &jac);
10704            let selected_site = crate::enforcement::primitive_dc10_select(&jac);
10705            hasher = hasher.fold_bytes(&(selected_site as u32).to_be_bytes());
10706            hasher = crate::enforcement::fold_unit_digest(
10707                hasher,
10708                witt_bits,
10709                witt_bits as u64,
10710                T::IRI,
10711                T::SITE_COUNT,
10712                T::CONSTRAINTS,
10713                <Kernel as super::ResolverKernel>::KIND,
10714            );
10715            let buffer = hasher.finalize();
10716            let fp =
10717                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10718            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10719            Ok(Certified::new(cert))
10720        }
10721    }
10722
10723    /// 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.
10724    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10725    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10726    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10727    /// failure — the witness itself is certified so downstream can persist it
10728    /// alongside success certs in a uniform `Certified<_>` channel.
10729    /// Phase X.1: the produced cert class is the ontology-declared class for
10730    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10731    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10732    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10733    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10734    /// kernels so each resolver's class discrimination is load-bearing.
10735    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10736    /// kernel's composition spec) whose output is folded into the canonical
10737    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10738    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10739    /// content-addressed per its ontology class.
10740    pub mod evaluation {
10741        use super::*;
10742
10743        #[doc(hidden)]
10744        pub struct Kernel;
10745        impl super::ResolverKernel for Kernel {
10746            type Cert<const FP_MAX: usize> = crate::enforcement::GroundingCertificate<FP_MAX>;
10747            const KIND: crate::enforcement::CertificateKind =
10748                crate::enforcement::CertificateKind::Evaluation;
10749        }
10750
10751        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10752        ///
10753        /// # Errors
10754        ///
10755        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10756        pub fn certify<
10757            T: crate::pipeline::ConstrainedTypeShape,
10758            P: crate::enforcement::ValidationPhase,
10759            H: crate::enforcement::Hasher<FP_MAX>,
10760            const FP_MAX: usize,
10761        >(
10762            input: &Validated<T, P>,
10763        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10764        {
10765            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
10766        }
10767
10768        /// Phase D (target §4.2): certify at an explicit Witt level.
10769        ///
10770        /// # Errors
10771        ///
10772        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10773        pub fn certify_at<
10774            T: crate::pipeline::ConstrainedTypeShape,
10775            P: crate::enforcement::ValidationPhase,
10776            H: crate::enforcement::Hasher<FP_MAX>,
10777            const FP_MAX: usize,
10778        >(
10779            input: &Validated<T, P>,
10780            level: WittLevel,
10781        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10782        {
10783            let _ = input.inner();
10784            let witt_bits = level.witt_length() as u16;
10785            let (tr_bits, tr_constraints, tr_sat) =
10786                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
10787                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
10788            if tr_sat == 0 {
10789                return Err(Certified::new(GenericImpossibilityWitness::default()));
10790            }
10791            let mut hasher = H::initial();
10792            hasher = crate::enforcement::fold_terminal_reduction(
10793                hasher,
10794                tr_bits,
10795                tr_constraints,
10796                tr_sat,
10797            );
10798            hasher = crate::enforcement::fold_unit_digest(
10799                hasher,
10800                witt_bits,
10801                witt_bits as u64,
10802                T::IRI,
10803                T::SITE_COUNT,
10804                T::CONSTRAINTS,
10805                <Kernel as super::ResolverKernel>::KIND,
10806            );
10807            let buffer = hasher.finalize();
10808            let fp =
10809                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10810            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10811            Ok(Certified::new(cert))
10812        }
10813    }
10814
10815    /// 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.
10816    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
10817    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10818    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10819    /// failure — the witness itself is certified so downstream can persist it
10820    /// alongside success certs in a uniform `Certified<_>` channel.
10821    /// Phase X.1: the produced cert class is the ontology-declared class for
10822    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10823    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10824    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10825    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10826    /// kernels so each resolver's class discrimination is load-bearing.
10827    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10828    /// kernel's composition spec) whose output is folded into the canonical
10829    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10830    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10831    /// content-addressed per its ontology class.
10832    pub mod session {
10833        use super::*;
10834
10835        #[doc(hidden)]
10836        pub struct Kernel;
10837        impl super::ResolverKernel for Kernel {
10838            type Cert<const FP_MAX: usize> = crate::enforcement::GroundingCertificate<FP_MAX>;
10839            const KIND: crate::enforcement::CertificateKind =
10840                crate::enforcement::CertificateKind::Session;
10841        }
10842
10843        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10844        ///
10845        /// # Errors
10846        ///
10847        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10848        pub fn certify<
10849            P: crate::enforcement::ValidationPhase,
10850            H: crate::enforcement::Hasher<FP_MAX>,
10851            const INLINE_BYTES: usize,
10852            const FP_MAX: usize,
10853        >(
10854            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
10855        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10856        {
10857            certify_at::<P, H, INLINE_BYTES, FP_MAX>(input, WittLevel::W32)
10858        }
10859
10860        /// Phase D (target §4.2): certify at an explicit Witt level.
10861        ///
10862        /// # Errors
10863        ///
10864        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10865        pub fn certify_at<
10866            P: crate::enforcement::ValidationPhase,
10867            H: crate::enforcement::Hasher<FP_MAX>,
10868            const INLINE_BYTES: usize,
10869            const FP_MAX: usize,
10870        >(
10871            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
10872            level: WittLevel,
10873        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10874        {
10875            let unit = input.inner();
10876            let witt_bits = level.witt_length() as u16;
10877            let budget = unit.thermodynamic_budget();
10878            let result_type_iri = unit.result_type_iri();
10879            let mut hasher = H::initial();
10880            let (binding_count, fold_addr) =
10881                crate::enforcement::primitive_session_binding_signature(unit.bindings());
10882            hasher = crate::enforcement::fold_session_signature(hasher, binding_count, fold_addr);
10883            hasher = crate::enforcement::fold_unit_digest(
10884                hasher,
10885                witt_bits,
10886                budget,
10887                result_type_iri,
10888                0usize,
10889                &[],
10890                <Kernel as super::ResolverKernel>::KIND,
10891            );
10892            let buffer = hasher.finalize();
10893            let fp =
10894                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10895            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10896            Ok(Certified::new(cert))
10897        }
10898    }
10899
10900    /// 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).
10901    /// Returns `Certified<BornRuleVerification>` on success carrying the Witt
10902    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10903    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10904    /// failure — the witness itself is certified so downstream can persist it
10905    /// alongside success certs in a uniform `Certified<_>` channel.
10906    /// Phase X.1: the produced cert class is the ontology-declared class for
10907    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10908    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10909    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10910    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10911    /// kernels so each resolver's class discrimination is load-bearing.
10912    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
10913    /// kernel's composition spec) whose output is folded into the canonical
10914    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
10915    /// yield distinct fingerprints — i.e., each kernel's decision is real and
10916    /// content-addressed per its ontology class.
10917    pub mod superposition {
10918        use super::*;
10919
10920        #[doc(hidden)]
10921        pub struct Kernel;
10922        impl super::ResolverKernel for Kernel {
10923            type Cert<const FP_MAX: usize> = crate::enforcement::BornRuleVerification<FP_MAX>;
10924            const KIND: crate::enforcement::CertificateKind =
10925                crate::enforcement::CertificateKind::Superposition;
10926        }
10927
10928        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
10929        ///
10930        /// # Errors
10931        ///
10932        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10933        pub fn certify<
10934            P: crate::enforcement::ValidationPhase,
10935            H: crate::enforcement::Hasher<FP_MAX>,
10936            const INLINE_BYTES: usize,
10937            const FP_MAX: usize,
10938        >(
10939            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
10940        ) -> Result<Certified<BornRuleVerification<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10941        {
10942            certify_at::<P, H, INLINE_BYTES, FP_MAX>(input, WittLevel::W32)
10943        }
10944
10945        /// Phase D (target §4.2): certify at an explicit Witt level.
10946        ///
10947        /// # Errors
10948        ///
10949        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
10950        pub fn certify_at<
10951            P: crate::enforcement::ValidationPhase,
10952            H: crate::enforcement::Hasher<FP_MAX>,
10953            const INLINE_BYTES: usize,
10954            const FP_MAX: usize,
10955        >(
10956            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
10957            level: WittLevel,
10958        ) -> Result<Certified<BornRuleVerification<FP_MAX>>, Certified<GenericImpossibilityWitness>>
10959        {
10960            let unit = input.inner();
10961            let witt_bits = level.witt_length() as u16;
10962            let budget = unit.thermodynamic_budget();
10963            let result_type_iri = unit.result_type_iri();
10964            let mut hasher = H::initial();
10965            let (binding_count, fold_addr) =
10966                crate::enforcement::primitive_session_binding_signature(unit.bindings());
10967            hasher = crate::enforcement::fold_session_signature(hasher, binding_count, fold_addr);
10968            let (outcome_index, probability) =
10969                crate::enforcement::primitive_measurement_projection(budget);
10970            hasher = crate::enforcement::fold_born_outcome(hasher, outcome_index, probability);
10971            hasher = crate::enforcement::fold_unit_digest(
10972                hasher,
10973                witt_bits,
10974                budget,
10975                result_type_iri,
10976                0usize,
10977                &[],
10978                <Kernel as super::ResolverKernel>::KIND,
10979            );
10980            let buffer = hasher.finalize();
10981            let fp =
10982                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
10983            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
10984            Ok(Certified::new(cert))
10985        }
10986    }
10987
10988    /// Phase D (target §4.2): `resolver:MeasurementResolver` — resolve a `trace:MeasurementEvent` against the von Neumann-Landauer bridge (QM_1): `preCollapseEntropy = postCollapseLandauerCost` at β* = ln 2.
10989    /// Returns `Certified<MeasurementCertificate>` on success carrying the Witt
10990    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
10991    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
10992    /// failure — the witness itself is certified so downstream can persist it
10993    /// alongside success certs in a uniform `Certified<_>` channel.
10994    /// Phase X.1: the produced cert class is the ontology-declared class for
10995    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
10996    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
10997    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
10998    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
10999    /// kernels so each resolver's class discrimination is load-bearing.
11000    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11001    /// kernel's composition spec) whose output is folded into the canonical
11002    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11003    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11004    /// content-addressed per its ontology class.
11005    pub mod measurement {
11006        use super::*;
11007
11008        #[doc(hidden)]
11009        pub struct Kernel;
11010        impl super::ResolverKernel for Kernel {
11011            type Cert<const FP_MAX: usize> = crate::enforcement::MeasurementCertificate<FP_MAX>;
11012            const KIND: crate::enforcement::CertificateKind =
11013                crate::enforcement::CertificateKind::Measurement;
11014        }
11015
11016        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11017        ///
11018        /// # Errors
11019        ///
11020        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11021        pub fn certify<
11022            P: crate::enforcement::ValidationPhase,
11023            H: crate::enforcement::Hasher<FP_MAX>,
11024            const INLINE_BYTES: usize,
11025            const FP_MAX: usize,
11026        >(
11027            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
11028        ) -> Result<Certified<MeasurementCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
11029        {
11030            certify_at::<P, H, INLINE_BYTES, FP_MAX>(input, WittLevel::W32)
11031        }
11032
11033        /// Phase D (target §4.2): certify at an explicit Witt level.
11034        ///
11035        /// # Errors
11036        ///
11037        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11038        pub fn certify_at<
11039            P: crate::enforcement::ValidationPhase,
11040            H: crate::enforcement::Hasher<FP_MAX>,
11041            const INLINE_BYTES: usize,
11042            const FP_MAX: usize,
11043        >(
11044            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
11045            level: WittLevel,
11046        ) -> Result<Certified<MeasurementCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
11047        {
11048            let unit = input.inner();
11049            let witt_bits = level.witt_length() as u16;
11050            let budget = unit.thermodynamic_budget();
11051            let result_type_iri = unit.result_type_iri();
11052            let mut hasher = H::initial();
11053            let (outcome_index, probability) =
11054                crate::enforcement::primitive_measurement_projection(budget);
11055            hasher = crate::enforcement::fold_born_outcome(hasher, outcome_index, probability);
11056            hasher = crate::enforcement::fold_unit_digest(
11057                hasher,
11058                witt_bits,
11059                budget,
11060                result_type_iri,
11061                0usize,
11062                &[],
11063                <Kernel as super::ResolverKernel>::KIND,
11064            );
11065            let buffer = hasher.finalize();
11066            let fp =
11067                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11068            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
11069            Ok(Certified::new(cert))
11070        }
11071    }
11072
11073    /// 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.
11074    /// Returns `Certified<GroundingCertificate>` on success carrying the Witt
11075    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
11076    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
11077    /// failure — the witness itself is certified so downstream can persist it
11078    /// alongside success certs in a uniform `Certified<_>` channel.
11079    /// Phase X.1: the produced cert class is the ontology-declared class for
11080    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
11081    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
11082    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
11083    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
11084    /// kernels so each resolver's class discrimination is load-bearing.
11085    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11086    /// kernel's composition spec) whose output is folded into the canonical
11087    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11088    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11089    /// content-addressed per its ontology class.
11090    pub mod witt_level_resolver {
11091        use super::*;
11092
11093        #[doc(hidden)]
11094        pub struct Kernel;
11095        impl super::ResolverKernel for Kernel {
11096            type Cert<const FP_MAX: usize> = crate::enforcement::GroundingCertificate<FP_MAX>;
11097            const KIND: crate::enforcement::CertificateKind =
11098                crate::enforcement::CertificateKind::WittLevel;
11099        }
11100
11101        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11102        ///
11103        /// # Errors
11104        ///
11105        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11106        pub fn certify<
11107            P: crate::enforcement::ValidationPhase,
11108            H: crate::enforcement::Hasher<FP_MAX>,
11109            const INLINE_BYTES: usize,
11110            const FP_MAX: usize,
11111        >(
11112            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
11113        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
11114        {
11115            certify_at::<P, H, INLINE_BYTES, FP_MAX>(input, WittLevel::W32)
11116        }
11117
11118        /// Phase D (target §4.2): certify at an explicit Witt level.
11119        ///
11120        /// # Errors
11121        ///
11122        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11123        pub fn certify_at<
11124            P: crate::enforcement::ValidationPhase,
11125            H: crate::enforcement::Hasher<FP_MAX>,
11126            const INLINE_BYTES: usize,
11127            const FP_MAX: usize,
11128        >(
11129            input: &Validated<CompileUnit<'_, INLINE_BYTES>, P>,
11130            level: WittLevel,
11131        ) -> Result<Certified<GroundingCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
11132        {
11133            let unit = input.inner();
11134            let witt_bits = level.witt_length() as u16;
11135            let budget = unit.thermodynamic_budget();
11136            let result_type_iri = unit.result_type_iri();
11137            let mut hasher = H::initial();
11138            hasher = hasher.fold_bytes(&witt_bits.to_be_bytes());
11139            let declared_level_bits = unit.witt_level().witt_length() as u16;
11140            hasher = hasher.fold_bytes(&declared_level_bits.to_be_bytes());
11141            hasher = crate::enforcement::fold_unit_digest(
11142                hasher,
11143                witt_bits,
11144                budget,
11145                result_type_iri,
11146                0usize,
11147                &[],
11148                <Kernel as super::ResolverKernel>::KIND,
11149            );
11150            let buffer = hasher.finalize();
11151            let fp =
11152                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11153            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
11154            Ok(Certified::new(cert))
11155        }
11156    }
11157
11158    /// Phase D (target §4.2): `resolver:DihedralFactorizationResolver` — run the dihedral factorization decider on a `ConstrainedType`'s carrier, producing a cert over the factor structure.
11159    /// Returns `Certified<InvolutionCertificate>` on success carrying the Witt
11160    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
11161    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
11162    /// failure — the witness itself is certified so downstream can persist it
11163    /// alongside success certs in a uniform `Certified<_>` channel.
11164    /// Phase X.1: the produced cert class is the ontology-declared class for
11165    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
11166    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
11167    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
11168    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
11169    /// kernels so each resolver's class discrimination is load-bearing.
11170    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11171    /// kernel's composition spec) whose output is folded into the canonical
11172    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11173    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11174    /// content-addressed per its ontology class.
11175    pub mod dihedral_factorization {
11176        use super::*;
11177
11178        #[doc(hidden)]
11179        pub struct Kernel;
11180        impl super::ResolverKernel for Kernel {
11181            type Cert<const FP_MAX: usize> = crate::enforcement::InvolutionCertificate<FP_MAX>;
11182            const KIND: crate::enforcement::CertificateKind =
11183                crate::enforcement::CertificateKind::DihedralFactorization;
11184        }
11185
11186        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11187        ///
11188        /// # Errors
11189        ///
11190        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11191        pub fn certify<
11192            T: crate::pipeline::ConstrainedTypeShape,
11193            P: crate::enforcement::ValidationPhase,
11194            H: crate::enforcement::Hasher<FP_MAX>,
11195            const FP_MAX: usize,
11196        >(
11197            input: &Validated<T, P>,
11198        ) -> Result<Certified<InvolutionCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
11199        {
11200            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
11201        }
11202
11203        /// Phase D (target §4.2): certify at an explicit Witt level.
11204        ///
11205        /// # Errors
11206        ///
11207        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11208        pub fn certify_at<
11209            T: crate::pipeline::ConstrainedTypeShape,
11210            P: crate::enforcement::ValidationPhase,
11211            H: crate::enforcement::Hasher<FP_MAX>,
11212            const FP_MAX: usize,
11213        >(
11214            input: &Validated<T, P>,
11215            level: WittLevel,
11216        ) -> Result<Certified<InvolutionCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
11217        {
11218            let _ = input.inner();
11219            let witt_bits = level.witt_length() as u16;
11220            let (tr_bits, tr_constraints, tr_sat) =
11221                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11222                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11223            if tr_sat == 0 {
11224                return Err(Certified::new(GenericImpossibilityWitness::default()));
11225            }
11226            let mut hasher = H::initial();
11227            hasher = crate::enforcement::fold_terminal_reduction(
11228                hasher,
11229                tr_bits,
11230                tr_constraints,
11231                tr_sat,
11232            );
11233            let (orbit_size, representative) =
11234                crate::enforcement::primitive_dihedral_signature::<T>();
11235            hasher =
11236                crate::enforcement::fold_dihedral_signature(hasher, orbit_size, representative);
11237            hasher = crate::enforcement::fold_unit_digest(
11238                hasher,
11239                witt_bits,
11240                witt_bits as u64,
11241                T::IRI,
11242                T::SITE_COUNT,
11243                T::CONSTRAINTS,
11244                <Kernel as super::ResolverKernel>::KIND,
11245            );
11246            let buffer = hasher.finalize();
11247            let fp =
11248                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11249            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
11250            Ok(Certified::new(cert))
11251        }
11252    }
11253
11254    /// 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.
11255    /// Returns `Certified<CompletenessCertificate>` on success carrying the Witt
11256    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
11257    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
11258    /// failure — the witness itself is certified so downstream can persist it
11259    /// alongside success certs in a uniform `Certified<_>` channel.
11260    /// Phase X.1: the produced cert class is the ontology-declared class for
11261    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
11262    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
11263    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
11264    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
11265    /// kernels so each resolver's class discrimination is load-bearing.
11266    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11267    /// kernel's composition spec) whose output is folded into the canonical
11268    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11269    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11270    /// content-addressed per its ontology class.
11271    pub mod completeness {
11272        use super::*;
11273
11274        #[doc(hidden)]
11275        pub struct Kernel;
11276        impl super::ResolverKernel for Kernel {
11277            type Cert<const FP_MAX: usize> = crate::enforcement::CompletenessCertificate<FP_MAX>;
11278            const KIND: crate::enforcement::CertificateKind =
11279                crate::enforcement::CertificateKind::Completeness;
11280        }
11281
11282        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11283        ///
11284        /// # Errors
11285        ///
11286        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11287        pub fn certify<
11288            T: crate::pipeline::ConstrainedTypeShape,
11289            P: crate::enforcement::ValidationPhase,
11290            H: crate::enforcement::Hasher<FP_MAX>,
11291            const FP_MAX: usize,
11292        >(
11293            input: &Validated<T, P>,
11294        ) -> Result<
11295            Certified<CompletenessCertificate<FP_MAX>>,
11296            Certified<GenericImpossibilityWitness>,
11297        > {
11298            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
11299        }
11300
11301        /// Phase D (target §4.2): certify at an explicit Witt level.
11302        ///
11303        /// # Errors
11304        ///
11305        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11306        pub fn certify_at<
11307            T: crate::pipeline::ConstrainedTypeShape,
11308            P: crate::enforcement::ValidationPhase,
11309            H: crate::enforcement::Hasher<FP_MAX>,
11310            const FP_MAX: usize,
11311        >(
11312            input: &Validated<T, P>,
11313            level: WittLevel,
11314        ) -> Result<
11315            Certified<CompletenessCertificate<FP_MAX>>,
11316            Certified<GenericImpossibilityWitness>,
11317        > {
11318            let _ = input.inner();
11319            let witt_bits = level.witt_length() as u16;
11320            let (tr_bits, tr_constraints, tr_sat) =
11321                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11322                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11323            if tr_sat == 0 {
11324                return Err(Certified::new(GenericImpossibilityWitness::default()));
11325            }
11326            let mut hasher = H::initial();
11327            hasher = crate::enforcement::fold_terminal_reduction(
11328                hasher,
11329                tr_bits,
11330                tr_constraints,
11331                tr_sat,
11332            );
11333            let betti = crate::enforcement::primitive_simplicial_nerve_betti::<T>()
11334                .map_err(crate::enforcement::Certified::new)?;
11335            let chi = crate::enforcement::primitive_euler_characteristic(&betti);
11336            hasher = crate::enforcement::fold_betti_tuple(hasher, &betti);
11337            hasher = hasher.fold_bytes(&chi.to_be_bytes());
11338            hasher = crate::enforcement::fold_unit_digest(
11339                hasher,
11340                witt_bits,
11341                witt_bits as u64,
11342                T::IRI,
11343                T::SITE_COUNT,
11344                T::CONSTRAINTS,
11345                <Kernel as super::ResolverKernel>::KIND,
11346            );
11347            let buffer = hasher.finalize();
11348            let fp =
11349                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11350            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
11351            Ok(Certified::new(cert))
11352        }
11353    }
11354
11355    /// 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.
11356    /// Returns `Certified<GeodesicCertificate>` on success carrying the Witt
11357    /// level and a consumer-hasher-computed substrate fingerprint that uniquely
11358    /// identifies the input. `Certified<GenericImpossibilityWitness>` on
11359    /// failure — the witness itself is certified so downstream can persist it
11360    /// alongside success certs in a uniform `Certified<_>` channel.
11361    /// Phase X.1: the produced cert class is the ontology-declared class for
11362    /// this resolver's `resolver:CertifyMapping`. Eight cert subclasses —
11363    /// `TransformCertificate`, `IsometryCertificate`, `InvolutionCertificate`,
11364    /// `CompletenessCertificate`, `GeodesicCertificate`, `MeasurementCertificate`,
11365    /// `BornRuleVerification`, and `GroundingCertificate` — are minted across the 17 Phase D
11366    /// kernels so each resolver's class discrimination is load-bearing.
11367    /// v0.2.2 Phase J: `certify_at` composes an ontology primitive (per the
11368    /// kernel's composition spec) whose output is folded into the canonical
11369    /// fingerprint ahead of `fold_unit_digest`, so distinct primitive outputs
11370    /// yield distinct fingerprints — i.e., each kernel's decision is real and
11371    /// content-addressed per its ontology class.
11372    pub mod geodesic_validator {
11373        use super::*;
11374
11375        #[doc(hidden)]
11376        pub struct Kernel;
11377        impl super::ResolverKernel for Kernel {
11378            type Cert<const FP_MAX: usize> = crate::enforcement::GeodesicCertificate<FP_MAX>;
11379            const KIND: crate::enforcement::CertificateKind =
11380                crate::enforcement::CertificateKind::GeodesicValidator;
11381        }
11382
11383        /// Phase D (target §4.2): certify at the canonical `WittLevel::W32`.
11384        ///
11385        /// # Errors
11386        ///
11387        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11388        pub fn certify<
11389            T: crate::pipeline::ConstrainedTypeShape,
11390            P: crate::enforcement::ValidationPhase,
11391            H: crate::enforcement::Hasher<FP_MAX>,
11392            const FP_MAX: usize,
11393        >(
11394            input: &Validated<T, P>,
11395        ) -> Result<Certified<GeodesicCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
11396        {
11397            certify_at::<T, P, H, FP_MAX>(input, WittLevel::W32)
11398        }
11399
11400        /// Phase D (target §4.2): certify at an explicit Witt level.
11401        ///
11402        /// # Errors
11403        ///
11404        /// Returns `Certified<GenericImpossibilityWitness>` on failure.
11405        pub fn certify_at<
11406            T: crate::pipeline::ConstrainedTypeShape,
11407            P: crate::enforcement::ValidationPhase,
11408            H: crate::enforcement::Hasher<FP_MAX>,
11409            const FP_MAX: usize,
11410        >(
11411            input: &Validated<T, P>,
11412            level: WittLevel,
11413        ) -> Result<Certified<GeodesicCertificate<FP_MAX>>, Certified<GenericImpossibilityWitness>>
11414        {
11415            let _ = input.inner();
11416            let witt_bits = level.witt_length() as u16;
11417            let (tr_bits, tr_constraints, tr_sat) =
11418                crate::enforcement::primitive_terminal_reduction::<T>(witt_bits)
11419                    .map_err(|_| Certified::new(GenericImpossibilityWitness::default()))?;
11420            if tr_sat == 0 {
11421                return Err(Certified::new(GenericImpossibilityWitness::default()));
11422            }
11423            let mut hasher = H::initial();
11424            hasher = crate::enforcement::fold_terminal_reduction(
11425                hasher,
11426                tr_bits,
11427                tr_constraints,
11428                tr_sat,
11429            );
11430            let jac = crate::enforcement::primitive_curvature_jacobian::<T>();
11431            hasher = crate::enforcement::fold_jacobian_profile(hasher, &jac);
11432            let selected_site = crate::enforcement::primitive_dc10_select(&jac);
11433            hasher = hasher.fold_bytes(&(selected_site as u32).to_be_bytes());
11434            hasher = crate::enforcement::fold_unit_digest(
11435                hasher,
11436                witt_bits,
11437                witt_bits as u64,
11438                T::IRI,
11439                T::SITE_COUNT,
11440                T::CONSTRAINTS,
11441                <Kernel as super::ResolverKernel>::KIND,
11442            );
11443            let buffer = hasher.finalize();
11444            let fp =
11445                crate::enforcement::ContentFingerprint::from_buffer(buffer, H::OUTPUT_BYTES as u8);
11446            let cert = <<Kernel as super::ResolverKernel>::Cert<FP_MAX> as crate::enforcement::certify_const_mint::MintWithLevelFingerprint<FP_MAX>>::mint_with_level_fingerprint(witt_bits, fp);
11447            Ok(Certified::new(cert))
11448        }
11449    }
11450}
11451
11452/// v0.2.2 phantom-typed ring operation surface. Each phantom struct binds a
11453/// `WittLevel` at the type level so consumers can write
11454/// `Mul::<W8>::apply(a, b)` for compile-time level-checked arithmetic.
11455pub trait RingOp<L> {
11456    /// Operand type at this level.
11457    type Operand;
11458    /// Apply this binary ring op.
11459    fn apply(a: Self::Operand, b: Self::Operand) -> Self::Operand;
11460}
11461
11462/// v0.2.2 W3: unary phantom-typed ring operation surface. Mirrors `RingOp`
11463/// for arity-1 operations (`Neg`, `BNot`, `Succ`) so consumers can write
11464/// `Neg::<W8>::apply(a)` for compile-time level-checked unary arithmetic.
11465pub trait UnaryRingOp<L> {
11466    /// Operand type at this level.
11467    type Operand;
11468    /// Apply this unary ring op.
11469    fn apply(a: Self::Operand) -> Self::Operand;
11470}
11471
11472/// Multiplicative ring op. phantom-typed at level `L`.
11473#[derive(Debug, Default, Clone, Copy)]
11474pub struct Mul<L>(PhantomData<L>);
11475
11476/// Additive ring op. phantom-typed at level `L`.
11477#[derive(Debug, Default, Clone, Copy)]
11478pub struct Add<L>(PhantomData<L>);
11479
11480/// Subtractive ring op. phantom-typed at level `L`.
11481#[derive(Debug, Default, Clone, Copy)]
11482pub struct Sub<L>(PhantomData<L>);
11483
11484/// Bitwise XOR ring op. phantom-typed at level `L`.
11485#[derive(Debug, Default, Clone, Copy)]
11486pub struct Xor<L>(PhantomData<L>);
11487
11488/// Bitwise AND ring op. phantom-typed at level `L`.
11489#[derive(Debug, Default, Clone, Copy)]
11490pub struct And<L>(PhantomData<L>);
11491
11492/// Bitwise OR ring op. phantom-typed at level `L`.
11493#[derive(Debug, Default, Clone, Copy)]
11494pub struct Or<L>(PhantomData<L>);
11495
11496/// Ring negation (the canonical involution: x → -x). Phantom-typed at level `L` (v0.2.2 W3).
11497#[derive(Debug, Default, Clone, Copy)]
11498pub struct Neg<L>(PhantomData<L>);
11499
11500/// Bitwise NOT (the Hamming involution: x → (2^n - 1) XOR x). Phantom-typed at level `L` (v0.2.2 W3).
11501#[derive(Debug, Default, Clone, Copy)]
11502pub struct BNot<L>(PhantomData<L>);
11503
11504/// Successor (= Neg ∘ BNot per the critical composition law). Phantom-typed at level `L` (v0.2.2 W3).
11505#[derive(Debug, Default, Clone, Copy)]
11506pub struct Succ<L>(PhantomData<L>);
11507
11508/// W8 marker — 8-bit Witt level reified at the type level.
11509#[derive(Debug, Default, Clone, Copy)]
11510pub struct W8;
11511
11512/// W16 marker — 16-bit Witt level reified at the type level.
11513#[derive(Debug, Default, Clone, Copy)]
11514pub struct W16;
11515
11516/// W24 marker — 24-bit Witt level reified at the type level.
11517#[derive(Debug, Default, Clone, Copy)]
11518pub struct W24;
11519
11520/// W32 marker — 32-bit Witt level reified at the type level.
11521#[derive(Debug, Default, Clone, Copy)]
11522pub struct W32;
11523
11524/// W40 marker — 40-bit Witt level reified at the type level.
11525#[derive(Debug, Default, Clone, Copy)]
11526pub struct W40;
11527
11528/// W48 marker — 48-bit Witt level reified at the type level.
11529#[derive(Debug, Default, Clone, Copy)]
11530pub struct W48;
11531
11532/// W56 marker — 56-bit Witt level reified at the type level.
11533#[derive(Debug, Default, Clone, Copy)]
11534pub struct W56;
11535
11536/// W64 marker — 64-bit Witt level reified at the type level.
11537#[derive(Debug, Default, Clone, Copy)]
11538pub struct W64;
11539
11540/// W72 marker — 72-bit Witt level reified at the type level.
11541#[derive(Debug, Default, Clone, Copy)]
11542pub struct W72;
11543
11544/// W80 marker — 80-bit Witt level reified at the type level.
11545#[derive(Debug, Default, Clone, Copy)]
11546pub struct W80;
11547
11548/// W88 marker — 88-bit Witt level reified at the type level.
11549#[derive(Debug, Default, Clone, Copy)]
11550pub struct W88;
11551
11552/// W96 marker — 96-bit Witt level reified at the type level.
11553#[derive(Debug, Default, Clone, Copy)]
11554pub struct W96;
11555
11556/// W104 marker — 104-bit Witt level reified at the type level.
11557#[derive(Debug, Default, Clone, Copy)]
11558pub struct W104;
11559
11560/// W112 marker — 112-bit Witt level reified at the type level.
11561#[derive(Debug, Default, Clone, Copy)]
11562pub struct W112;
11563
11564/// W120 marker — 120-bit Witt level reified at the type level.
11565#[derive(Debug, Default, Clone, Copy)]
11566pub struct W120;
11567
11568/// W128 marker — 128-bit Witt level reified at the type level.
11569#[derive(Debug, Default, Clone, Copy)]
11570pub struct W128;
11571
11572impl RingOp<W8> for Mul<W8> {
11573    type Operand = u8;
11574    #[inline]
11575    fn apply(a: u8, b: u8) -> u8 {
11576        const_ring_eval_w8(PrimitiveOp::Mul, a, b)
11577    }
11578}
11579
11580impl RingOp<W8> for Add<W8> {
11581    type Operand = u8;
11582    #[inline]
11583    fn apply(a: u8, b: u8) -> u8 {
11584        const_ring_eval_w8(PrimitiveOp::Add, a, b)
11585    }
11586}
11587
11588impl RingOp<W8> for Sub<W8> {
11589    type Operand = u8;
11590    #[inline]
11591    fn apply(a: u8, b: u8) -> u8 {
11592        const_ring_eval_w8(PrimitiveOp::Sub, a, b)
11593    }
11594}
11595
11596impl RingOp<W8> for Xor<W8> {
11597    type Operand = u8;
11598    #[inline]
11599    fn apply(a: u8, b: u8) -> u8 {
11600        const_ring_eval_w8(PrimitiveOp::Xor, a, b)
11601    }
11602}
11603
11604impl RingOp<W8> for And<W8> {
11605    type Operand = u8;
11606    #[inline]
11607    fn apply(a: u8, b: u8) -> u8 {
11608        const_ring_eval_w8(PrimitiveOp::And, a, b)
11609    }
11610}
11611
11612impl RingOp<W8> for Or<W8> {
11613    type Operand = u8;
11614    #[inline]
11615    fn apply(a: u8, b: u8) -> u8 {
11616        const_ring_eval_w8(PrimitiveOp::Or, a, b)
11617    }
11618}
11619
11620impl RingOp<W16> for Mul<W16> {
11621    type Operand = u16;
11622    #[inline]
11623    fn apply(a: u16, b: u16) -> u16 {
11624        const_ring_eval_w16(PrimitiveOp::Mul, a, b)
11625    }
11626}
11627
11628impl RingOp<W16> for Add<W16> {
11629    type Operand = u16;
11630    #[inline]
11631    fn apply(a: u16, b: u16) -> u16 {
11632        const_ring_eval_w16(PrimitiveOp::Add, a, b)
11633    }
11634}
11635
11636impl RingOp<W16> for Sub<W16> {
11637    type Operand = u16;
11638    #[inline]
11639    fn apply(a: u16, b: u16) -> u16 {
11640        const_ring_eval_w16(PrimitiveOp::Sub, a, b)
11641    }
11642}
11643
11644impl RingOp<W16> for Xor<W16> {
11645    type Operand = u16;
11646    #[inline]
11647    fn apply(a: u16, b: u16) -> u16 {
11648        const_ring_eval_w16(PrimitiveOp::Xor, a, b)
11649    }
11650}
11651
11652impl RingOp<W16> for And<W16> {
11653    type Operand = u16;
11654    #[inline]
11655    fn apply(a: u16, b: u16) -> u16 {
11656        const_ring_eval_w16(PrimitiveOp::And, a, b)
11657    }
11658}
11659
11660impl RingOp<W16> for Or<W16> {
11661    type Operand = u16;
11662    #[inline]
11663    fn apply(a: u16, b: u16) -> u16 {
11664        const_ring_eval_w16(PrimitiveOp::Or, a, b)
11665    }
11666}
11667
11668impl RingOp<W24> for Mul<W24> {
11669    type Operand = u32;
11670    #[inline]
11671    fn apply(a: u32, b: u32) -> u32 {
11672        const_ring_eval_w24(PrimitiveOp::Mul, a, b)
11673    }
11674}
11675
11676impl RingOp<W24> for Add<W24> {
11677    type Operand = u32;
11678    #[inline]
11679    fn apply(a: u32, b: u32) -> u32 {
11680        const_ring_eval_w24(PrimitiveOp::Add, a, b)
11681    }
11682}
11683
11684impl RingOp<W24> for Sub<W24> {
11685    type Operand = u32;
11686    #[inline]
11687    fn apply(a: u32, b: u32) -> u32 {
11688        const_ring_eval_w24(PrimitiveOp::Sub, a, b)
11689    }
11690}
11691
11692impl RingOp<W24> for Xor<W24> {
11693    type Operand = u32;
11694    #[inline]
11695    fn apply(a: u32, b: u32) -> u32 {
11696        const_ring_eval_w24(PrimitiveOp::Xor, a, b)
11697    }
11698}
11699
11700impl RingOp<W24> for And<W24> {
11701    type Operand = u32;
11702    #[inline]
11703    fn apply(a: u32, b: u32) -> u32 {
11704        const_ring_eval_w24(PrimitiveOp::And, a, b)
11705    }
11706}
11707
11708impl RingOp<W24> for Or<W24> {
11709    type Operand = u32;
11710    #[inline]
11711    fn apply(a: u32, b: u32) -> u32 {
11712        const_ring_eval_w24(PrimitiveOp::Or, a, b)
11713    }
11714}
11715
11716impl RingOp<W32> for Mul<W32> {
11717    type Operand = u32;
11718    #[inline]
11719    fn apply(a: u32, b: u32) -> u32 {
11720        const_ring_eval_w32(PrimitiveOp::Mul, a, b)
11721    }
11722}
11723
11724impl RingOp<W32> for Add<W32> {
11725    type Operand = u32;
11726    #[inline]
11727    fn apply(a: u32, b: u32) -> u32 {
11728        const_ring_eval_w32(PrimitiveOp::Add, a, b)
11729    }
11730}
11731
11732impl RingOp<W32> for Sub<W32> {
11733    type Operand = u32;
11734    #[inline]
11735    fn apply(a: u32, b: u32) -> u32 {
11736        const_ring_eval_w32(PrimitiveOp::Sub, a, b)
11737    }
11738}
11739
11740impl RingOp<W32> for Xor<W32> {
11741    type Operand = u32;
11742    #[inline]
11743    fn apply(a: u32, b: u32) -> u32 {
11744        const_ring_eval_w32(PrimitiveOp::Xor, a, b)
11745    }
11746}
11747
11748impl RingOp<W32> for And<W32> {
11749    type Operand = u32;
11750    #[inline]
11751    fn apply(a: u32, b: u32) -> u32 {
11752        const_ring_eval_w32(PrimitiveOp::And, a, b)
11753    }
11754}
11755
11756impl RingOp<W32> for Or<W32> {
11757    type Operand = u32;
11758    #[inline]
11759    fn apply(a: u32, b: u32) -> u32 {
11760        const_ring_eval_w32(PrimitiveOp::Or, a, b)
11761    }
11762}
11763
11764impl RingOp<W40> for Mul<W40> {
11765    type Operand = u64;
11766    #[inline]
11767    fn apply(a: u64, b: u64) -> u64 {
11768        const_ring_eval_w40(PrimitiveOp::Mul, a, b)
11769    }
11770}
11771
11772impl RingOp<W40> for Add<W40> {
11773    type Operand = u64;
11774    #[inline]
11775    fn apply(a: u64, b: u64) -> u64 {
11776        const_ring_eval_w40(PrimitiveOp::Add, a, b)
11777    }
11778}
11779
11780impl RingOp<W40> for Sub<W40> {
11781    type Operand = u64;
11782    #[inline]
11783    fn apply(a: u64, b: u64) -> u64 {
11784        const_ring_eval_w40(PrimitiveOp::Sub, a, b)
11785    }
11786}
11787
11788impl RingOp<W40> for Xor<W40> {
11789    type Operand = u64;
11790    #[inline]
11791    fn apply(a: u64, b: u64) -> u64 {
11792        const_ring_eval_w40(PrimitiveOp::Xor, a, b)
11793    }
11794}
11795
11796impl RingOp<W40> for And<W40> {
11797    type Operand = u64;
11798    #[inline]
11799    fn apply(a: u64, b: u64) -> u64 {
11800        const_ring_eval_w40(PrimitiveOp::And, a, b)
11801    }
11802}
11803
11804impl RingOp<W40> for Or<W40> {
11805    type Operand = u64;
11806    #[inline]
11807    fn apply(a: u64, b: u64) -> u64 {
11808        const_ring_eval_w40(PrimitiveOp::Or, a, b)
11809    }
11810}
11811
11812impl RingOp<W48> for Mul<W48> {
11813    type Operand = u64;
11814    #[inline]
11815    fn apply(a: u64, b: u64) -> u64 {
11816        const_ring_eval_w48(PrimitiveOp::Mul, a, b)
11817    }
11818}
11819
11820impl RingOp<W48> for Add<W48> {
11821    type Operand = u64;
11822    #[inline]
11823    fn apply(a: u64, b: u64) -> u64 {
11824        const_ring_eval_w48(PrimitiveOp::Add, a, b)
11825    }
11826}
11827
11828impl RingOp<W48> for Sub<W48> {
11829    type Operand = u64;
11830    #[inline]
11831    fn apply(a: u64, b: u64) -> u64 {
11832        const_ring_eval_w48(PrimitiveOp::Sub, a, b)
11833    }
11834}
11835
11836impl RingOp<W48> for Xor<W48> {
11837    type Operand = u64;
11838    #[inline]
11839    fn apply(a: u64, b: u64) -> u64 {
11840        const_ring_eval_w48(PrimitiveOp::Xor, a, b)
11841    }
11842}
11843
11844impl RingOp<W48> for And<W48> {
11845    type Operand = u64;
11846    #[inline]
11847    fn apply(a: u64, b: u64) -> u64 {
11848        const_ring_eval_w48(PrimitiveOp::And, a, b)
11849    }
11850}
11851
11852impl RingOp<W48> for Or<W48> {
11853    type Operand = u64;
11854    #[inline]
11855    fn apply(a: u64, b: u64) -> u64 {
11856        const_ring_eval_w48(PrimitiveOp::Or, a, b)
11857    }
11858}
11859
11860impl RingOp<W56> for Mul<W56> {
11861    type Operand = u64;
11862    #[inline]
11863    fn apply(a: u64, b: u64) -> u64 {
11864        const_ring_eval_w56(PrimitiveOp::Mul, a, b)
11865    }
11866}
11867
11868impl RingOp<W56> for Add<W56> {
11869    type Operand = u64;
11870    #[inline]
11871    fn apply(a: u64, b: u64) -> u64 {
11872        const_ring_eval_w56(PrimitiveOp::Add, a, b)
11873    }
11874}
11875
11876impl RingOp<W56> for Sub<W56> {
11877    type Operand = u64;
11878    #[inline]
11879    fn apply(a: u64, b: u64) -> u64 {
11880        const_ring_eval_w56(PrimitiveOp::Sub, a, b)
11881    }
11882}
11883
11884impl RingOp<W56> for Xor<W56> {
11885    type Operand = u64;
11886    #[inline]
11887    fn apply(a: u64, b: u64) -> u64 {
11888        const_ring_eval_w56(PrimitiveOp::Xor, a, b)
11889    }
11890}
11891
11892impl RingOp<W56> for And<W56> {
11893    type Operand = u64;
11894    #[inline]
11895    fn apply(a: u64, b: u64) -> u64 {
11896        const_ring_eval_w56(PrimitiveOp::And, a, b)
11897    }
11898}
11899
11900impl RingOp<W56> for Or<W56> {
11901    type Operand = u64;
11902    #[inline]
11903    fn apply(a: u64, b: u64) -> u64 {
11904        const_ring_eval_w56(PrimitiveOp::Or, a, b)
11905    }
11906}
11907
11908impl RingOp<W64> for Mul<W64> {
11909    type Operand = u64;
11910    #[inline]
11911    fn apply(a: u64, b: u64) -> u64 {
11912        const_ring_eval_w64(PrimitiveOp::Mul, a, b)
11913    }
11914}
11915
11916impl RingOp<W64> for Add<W64> {
11917    type Operand = u64;
11918    #[inline]
11919    fn apply(a: u64, b: u64) -> u64 {
11920        const_ring_eval_w64(PrimitiveOp::Add, a, b)
11921    }
11922}
11923
11924impl RingOp<W64> for Sub<W64> {
11925    type Operand = u64;
11926    #[inline]
11927    fn apply(a: u64, b: u64) -> u64 {
11928        const_ring_eval_w64(PrimitiveOp::Sub, a, b)
11929    }
11930}
11931
11932impl RingOp<W64> for Xor<W64> {
11933    type Operand = u64;
11934    #[inline]
11935    fn apply(a: u64, b: u64) -> u64 {
11936        const_ring_eval_w64(PrimitiveOp::Xor, a, b)
11937    }
11938}
11939
11940impl RingOp<W64> for And<W64> {
11941    type Operand = u64;
11942    #[inline]
11943    fn apply(a: u64, b: u64) -> u64 {
11944        const_ring_eval_w64(PrimitiveOp::And, a, b)
11945    }
11946}
11947
11948impl RingOp<W64> for Or<W64> {
11949    type Operand = u64;
11950    #[inline]
11951    fn apply(a: u64, b: u64) -> u64 {
11952        const_ring_eval_w64(PrimitiveOp::Or, a, b)
11953    }
11954}
11955
11956impl RingOp<W72> for Mul<W72> {
11957    type Operand = u128;
11958    #[inline]
11959    fn apply(a: u128, b: u128) -> u128 {
11960        const_ring_eval_w72(PrimitiveOp::Mul, a, b)
11961    }
11962}
11963
11964impl RingOp<W72> for Add<W72> {
11965    type Operand = u128;
11966    #[inline]
11967    fn apply(a: u128, b: u128) -> u128 {
11968        const_ring_eval_w72(PrimitiveOp::Add, a, b)
11969    }
11970}
11971
11972impl RingOp<W72> for Sub<W72> {
11973    type Operand = u128;
11974    #[inline]
11975    fn apply(a: u128, b: u128) -> u128 {
11976        const_ring_eval_w72(PrimitiveOp::Sub, a, b)
11977    }
11978}
11979
11980impl RingOp<W72> for Xor<W72> {
11981    type Operand = u128;
11982    #[inline]
11983    fn apply(a: u128, b: u128) -> u128 {
11984        const_ring_eval_w72(PrimitiveOp::Xor, a, b)
11985    }
11986}
11987
11988impl RingOp<W72> for And<W72> {
11989    type Operand = u128;
11990    #[inline]
11991    fn apply(a: u128, b: u128) -> u128 {
11992        const_ring_eval_w72(PrimitiveOp::And, a, b)
11993    }
11994}
11995
11996impl RingOp<W72> for Or<W72> {
11997    type Operand = u128;
11998    #[inline]
11999    fn apply(a: u128, b: u128) -> u128 {
12000        const_ring_eval_w72(PrimitiveOp::Or, a, b)
12001    }
12002}
12003
12004impl RingOp<W80> for Mul<W80> {
12005    type Operand = u128;
12006    #[inline]
12007    fn apply(a: u128, b: u128) -> u128 {
12008        const_ring_eval_w80(PrimitiveOp::Mul, a, b)
12009    }
12010}
12011
12012impl RingOp<W80> for Add<W80> {
12013    type Operand = u128;
12014    #[inline]
12015    fn apply(a: u128, b: u128) -> u128 {
12016        const_ring_eval_w80(PrimitiveOp::Add, a, b)
12017    }
12018}
12019
12020impl RingOp<W80> for Sub<W80> {
12021    type Operand = u128;
12022    #[inline]
12023    fn apply(a: u128, b: u128) -> u128 {
12024        const_ring_eval_w80(PrimitiveOp::Sub, a, b)
12025    }
12026}
12027
12028impl RingOp<W80> for Xor<W80> {
12029    type Operand = u128;
12030    #[inline]
12031    fn apply(a: u128, b: u128) -> u128 {
12032        const_ring_eval_w80(PrimitiveOp::Xor, a, b)
12033    }
12034}
12035
12036impl RingOp<W80> for And<W80> {
12037    type Operand = u128;
12038    #[inline]
12039    fn apply(a: u128, b: u128) -> u128 {
12040        const_ring_eval_w80(PrimitiveOp::And, a, b)
12041    }
12042}
12043
12044impl RingOp<W80> for Or<W80> {
12045    type Operand = u128;
12046    #[inline]
12047    fn apply(a: u128, b: u128) -> u128 {
12048        const_ring_eval_w80(PrimitiveOp::Or, a, b)
12049    }
12050}
12051
12052impl RingOp<W88> for Mul<W88> {
12053    type Operand = u128;
12054    #[inline]
12055    fn apply(a: u128, b: u128) -> u128 {
12056        const_ring_eval_w88(PrimitiveOp::Mul, a, b)
12057    }
12058}
12059
12060impl RingOp<W88> for Add<W88> {
12061    type Operand = u128;
12062    #[inline]
12063    fn apply(a: u128, b: u128) -> u128 {
12064        const_ring_eval_w88(PrimitiveOp::Add, a, b)
12065    }
12066}
12067
12068impl RingOp<W88> for Sub<W88> {
12069    type Operand = u128;
12070    #[inline]
12071    fn apply(a: u128, b: u128) -> u128 {
12072        const_ring_eval_w88(PrimitiveOp::Sub, a, b)
12073    }
12074}
12075
12076impl RingOp<W88> for Xor<W88> {
12077    type Operand = u128;
12078    #[inline]
12079    fn apply(a: u128, b: u128) -> u128 {
12080        const_ring_eval_w88(PrimitiveOp::Xor, a, b)
12081    }
12082}
12083
12084impl RingOp<W88> for And<W88> {
12085    type Operand = u128;
12086    #[inline]
12087    fn apply(a: u128, b: u128) -> u128 {
12088        const_ring_eval_w88(PrimitiveOp::And, a, b)
12089    }
12090}
12091
12092impl RingOp<W88> for Or<W88> {
12093    type Operand = u128;
12094    #[inline]
12095    fn apply(a: u128, b: u128) -> u128 {
12096        const_ring_eval_w88(PrimitiveOp::Or, a, b)
12097    }
12098}
12099
12100impl RingOp<W96> for Mul<W96> {
12101    type Operand = u128;
12102    #[inline]
12103    fn apply(a: u128, b: u128) -> u128 {
12104        const_ring_eval_w96(PrimitiveOp::Mul, a, b)
12105    }
12106}
12107
12108impl RingOp<W96> for Add<W96> {
12109    type Operand = u128;
12110    #[inline]
12111    fn apply(a: u128, b: u128) -> u128 {
12112        const_ring_eval_w96(PrimitiveOp::Add, a, b)
12113    }
12114}
12115
12116impl RingOp<W96> for Sub<W96> {
12117    type Operand = u128;
12118    #[inline]
12119    fn apply(a: u128, b: u128) -> u128 {
12120        const_ring_eval_w96(PrimitiveOp::Sub, a, b)
12121    }
12122}
12123
12124impl RingOp<W96> for Xor<W96> {
12125    type Operand = u128;
12126    #[inline]
12127    fn apply(a: u128, b: u128) -> u128 {
12128        const_ring_eval_w96(PrimitiveOp::Xor, a, b)
12129    }
12130}
12131
12132impl RingOp<W96> for And<W96> {
12133    type Operand = u128;
12134    #[inline]
12135    fn apply(a: u128, b: u128) -> u128 {
12136        const_ring_eval_w96(PrimitiveOp::And, a, b)
12137    }
12138}
12139
12140impl RingOp<W96> for Or<W96> {
12141    type Operand = u128;
12142    #[inline]
12143    fn apply(a: u128, b: u128) -> u128 {
12144        const_ring_eval_w96(PrimitiveOp::Or, a, b)
12145    }
12146}
12147
12148impl RingOp<W104> for Mul<W104> {
12149    type Operand = u128;
12150    #[inline]
12151    fn apply(a: u128, b: u128) -> u128 {
12152        const_ring_eval_w104(PrimitiveOp::Mul, a, b)
12153    }
12154}
12155
12156impl RingOp<W104> for Add<W104> {
12157    type Operand = u128;
12158    #[inline]
12159    fn apply(a: u128, b: u128) -> u128 {
12160        const_ring_eval_w104(PrimitiveOp::Add, a, b)
12161    }
12162}
12163
12164impl RingOp<W104> for Sub<W104> {
12165    type Operand = u128;
12166    #[inline]
12167    fn apply(a: u128, b: u128) -> u128 {
12168        const_ring_eval_w104(PrimitiveOp::Sub, a, b)
12169    }
12170}
12171
12172impl RingOp<W104> for Xor<W104> {
12173    type Operand = u128;
12174    #[inline]
12175    fn apply(a: u128, b: u128) -> u128 {
12176        const_ring_eval_w104(PrimitiveOp::Xor, a, b)
12177    }
12178}
12179
12180impl RingOp<W104> for And<W104> {
12181    type Operand = u128;
12182    #[inline]
12183    fn apply(a: u128, b: u128) -> u128 {
12184        const_ring_eval_w104(PrimitiveOp::And, a, b)
12185    }
12186}
12187
12188impl RingOp<W104> for Or<W104> {
12189    type Operand = u128;
12190    #[inline]
12191    fn apply(a: u128, b: u128) -> u128 {
12192        const_ring_eval_w104(PrimitiveOp::Or, a, b)
12193    }
12194}
12195
12196impl RingOp<W112> for Mul<W112> {
12197    type Operand = u128;
12198    #[inline]
12199    fn apply(a: u128, b: u128) -> u128 {
12200        const_ring_eval_w112(PrimitiveOp::Mul, a, b)
12201    }
12202}
12203
12204impl RingOp<W112> for Add<W112> {
12205    type Operand = u128;
12206    #[inline]
12207    fn apply(a: u128, b: u128) -> u128 {
12208        const_ring_eval_w112(PrimitiveOp::Add, a, b)
12209    }
12210}
12211
12212impl RingOp<W112> for Sub<W112> {
12213    type Operand = u128;
12214    #[inline]
12215    fn apply(a: u128, b: u128) -> u128 {
12216        const_ring_eval_w112(PrimitiveOp::Sub, a, b)
12217    }
12218}
12219
12220impl RingOp<W112> for Xor<W112> {
12221    type Operand = u128;
12222    #[inline]
12223    fn apply(a: u128, b: u128) -> u128 {
12224        const_ring_eval_w112(PrimitiveOp::Xor, a, b)
12225    }
12226}
12227
12228impl RingOp<W112> for And<W112> {
12229    type Operand = u128;
12230    #[inline]
12231    fn apply(a: u128, b: u128) -> u128 {
12232        const_ring_eval_w112(PrimitiveOp::And, a, b)
12233    }
12234}
12235
12236impl RingOp<W112> for Or<W112> {
12237    type Operand = u128;
12238    #[inline]
12239    fn apply(a: u128, b: u128) -> u128 {
12240        const_ring_eval_w112(PrimitiveOp::Or, a, b)
12241    }
12242}
12243
12244impl RingOp<W120> for Mul<W120> {
12245    type Operand = u128;
12246    #[inline]
12247    fn apply(a: u128, b: u128) -> u128 {
12248        const_ring_eval_w120(PrimitiveOp::Mul, a, b)
12249    }
12250}
12251
12252impl RingOp<W120> for Add<W120> {
12253    type Operand = u128;
12254    #[inline]
12255    fn apply(a: u128, b: u128) -> u128 {
12256        const_ring_eval_w120(PrimitiveOp::Add, a, b)
12257    }
12258}
12259
12260impl RingOp<W120> for Sub<W120> {
12261    type Operand = u128;
12262    #[inline]
12263    fn apply(a: u128, b: u128) -> u128 {
12264        const_ring_eval_w120(PrimitiveOp::Sub, a, b)
12265    }
12266}
12267
12268impl RingOp<W120> for Xor<W120> {
12269    type Operand = u128;
12270    #[inline]
12271    fn apply(a: u128, b: u128) -> u128 {
12272        const_ring_eval_w120(PrimitiveOp::Xor, a, b)
12273    }
12274}
12275
12276impl RingOp<W120> for And<W120> {
12277    type Operand = u128;
12278    #[inline]
12279    fn apply(a: u128, b: u128) -> u128 {
12280        const_ring_eval_w120(PrimitiveOp::And, a, b)
12281    }
12282}
12283
12284impl RingOp<W120> for Or<W120> {
12285    type Operand = u128;
12286    #[inline]
12287    fn apply(a: u128, b: u128) -> u128 {
12288        const_ring_eval_w120(PrimitiveOp::Or, a, b)
12289    }
12290}
12291
12292impl RingOp<W128> for Mul<W128> {
12293    type Operand = u128;
12294    #[inline]
12295    fn apply(a: u128, b: u128) -> u128 {
12296        const_ring_eval_w128(PrimitiveOp::Mul, a, b)
12297    }
12298}
12299
12300impl RingOp<W128> for Add<W128> {
12301    type Operand = u128;
12302    #[inline]
12303    fn apply(a: u128, b: u128) -> u128 {
12304        const_ring_eval_w128(PrimitiveOp::Add, a, b)
12305    }
12306}
12307
12308impl RingOp<W128> for Sub<W128> {
12309    type Operand = u128;
12310    #[inline]
12311    fn apply(a: u128, b: u128) -> u128 {
12312        const_ring_eval_w128(PrimitiveOp::Sub, a, b)
12313    }
12314}
12315
12316impl RingOp<W128> for Xor<W128> {
12317    type Operand = u128;
12318    #[inline]
12319    fn apply(a: u128, b: u128) -> u128 {
12320        const_ring_eval_w128(PrimitiveOp::Xor, a, b)
12321    }
12322}
12323
12324impl RingOp<W128> for And<W128> {
12325    type Operand = u128;
12326    #[inline]
12327    fn apply(a: u128, b: u128) -> u128 {
12328        const_ring_eval_w128(PrimitiveOp::And, a, b)
12329    }
12330}
12331
12332impl RingOp<W128> for Or<W128> {
12333    type Operand = u128;
12334    #[inline]
12335    fn apply(a: u128, b: u128) -> u128 {
12336        const_ring_eval_w128(PrimitiveOp::Or, a, b)
12337    }
12338}
12339
12340impl UnaryRingOp<W8> for Neg<W8> {
12341    type Operand = u8;
12342    #[inline]
12343    fn apply(a: u8) -> u8 {
12344        const_ring_eval_w8(PrimitiveOp::Sub, 0, a)
12345    }
12346}
12347
12348impl UnaryRingOp<W8> for BNot<W8> {
12349    type Operand = u8;
12350    #[inline]
12351    fn apply(a: u8) -> u8 {
12352        const_ring_eval_w8(PrimitiveOp::Xor, a, u8::MAX)
12353    }
12354}
12355
12356impl UnaryRingOp<W8> for Succ<W8> {
12357    type Operand = u8;
12358    #[inline]
12359    fn apply(a: u8) -> u8 {
12360        <Neg<W8> as UnaryRingOp<W8>>::apply(<BNot<W8> as UnaryRingOp<W8>>::apply(a))
12361    }
12362}
12363
12364impl UnaryRingOp<W16> for Neg<W16> {
12365    type Operand = u16;
12366    #[inline]
12367    fn apply(a: u16) -> u16 {
12368        const_ring_eval_w16(PrimitiveOp::Sub, 0, a)
12369    }
12370}
12371
12372impl UnaryRingOp<W16> for BNot<W16> {
12373    type Operand = u16;
12374    #[inline]
12375    fn apply(a: u16) -> u16 {
12376        const_ring_eval_w16(PrimitiveOp::Xor, a, u16::MAX)
12377    }
12378}
12379
12380impl UnaryRingOp<W16> for Succ<W16> {
12381    type Operand = u16;
12382    #[inline]
12383    fn apply(a: u16) -> u16 {
12384        <Neg<W16> as UnaryRingOp<W16>>::apply(<BNot<W16> as UnaryRingOp<W16>>::apply(a))
12385    }
12386}
12387
12388impl UnaryRingOp<W24> for Neg<W24> {
12389    type Operand = u32;
12390    #[inline]
12391    fn apply(a: u32) -> u32 {
12392        const_ring_eval_w24(PrimitiveOp::Sub, 0, a)
12393    }
12394}
12395
12396impl UnaryRingOp<W24> for BNot<W24> {
12397    type Operand = u32;
12398    #[inline]
12399    fn apply(a: u32) -> u32 {
12400        const_ring_eval_w24(PrimitiveOp::Xor, a, 0x00FF_FFFFu32)
12401    }
12402}
12403
12404impl UnaryRingOp<W24> for Succ<W24> {
12405    type Operand = u32;
12406    #[inline]
12407    fn apply(a: u32) -> u32 {
12408        <Neg<W24> as UnaryRingOp<W24>>::apply(<BNot<W24> as UnaryRingOp<W24>>::apply(a))
12409    }
12410}
12411
12412impl UnaryRingOp<W32> for Neg<W32> {
12413    type Operand = u32;
12414    #[inline]
12415    fn apply(a: u32) -> u32 {
12416        const_ring_eval_w32(PrimitiveOp::Sub, 0, a)
12417    }
12418}
12419
12420impl UnaryRingOp<W32> for BNot<W32> {
12421    type Operand = u32;
12422    #[inline]
12423    fn apply(a: u32) -> u32 {
12424        const_ring_eval_w32(PrimitiveOp::Xor, a, u32::MAX)
12425    }
12426}
12427
12428impl UnaryRingOp<W32> for Succ<W32> {
12429    type Operand = u32;
12430    #[inline]
12431    fn apply(a: u32) -> u32 {
12432        <Neg<W32> as UnaryRingOp<W32>>::apply(<BNot<W32> as UnaryRingOp<W32>>::apply(a))
12433    }
12434}
12435
12436impl UnaryRingOp<W40> for Neg<W40> {
12437    type Operand = u64;
12438    #[inline]
12439    fn apply(a: u64) -> u64 {
12440        const_ring_eval_w40(PrimitiveOp::Sub, 0, a)
12441    }
12442}
12443
12444impl UnaryRingOp<W40> for BNot<W40> {
12445    type Operand = u64;
12446    #[inline]
12447    fn apply(a: u64) -> u64 {
12448        const_ring_eval_w40(PrimitiveOp::Xor, a, 0x0000_00FF_FFFF_FFFFu64)
12449    }
12450}
12451
12452impl UnaryRingOp<W40> for Succ<W40> {
12453    type Operand = u64;
12454    #[inline]
12455    fn apply(a: u64) -> u64 {
12456        <Neg<W40> as UnaryRingOp<W40>>::apply(<BNot<W40> as UnaryRingOp<W40>>::apply(a))
12457    }
12458}
12459
12460impl UnaryRingOp<W48> for Neg<W48> {
12461    type Operand = u64;
12462    #[inline]
12463    fn apply(a: u64) -> u64 {
12464        const_ring_eval_w48(PrimitiveOp::Sub, 0, a)
12465    }
12466}
12467
12468impl UnaryRingOp<W48> for BNot<W48> {
12469    type Operand = u64;
12470    #[inline]
12471    fn apply(a: u64) -> u64 {
12472        const_ring_eval_w48(PrimitiveOp::Xor, a, 0x0000_FFFF_FFFF_FFFFu64)
12473    }
12474}
12475
12476impl UnaryRingOp<W48> for Succ<W48> {
12477    type Operand = u64;
12478    #[inline]
12479    fn apply(a: u64) -> u64 {
12480        <Neg<W48> as UnaryRingOp<W48>>::apply(<BNot<W48> as UnaryRingOp<W48>>::apply(a))
12481    }
12482}
12483
12484impl UnaryRingOp<W56> for Neg<W56> {
12485    type Operand = u64;
12486    #[inline]
12487    fn apply(a: u64) -> u64 {
12488        const_ring_eval_w56(PrimitiveOp::Sub, 0, a)
12489    }
12490}
12491
12492impl UnaryRingOp<W56> for BNot<W56> {
12493    type Operand = u64;
12494    #[inline]
12495    fn apply(a: u64) -> u64 {
12496        const_ring_eval_w56(PrimitiveOp::Xor, a, 0x00FF_FFFF_FFFF_FFFFu64)
12497    }
12498}
12499
12500impl UnaryRingOp<W56> for Succ<W56> {
12501    type Operand = u64;
12502    #[inline]
12503    fn apply(a: u64) -> u64 {
12504        <Neg<W56> as UnaryRingOp<W56>>::apply(<BNot<W56> as UnaryRingOp<W56>>::apply(a))
12505    }
12506}
12507
12508impl UnaryRingOp<W64> for Neg<W64> {
12509    type Operand = u64;
12510    #[inline]
12511    fn apply(a: u64) -> u64 {
12512        const_ring_eval_w64(PrimitiveOp::Sub, 0, a)
12513    }
12514}
12515
12516impl UnaryRingOp<W64> for BNot<W64> {
12517    type Operand = u64;
12518    #[inline]
12519    fn apply(a: u64) -> u64 {
12520        const_ring_eval_w64(PrimitiveOp::Xor, a, u64::MAX)
12521    }
12522}
12523
12524impl UnaryRingOp<W64> for Succ<W64> {
12525    type Operand = u64;
12526    #[inline]
12527    fn apply(a: u64) -> u64 {
12528        <Neg<W64> as UnaryRingOp<W64>>::apply(<BNot<W64> as UnaryRingOp<W64>>::apply(a))
12529    }
12530}
12531
12532impl UnaryRingOp<W72> for Neg<W72> {
12533    type Operand = u128;
12534    #[inline]
12535    fn apply(a: u128) -> u128 {
12536        const_ring_eval_w72(PrimitiveOp::Sub, 0, a)
12537    }
12538}
12539
12540impl UnaryRingOp<W72> for BNot<W72> {
12541    type Operand = u128;
12542    #[inline]
12543    fn apply(a: u128) -> u128 {
12544        const_ring_eval_w72(PrimitiveOp::Xor, a, u128::MAX >> (128 - 72))
12545    }
12546}
12547
12548impl UnaryRingOp<W72> for Succ<W72> {
12549    type Operand = u128;
12550    #[inline]
12551    fn apply(a: u128) -> u128 {
12552        <Neg<W72> as UnaryRingOp<W72>>::apply(<BNot<W72> as UnaryRingOp<W72>>::apply(a))
12553    }
12554}
12555
12556impl UnaryRingOp<W80> for Neg<W80> {
12557    type Operand = u128;
12558    #[inline]
12559    fn apply(a: u128) -> u128 {
12560        const_ring_eval_w80(PrimitiveOp::Sub, 0, a)
12561    }
12562}
12563
12564impl UnaryRingOp<W80> for BNot<W80> {
12565    type Operand = u128;
12566    #[inline]
12567    fn apply(a: u128) -> u128 {
12568        const_ring_eval_w80(PrimitiveOp::Xor, a, u128::MAX >> (128 - 80))
12569    }
12570}
12571
12572impl UnaryRingOp<W80> for Succ<W80> {
12573    type Operand = u128;
12574    #[inline]
12575    fn apply(a: u128) -> u128 {
12576        <Neg<W80> as UnaryRingOp<W80>>::apply(<BNot<W80> as UnaryRingOp<W80>>::apply(a))
12577    }
12578}
12579
12580impl UnaryRingOp<W88> for Neg<W88> {
12581    type Operand = u128;
12582    #[inline]
12583    fn apply(a: u128) -> u128 {
12584        const_ring_eval_w88(PrimitiveOp::Sub, 0, a)
12585    }
12586}
12587
12588impl UnaryRingOp<W88> for BNot<W88> {
12589    type Operand = u128;
12590    #[inline]
12591    fn apply(a: u128) -> u128 {
12592        const_ring_eval_w88(PrimitiveOp::Xor, a, u128::MAX >> (128 - 88))
12593    }
12594}
12595
12596impl UnaryRingOp<W88> for Succ<W88> {
12597    type Operand = u128;
12598    #[inline]
12599    fn apply(a: u128) -> u128 {
12600        <Neg<W88> as UnaryRingOp<W88>>::apply(<BNot<W88> as UnaryRingOp<W88>>::apply(a))
12601    }
12602}
12603
12604impl UnaryRingOp<W96> for Neg<W96> {
12605    type Operand = u128;
12606    #[inline]
12607    fn apply(a: u128) -> u128 {
12608        const_ring_eval_w96(PrimitiveOp::Sub, 0, a)
12609    }
12610}
12611
12612impl UnaryRingOp<W96> for BNot<W96> {
12613    type Operand = u128;
12614    #[inline]
12615    fn apply(a: u128) -> u128 {
12616        const_ring_eval_w96(PrimitiveOp::Xor, a, u128::MAX >> (128 - 96))
12617    }
12618}
12619
12620impl UnaryRingOp<W96> for Succ<W96> {
12621    type Operand = u128;
12622    #[inline]
12623    fn apply(a: u128) -> u128 {
12624        <Neg<W96> as UnaryRingOp<W96>>::apply(<BNot<W96> as UnaryRingOp<W96>>::apply(a))
12625    }
12626}
12627
12628impl UnaryRingOp<W104> for Neg<W104> {
12629    type Operand = u128;
12630    #[inline]
12631    fn apply(a: u128) -> u128 {
12632        const_ring_eval_w104(PrimitiveOp::Sub, 0, a)
12633    }
12634}
12635
12636impl UnaryRingOp<W104> for BNot<W104> {
12637    type Operand = u128;
12638    #[inline]
12639    fn apply(a: u128) -> u128 {
12640        const_ring_eval_w104(PrimitiveOp::Xor, a, u128::MAX >> (128 - 104))
12641    }
12642}
12643
12644impl UnaryRingOp<W104> for Succ<W104> {
12645    type Operand = u128;
12646    #[inline]
12647    fn apply(a: u128) -> u128 {
12648        <Neg<W104> as UnaryRingOp<W104>>::apply(<BNot<W104> as UnaryRingOp<W104>>::apply(a))
12649    }
12650}
12651
12652impl UnaryRingOp<W112> for Neg<W112> {
12653    type Operand = u128;
12654    #[inline]
12655    fn apply(a: u128) -> u128 {
12656        const_ring_eval_w112(PrimitiveOp::Sub, 0, a)
12657    }
12658}
12659
12660impl UnaryRingOp<W112> for BNot<W112> {
12661    type Operand = u128;
12662    #[inline]
12663    fn apply(a: u128) -> u128 {
12664        const_ring_eval_w112(PrimitiveOp::Xor, a, u128::MAX >> (128 - 112))
12665    }
12666}
12667
12668impl UnaryRingOp<W112> for Succ<W112> {
12669    type Operand = u128;
12670    #[inline]
12671    fn apply(a: u128) -> u128 {
12672        <Neg<W112> as UnaryRingOp<W112>>::apply(<BNot<W112> as UnaryRingOp<W112>>::apply(a))
12673    }
12674}
12675
12676impl UnaryRingOp<W120> for Neg<W120> {
12677    type Operand = u128;
12678    #[inline]
12679    fn apply(a: u128) -> u128 {
12680        const_ring_eval_w120(PrimitiveOp::Sub, 0, a)
12681    }
12682}
12683
12684impl UnaryRingOp<W120> for BNot<W120> {
12685    type Operand = u128;
12686    #[inline]
12687    fn apply(a: u128) -> u128 {
12688        const_ring_eval_w120(PrimitiveOp::Xor, a, u128::MAX >> (128 - 120))
12689    }
12690}
12691
12692impl UnaryRingOp<W120> for Succ<W120> {
12693    type Operand = u128;
12694    #[inline]
12695    fn apply(a: u128) -> u128 {
12696        <Neg<W120> as UnaryRingOp<W120>>::apply(<BNot<W120> as UnaryRingOp<W120>>::apply(a))
12697    }
12698}
12699
12700impl UnaryRingOp<W128> for Neg<W128> {
12701    type Operand = u128;
12702    #[inline]
12703    fn apply(a: u128) -> u128 {
12704        const_ring_eval_w128(PrimitiveOp::Sub, 0, a)
12705    }
12706}
12707
12708impl UnaryRingOp<W128> for BNot<W128> {
12709    type Operand = u128;
12710    #[inline]
12711    fn apply(a: u128) -> u128 {
12712        const_ring_eval_w128(PrimitiveOp::Xor, a, u128::MAX)
12713    }
12714}
12715
12716impl UnaryRingOp<W128> for Succ<W128> {
12717    type Operand = u128;
12718    #[inline]
12719    fn apply(a: u128) -> u128 {
12720        <Neg<W128> as UnaryRingOp<W128>>::apply(<BNot<W128> as UnaryRingOp<W128>>::apply(a))
12721    }
12722}
12723
12724/// Sealed marker for well-formed level embedding pairs (`(From, To)` with
12725/// `From <= To`). v0.2.2 W3.
12726pub trait ValidLevelEmbedding: valid_level_embedding_sealed::Sealed {}
12727
12728mod valid_level_embedding_sealed {
12729    /// Private supertrait. Not implementable outside this crate.
12730    pub trait Sealed {}
12731    impl Sealed for (super::W8, super::W8) {}
12732    impl Sealed for (super::W8, super::W16) {}
12733    impl Sealed for (super::W8, super::W24) {}
12734    impl Sealed for (super::W8, super::W32) {}
12735    impl Sealed for (super::W8, super::W40) {}
12736    impl Sealed for (super::W8, super::W48) {}
12737    impl Sealed for (super::W8, super::W56) {}
12738    impl Sealed for (super::W8, super::W64) {}
12739    impl Sealed for (super::W8, super::W72) {}
12740    impl Sealed for (super::W8, super::W80) {}
12741    impl Sealed for (super::W8, super::W88) {}
12742    impl Sealed for (super::W8, super::W96) {}
12743    impl Sealed for (super::W8, super::W104) {}
12744    impl Sealed for (super::W8, super::W112) {}
12745    impl Sealed for (super::W8, super::W120) {}
12746    impl Sealed for (super::W8, super::W128) {}
12747    impl Sealed for (super::W16, super::W16) {}
12748    impl Sealed for (super::W16, super::W24) {}
12749    impl Sealed for (super::W16, super::W32) {}
12750    impl Sealed for (super::W16, super::W40) {}
12751    impl Sealed for (super::W16, super::W48) {}
12752    impl Sealed for (super::W16, super::W56) {}
12753    impl Sealed for (super::W16, super::W64) {}
12754    impl Sealed for (super::W16, super::W72) {}
12755    impl Sealed for (super::W16, super::W80) {}
12756    impl Sealed for (super::W16, super::W88) {}
12757    impl Sealed for (super::W16, super::W96) {}
12758    impl Sealed for (super::W16, super::W104) {}
12759    impl Sealed for (super::W16, super::W112) {}
12760    impl Sealed for (super::W16, super::W120) {}
12761    impl Sealed for (super::W16, super::W128) {}
12762    impl Sealed for (super::W24, super::W24) {}
12763    impl Sealed for (super::W24, super::W32) {}
12764    impl Sealed for (super::W24, super::W40) {}
12765    impl Sealed for (super::W24, super::W48) {}
12766    impl Sealed for (super::W24, super::W56) {}
12767    impl Sealed for (super::W24, super::W64) {}
12768    impl Sealed for (super::W24, super::W72) {}
12769    impl Sealed for (super::W24, super::W80) {}
12770    impl Sealed for (super::W24, super::W88) {}
12771    impl Sealed for (super::W24, super::W96) {}
12772    impl Sealed for (super::W24, super::W104) {}
12773    impl Sealed for (super::W24, super::W112) {}
12774    impl Sealed for (super::W24, super::W120) {}
12775    impl Sealed for (super::W24, super::W128) {}
12776    impl Sealed for (super::W32, super::W32) {}
12777    impl Sealed for (super::W32, super::W40) {}
12778    impl Sealed for (super::W32, super::W48) {}
12779    impl Sealed for (super::W32, super::W56) {}
12780    impl Sealed for (super::W32, super::W64) {}
12781    impl Sealed for (super::W32, super::W72) {}
12782    impl Sealed for (super::W32, super::W80) {}
12783    impl Sealed for (super::W32, super::W88) {}
12784    impl Sealed for (super::W32, super::W96) {}
12785    impl Sealed for (super::W32, super::W104) {}
12786    impl Sealed for (super::W32, super::W112) {}
12787    impl Sealed for (super::W32, super::W120) {}
12788    impl Sealed for (super::W32, super::W128) {}
12789    impl Sealed for (super::W40, super::W40) {}
12790    impl Sealed for (super::W40, super::W48) {}
12791    impl Sealed for (super::W40, super::W56) {}
12792    impl Sealed for (super::W40, super::W64) {}
12793    impl Sealed for (super::W40, super::W72) {}
12794    impl Sealed for (super::W40, super::W80) {}
12795    impl Sealed for (super::W40, super::W88) {}
12796    impl Sealed for (super::W40, super::W96) {}
12797    impl Sealed for (super::W40, super::W104) {}
12798    impl Sealed for (super::W40, super::W112) {}
12799    impl Sealed for (super::W40, super::W120) {}
12800    impl Sealed for (super::W40, super::W128) {}
12801    impl Sealed for (super::W48, super::W48) {}
12802    impl Sealed for (super::W48, super::W56) {}
12803    impl Sealed for (super::W48, super::W64) {}
12804    impl Sealed for (super::W48, super::W72) {}
12805    impl Sealed for (super::W48, super::W80) {}
12806    impl Sealed for (super::W48, super::W88) {}
12807    impl Sealed for (super::W48, super::W96) {}
12808    impl Sealed for (super::W48, super::W104) {}
12809    impl Sealed for (super::W48, super::W112) {}
12810    impl Sealed for (super::W48, super::W120) {}
12811    impl Sealed for (super::W48, super::W128) {}
12812    impl Sealed for (super::W56, super::W56) {}
12813    impl Sealed for (super::W56, super::W64) {}
12814    impl Sealed for (super::W56, super::W72) {}
12815    impl Sealed for (super::W56, super::W80) {}
12816    impl Sealed for (super::W56, super::W88) {}
12817    impl Sealed for (super::W56, super::W96) {}
12818    impl Sealed for (super::W56, super::W104) {}
12819    impl Sealed for (super::W56, super::W112) {}
12820    impl Sealed for (super::W56, super::W120) {}
12821    impl Sealed for (super::W56, super::W128) {}
12822    impl Sealed for (super::W64, super::W64) {}
12823    impl Sealed for (super::W64, super::W72) {}
12824    impl Sealed for (super::W64, super::W80) {}
12825    impl Sealed for (super::W64, super::W88) {}
12826    impl Sealed for (super::W64, super::W96) {}
12827    impl Sealed for (super::W64, super::W104) {}
12828    impl Sealed for (super::W64, super::W112) {}
12829    impl Sealed for (super::W64, super::W120) {}
12830    impl Sealed for (super::W64, super::W128) {}
12831    impl Sealed for (super::W72, super::W72) {}
12832    impl Sealed for (super::W72, super::W80) {}
12833    impl Sealed for (super::W72, super::W88) {}
12834    impl Sealed for (super::W72, super::W96) {}
12835    impl Sealed for (super::W72, super::W104) {}
12836    impl Sealed for (super::W72, super::W112) {}
12837    impl Sealed for (super::W72, super::W120) {}
12838    impl Sealed for (super::W72, super::W128) {}
12839    impl Sealed for (super::W80, super::W80) {}
12840    impl Sealed for (super::W80, super::W88) {}
12841    impl Sealed for (super::W80, super::W96) {}
12842    impl Sealed for (super::W80, super::W104) {}
12843    impl Sealed for (super::W80, super::W112) {}
12844    impl Sealed for (super::W80, super::W120) {}
12845    impl Sealed for (super::W80, super::W128) {}
12846    impl Sealed for (super::W88, super::W88) {}
12847    impl Sealed for (super::W88, super::W96) {}
12848    impl Sealed for (super::W88, super::W104) {}
12849    impl Sealed for (super::W88, super::W112) {}
12850    impl Sealed for (super::W88, super::W120) {}
12851    impl Sealed for (super::W88, super::W128) {}
12852    impl Sealed for (super::W96, super::W96) {}
12853    impl Sealed for (super::W96, super::W104) {}
12854    impl Sealed for (super::W96, super::W112) {}
12855    impl Sealed for (super::W96, super::W120) {}
12856    impl Sealed for (super::W96, super::W128) {}
12857    impl Sealed for (super::W104, super::W104) {}
12858    impl Sealed for (super::W104, super::W112) {}
12859    impl Sealed for (super::W104, super::W120) {}
12860    impl Sealed for (super::W104, super::W128) {}
12861    impl Sealed for (super::W112, super::W112) {}
12862    impl Sealed for (super::W112, super::W120) {}
12863    impl Sealed for (super::W112, super::W128) {}
12864    impl Sealed for (super::W120, super::W120) {}
12865    impl Sealed for (super::W120, super::W128) {}
12866    impl Sealed for (super::W128, super::W128) {}
12867}
12868
12869impl ValidLevelEmbedding for (W8, W8) {}
12870impl ValidLevelEmbedding for (W8, W16) {}
12871impl ValidLevelEmbedding for (W8, W24) {}
12872impl ValidLevelEmbedding for (W8, W32) {}
12873impl ValidLevelEmbedding for (W8, W40) {}
12874impl ValidLevelEmbedding for (W8, W48) {}
12875impl ValidLevelEmbedding for (W8, W56) {}
12876impl ValidLevelEmbedding for (W8, W64) {}
12877impl ValidLevelEmbedding for (W8, W72) {}
12878impl ValidLevelEmbedding for (W8, W80) {}
12879impl ValidLevelEmbedding for (W8, W88) {}
12880impl ValidLevelEmbedding for (W8, W96) {}
12881impl ValidLevelEmbedding for (W8, W104) {}
12882impl ValidLevelEmbedding for (W8, W112) {}
12883impl ValidLevelEmbedding for (W8, W120) {}
12884impl ValidLevelEmbedding for (W8, W128) {}
12885impl ValidLevelEmbedding for (W16, W16) {}
12886impl ValidLevelEmbedding for (W16, W24) {}
12887impl ValidLevelEmbedding for (W16, W32) {}
12888impl ValidLevelEmbedding for (W16, W40) {}
12889impl ValidLevelEmbedding for (W16, W48) {}
12890impl ValidLevelEmbedding for (W16, W56) {}
12891impl ValidLevelEmbedding for (W16, W64) {}
12892impl ValidLevelEmbedding for (W16, W72) {}
12893impl ValidLevelEmbedding for (W16, W80) {}
12894impl ValidLevelEmbedding for (W16, W88) {}
12895impl ValidLevelEmbedding for (W16, W96) {}
12896impl ValidLevelEmbedding for (W16, W104) {}
12897impl ValidLevelEmbedding for (W16, W112) {}
12898impl ValidLevelEmbedding for (W16, W120) {}
12899impl ValidLevelEmbedding for (W16, W128) {}
12900impl ValidLevelEmbedding for (W24, W24) {}
12901impl ValidLevelEmbedding for (W24, W32) {}
12902impl ValidLevelEmbedding for (W24, W40) {}
12903impl ValidLevelEmbedding for (W24, W48) {}
12904impl ValidLevelEmbedding for (W24, W56) {}
12905impl ValidLevelEmbedding for (W24, W64) {}
12906impl ValidLevelEmbedding for (W24, W72) {}
12907impl ValidLevelEmbedding for (W24, W80) {}
12908impl ValidLevelEmbedding for (W24, W88) {}
12909impl ValidLevelEmbedding for (W24, W96) {}
12910impl ValidLevelEmbedding for (W24, W104) {}
12911impl ValidLevelEmbedding for (W24, W112) {}
12912impl ValidLevelEmbedding for (W24, W120) {}
12913impl ValidLevelEmbedding for (W24, W128) {}
12914impl ValidLevelEmbedding for (W32, W32) {}
12915impl ValidLevelEmbedding for (W32, W40) {}
12916impl ValidLevelEmbedding for (W32, W48) {}
12917impl ValidLevelEmbedding for (W32, W56) {}
12918impl ValidLevelEmbedding for (W32, W64) {}
12919impl ValidLevelEmbedding for (W32, W72) {}
12920impl ValidLevelEmbedding for (W32, W80) {}
12921impl ValidLevelEmbedding for (W32, W88) {}
12922impl ValidLevelEmbedding for (W32, W96) {}
12923impl ValidLevelEmbedding for (W32, W104) {}
12924impl ValidLevelEmbedding for (W32, W112) {}
12925impl ValidLevelEmbedding for (W32, W120) {}
12926impl ValidLevelEmbedding for (W32, W128) {}
12927impl ValidLevelEmbedding for (W40, W40) {}
12928impl ValidLevelEmbedding for (W40, W48) {}
12929impl ValidLevelEmbedding for (W40, W56) {}
12930impl ValidLevelEmbedding for (W40, W64) {}
12931impl ValidLevelEmbedding for (W40, W72) {}
12932impl ValidLevelEmbedding for (W40, W80) {}
12933impl ValidLevelEmbedding for (W40, W88) {}
12934impl ValidLevelEmbedding for (W40, W96) {}
12935impl ValidLevelEmbedding for (W40, W104) {}
12936impl ValidLevelEmbedding for (W40, W112) {}
12937impl ValidLevelEmbedding for (W40, W120) {}
12938impl ValidLevelEmbedding for (W40, W128) {}
12939impl ValidLevelEmbedding for (W48, W48) {}
12940impl ValidLevelEmbedding for (W48, W56) {}
12941impl ValidLevelEmbedding for (W48, W64) {}
12942impl ValidLevelEmbedding for (W48, W72) {}
12943impl ValidLevelEmbedding for (W48, W80) {}
12944impl ValidLevelEmbedding for (W48, W88) {}
12945impl ValidLevelEmbedding for (W48, W96) {}
12946impl ValidLevelEmbedding for (W48, W104) {}
12947impl ValidLevelEmbedding for (W48, W112) {}
12948impl ValidLevelEmbedding for (W48, W120) {}
12949impl ValidLevelEmbedding for (W48, W128) {}
12950impl ValidLevelEmbedding for (W56, W56) {}
12951impl ValidLevelEmbedding for (W56, W64) {}
12952impl ValidLevelEmbedding for (W56, W72) {}
12953impl ValidLevelEmbedding for (W56, W80) {}
12954impl ValidLevelEmbedding for (W56, W88) {}
12955impl ValidLevelEmbedding for (W56, W96) {}
12956impl ValidLevelEmbedding for (W56, W104) {}
12957impl ValidLevelEmbedding for (W56, W112) {}
12958impl ValidLevelEmbedding for (W56, W120) {}
12959impl ValidLevelEmbedding for (W56, W128) {}
12960impl ValidLevelEmbedding for (W64, W64) {}
12961impl ValidLevelEmbedding for (W64, W72) {}
12962impl ValidLevelEmbedding for (W64, W80) {}
12963impl ValidLevelEmbedding for (W64, W88) {}
12964impl ValidLevelEmbedding for (W64, W96) {}
12965impl ValidLevelEmbedding for (W64, W104) {}
12966impl ValidLevelEmbedding for (W64, W112) {}
12967impl ValidLevelEmbedding for (W64, W120) {}
12968impl ValidLevelEmbedding for (W64, W128) {}
12969impl ValidLevelEmbedding for (W72, W72) {}
12970impl ValidLevelEmbedding for (W72, W80) {}
12971impl ValidLevelEmbedding for (W72, W88) {}
12972impl ValidLevelEmbedding for (W72, W96) {}
12973impl ValidLevelEmbedding for (W72, W104) {}
12974impl ValidLevelEmbedding for (W72, W112) {}
12975impl ValidLevelEmbedding for (W72, W120) {}
12976impl ValidLevelEmbedding for (W72, W128) {}
12977impl ValidLevelEmbedding for (W80, W80) {}
12978impl ValidLevelEmbedding for (W80, W88) {}
12979impl ValidLevelEmbedding for (W80, W96) {}
12980impl ValidLevelEmbedding for (W80, W104) {}
12981impl ValidLevelEmbedding for (W80, W112) {}
12982impl ValidLevelEmbedding for (W80, W120) {}
12983impl ValidLevelEmbedding for (W80, W128) {}
12984impl ValidLevelEmbedding for (W88, W88) {}
12985impl ValidLevelEmbedding for (W88, W96) {}
12986impl ValidLevelEmbedding for (W88, W104) {}
12987impl ValidLevelEmbedding for (W88, W112) {}
12988impl ValidLevelEmbedding for (W88, W120) {}
12989impl ValidLevelEmbedding for (W88, W128) {}
12990impl ValidLevelEmbedding for (W96, W96) {}
12991impl ValidLevelEmbedding for (W96, W104) {}
12992impl ValidLevelEmbedding for (W96, W112) {}
12993impl ValidLevelEmbedding for (W96, W120) {}
12994impl ValidLevelEmbedding for (W96, W128) {}
12995impl ValidLevelEmbedding for (W104, W104) {}
12996impl ValidLevelEmbedding for (W104, W112) {}
12997impl ValidLevelEmbedding for (W104, W120) {}
12998impl ValidLevelEmbedding for (W104, W128) {}
12999impl ValidLevelEmbedding for (W112, W112) {}
13000impl ValidLevelEmbedding for (W112, W120) {}
13001impl ValidLevelEmbedding for (W112, W128) {}
13002impl ValidLevelEmbedding for (W120, W120) {}
13003impl ValidLevelEmbedding for (W120, W128) {}
13004impl ValidLevelEmbedding for (W128, W128) {}
13005
13006/// v0.2.2 W3: phantom-typed level embedding `Embed<From, To>` for the
13007/// canonical injection ι : R_From → R_To when `From <= To`.
13008/// Implementations exist only for sealed `(From, To)` pairs in the
13009/// `ValidLevelEmbedding` trait, so attempting an unsupported direction
13010/// (e.g., `Embed<W32, W8>`) fails at compile time.
13011#[derive(Debug, Default, Clone, Copy)]
13012pub struct Embed<From, To>(PhantomData<(From, To)>);
13013
13014impl Embed<W8, W8> {
13015    /// Embed a `u8` value at W8 into a `u8` value at W8.
13016    #[inline]
13017    #[must_use]
13018    pub const fn apply(value: u8) -> u8 {
13019        value
13020    }
13021}
13022
13023impl Embed<W8, W16> {
13024    /// Embed a `u8` value at W8 into a `u16` value at W16.
13025    #[inline]
13026    #[must_use]
13027    pub const fn apply(value: u8) -> u16 {
13028        value as u16
13029    }
13030}
13031
13032impl Embed<W8, W24> {
13033    /// Embed a `u8` value at W8 into a `u32` value at W24.
13034    #[inline]
13035    #[must_use]
13036    pub const fn apply(value: u8) -> u32 {
13037        value as u32
13038    }
13039}
13040
13041impl Embed<W8, W32> {
13042    /// Embed a `u8` value at W8 into a `u32` value at W32.
13043    #[inline]
13044    #[must_use]
13045    pub const fn apply(value: u8) -> u32 {
13046        value as u32
13047    }
13048}
13049
13050impl Embed<W8, W40> {
13051    /// Embed a `u8` value at W8 into a `u64` value at W40.
13052    #[inline]
13053    #[must_use]
13054    pub const fn apply(value: u8) -> u64 {
13055        value as u64
13056    }
13057}
13058
13059impl Embed<W8, W48> {
13060    /// Embed a `u8` value at W8 into a `u64` value at W48.
13061    #[inline]
13062    #[must_use]
13063    pub const fn apply(value: u8) -> u64 {
13064        value as u64
13065    }
13066}
13067
13068impl Embed<W8, W56> {
13069    /// Embed a `u8` value at W8 into a `u64` value at W56.
13070    #[inline]
13071    #[must_use]
13072    pub const fn apply(value: u8) -> u64 {
13073        value as u64
13074    }
13075}
13076
13077impl Embed<W8, W64> {
13078    /// Embed a `u8` value at W8 into a `u64` value at W64.
13079    #[inline]
13080    #[must_use]
13081    pub const fn apply(value: u8) -> u64 {
13082        value as u64
13083    }
13084}
13085
13086impl Embed<W8, W72> {
13087    /// Embed a `u8` value at W8 into a `u128` value at W72.
13088    #[inline]
13089    #[must_use]
13090    pub const fn apply(value: u8) -> u128 {
13091        value as u128
13092    }
13093}
13094
13095impl Embed<W8, W80> {
13096    /// Embed a `u8` value at W8 into a `u128` value at W80.
13097    #[inline]
13098    #[must_use]
13099    pub const fn apply(value: u8) -> u128 {
13100        value as u128
13101    }
13102}
13103
13104impl Embed<W8, W88> {
13105    /// Embed a `u8` value at W8 into a `u128` value at W88.
13106    #[inline]
13107    #[must_use]
13108    pub const fn apply(value: u8) -> u128 {
13109        value as u128
13110    }
13111}
13112
13113impl Embed<W8, W96> {
13114    /// Embed a `u8` value at W8 into a `u128` value at W96.
13115    #[inline]
13116    #[must_use]
13117    pub const fn apply(value: u8) -> u128 {
13118        value as u128
13119    }
13120}
13121
13122impl Embed<W8, W104> {
13123    /// Embed a `u8` value at W8 into a `u128` value at W104.
13124    #[inline]
13125    #[must_use]
13126    pub const fn apply(value: u8) -> u128 {
13127        value as u128
13128    }
13129}
13130
13131impl Embed<W8, W112> {
13132    /// Embed a `u8` value at W8 into a `u128` value at W112.
13133    #[inline]
13134    #[must_use]
13135    pub const fn apply(value: u8) -> u128 {
13136        value as u128
13137    }
13138}
13139
13140impl Embed<W8, W120> {
13141    /// Embed a `u8` value at W8 into a `u128` value at W120.
13142    #[inline]
13143    #[must_use]
13144    pub const fn apply(value: u8) -> u128 {
13145        value as u128
13146    }
13147}
13148
13149impl Embed<W8, W128> {
13150    /// Embed a `u8` value at W8 into a `u128` value at W128.
13151    #[inline]
13152    #[must_use]
13153    pub const fn apply(value: u8) -> u128 {
13154        value as u128
13155    }
13156}
13157
13158impl Embed<W16, W16> {
13159    /// Embed a `u16` value at W16 into a `u16` value at W16.
13160    #[inline]
13161    #[must_use]
13162    pub const fn apply(value: u16) -> u16 {
13163        value
13164    }
13165}
13166
13167impl Embed<W16, W24> {
13168    /// Embed a `u16` value at W16 into a `u32` value at W24.
13169    #[inline]
13170    #[must_use]
13171    pub const fn apply(value: u16) -> u32 {
13172        value as u32
13173    }
13174}
13175
13176impl Embed<W16, W32> {
13177    /// Embed a `u16` value at W16 into a `u32` value at W32.
13178    #[inline]
13179    #[must_use]
13180    pub const fn apply(value: u16) -> u32 {
13181        value as u32
13182    }
13183}
13184
13185impl Embed<W16, W40> {
13186    /// Embed a `u16` value at W16 into a `u64` value at W40.
13187    #[inline]
13188    #[must_use]
13189    pub const fn apply(value: u16) -> u64 {
13190        value as u64
13191    }
13192}
13193
13194impl Embed<W16, W48> {
13195    /// Embed a `u16` value at W16 into a `u64` value at W48.
13196    #[inline]
13197    #[must_use]
13198    pub const fn apply(value: u16) -> u64 {
13199        value as u64
13200    }
13201}
13202
13203impl Embed<W16, W56> {
13204    /// Embed a `u16` value at W16 into a `u64` value at W56.
13205    #[inline]
13206    #[must_use]
13207    pub const fn apply(value: u16) -> u64 {
13208        value as u64
13209    }
13210}
13211
13212impl Embed<W16, W64> {
13213    /// Embed a `u16` value at W16 into a `u64` value at W64.
13214    #[inline]
13215    #[must_use]
13216    pub const fn apply(value: u16) -> u64 {
13217        value as u64
13218    }
13219}
13220
13221impl Embed<W16, W72> {
13222    /// Embed a `u16` value at W16 into a `u128` value at W72.
13223    #[inline]
13224    #[must_use]
13225    pub const fn apply(value: u16) -> u128 {
13226        value as u128
13227    }
13228}
13229
13230impl Embed<W16, W80> {
13231    /// Embed a `u16` value at W16 into a `u128` value at W80.
13232    #[inline]
13233    #[must_use]
13234    pub const fn apply(value: u16) -> u128 {
13235        value as u128
13236    }
13237}
13238
13239impl Embed<W16, W88> {
13240    /// Embed a `u16` value at W16 into a `u128` value at W88.
13241    #[inline]
13242    #[must_use]
13243    pub const fn apply(value: u16) -> u128 {
13244        value as u128
13245    }
13246}
13247
13248impl Embed<W16, W96> {
13249    /// Embed a `u16` value at W16 into a `u128` value at W96.
13250    #[inline]
13251    #[must_use]
13252    pub const fn apply(value: u16) -> u128 {
13253        value as u128
13254    }
13255}
13256
13257impl Embed<W16, W104> {
13258    /// Embed a `u16` value at W16 into a `u128` value at W104.
13259    #[inline]
13260    #[must_use]
13261    pub const fn apply(value: u16) -> u128 {
13262        value as u128
13263    }
13264}
13265
13266impl Embed<W16, W112> {
13267    /// Embed a `u16` value at W16 into a `u128` value at W112.
13268    #[inline]
13269    #[must_use]
13270    pub const fn apply(value: u16) -> u128 {
13271        value as u128
13272    }
13273}
13274
13275impl Embed<W16, W120> {
13276    /// Embed a `u16` value at W16 into a `u128` value at W120.
13277    #[inline]
13278    #[must_use]
13279    pub const fn apply(value: u16) -> u128 {
13280        value as u128
13281    }
13282}
13283
13284impl Embed<W16, W128> {
13285    /// Embed a `u16` value at W16 into a `u128` value at W128.
13286    #[inline]
13287    #[must_use]
13288    pub const fn apply(value: u16) -> u128 {
13289        value as u128
13290    }
13291}
13292
13293impl Embed<W24, W24> {
13294    /// Embed a `u32` value at W24 into a `u32` value at W24.
13295    #[inline]
13296    #[must_use]
13297    pub const fn apply(value: u32) -> u32 {
13298        value
13299    }
13300}
13301
13302impl Embed<W24, W32> {
13303    /// Embed a `u32` value at W24 into a `u32` value at W32.
13304    #[inline]
13305    #[must_use]
13306    pub const fn apply(value: u32) -> u32 {
13307        value
13308    }
13309}
13310
13311impl Embed<W24, W40> {
13312    /// Embed a `u32` value at W24 into a `u64` value at W40.
13313    #[inline]
13314    #[must_use]
13315    pub const fn apply(value: u32) -> u64 {
13316        value as u64
13317    }
13318}
13319
13320impl Embed<W24, W48> {
13321    /// Embed a `u32` value at W24 into a `u64` value at W48.
13322    #[inline]
13323    #[must_use]
13324    pub const fn apply(value: u32) -> u64 {
13325        value as u64
13326    }
13327}
13328
13329impl Embed<W24, W56> {
13330    /// Embed a `u32` value at W24 into a `u64` value at W56.
13331    #[inline]
13332    #[must_use]
13333    pub const fn apply(value: u32) -> u64 {
13334        value as u64
13335    }
13336}
13337
13338impl Embed<W24, W64> {
13339    /// Embed a `u32` value at W24 into a `u64` value at W64.
13340    #[inline]
13341    #[must_use]
13342    pub const fn apply(value: u32) -> u64 {
13343        value as u64
13344    }
13345}
13346
13347impl Embed<W24, W72> {
13348    /// Embed a `u32` value at W24 into a `u128` value at W72.
13349    #[inline]
13350    #[must_use]
13351    pub const fn apply(value: u32) -> u128 {
13352        value as u128
13353    }
13354}
13355
13356impl Embed<W24, W80> {
13357    /// Embed a `u32` value at W24 into a `u128` value at W80.
13358    #[inline]
13359    #[must_use]
13360    pub const fn apply(value: u32) -> u128 {
13361        value as u128
13362    }
13363}
13364
13365impl Embed<W24, W88> {
13366    /// Embed a `u32` value at W24 into a `u128` value at W88.
13367    #[inline]
13368    #[must_use]
13369    pub const fn apply(value: u32) -> u128 {
13370        value as u128
13371    }
13372}
13373
13374impl Embed<W24, W96> {
13375    /// Embed a `u32` value at W24 into a `u128` value at W96.
13376    #[inline]
13377    #[must_use]
13378    pub const fn apply(value: u32) -> u128 {
13379        value as u128
13380    }
13381}
13382
13383impl Embed<W24, W104> {
13384    /// Embed a `u32` value at W24 into a `u128` value at W104.
13385    #[inline]
13386    #[must_use]
13387    pub const fn apply(value: u32) -> u128 {
13388        value as u128
13389    }
13390}
13391
13392impl Embed<W24, W112> {
13393    /// Embed a `u32` value at W24 into a `u128` value at W112.
13394    #[inline]
13395    #[must_use]
13396    pub const fn apply(value: u32) -> u128 {
13397        value as u128
13398    }
13399}
13400
13401impl Embed<W24, W120> {
13402    /// Embed a `u32` value at W24 into a `u128` value at W120.
13403    #[inline]
13404    #[must_use]
13405    pub const fn apply(value: u32) -> u128 {
13406        value as u128
13407    }
13408}
13409
13410impl Embed<W24, W128> {
13411    /// Embed a `u32` value at W24 into a `u128` value at W128.
13412    #[inline]
13413    #[must_use]
13414    pub const fn apply(value: u32) -> u128 {
13415        value as u128
13416    }
13417}
13418
13419impl Embed<W32, W32> {
13420    /// Embed a `u32` value at W32 into a `u32` value at W32.
13421    #[inline]
13422    #[must_use]
13423    pub const fn apply(value: u32) -> u32 {
13424        value
13425    }
13426}
13427
13428impl Embed<W32, W40> {
13429    /// Embed a `u32` value at W32 into a `u64` value at W40.
13430    #[inline]
13431    #[must_use]
13432    pub const fn apply(value: u32) -> u64 {
13433        value as u64
13434    }
13435}
13436
13437impl Embed<W32, W48> {
13438    /// Embed a `u32` value at W32 into a `u64` value at W48.
13439    #[inline]
13440    #[must_use]
13441    pub const fn apply(value: u32) -> u64 {
13442        value as u64
13443    }
13444}
13445
13446impl Embed<W32, W56> {
13447    /// Embed a `u32` value at W32 into a `u64` value at W56.
13448    #[inline]
13449    #[must_use]
13450    pub const fn apply(value: u32) -> u64 {
13451        value as u64
13452    }
13453}
13454
13455impl Embed<W32, W64> {
13456    /// Embed a `u32` value at W32 into a `u64` value at W64.
13457    #[inline]
13458    #[must_use]
13459    pub const fn apply(value: u32) -> u64 {
13460        value as u64
13461    }
13462}
13463
13464impl Embed<W32, W72> {
13465    /// Embed a `u32` value at W32 into a `u128` value at W72.
13466    #[inline]
13467    #[must_use]
13468    pub const fn apply(value: u32) -> u128 {
13469        value as u128
13470    }
13471}
13472
13473impl Embed<W32, W80> {
13474    /// Embed a `u32` value at W32 into a `u128` value at W80.
13475    #[inline]
13476    #[must_use]
13477    pub const fn apply(value: u32) -> u128 {
13478        value as u128
13479    }
13480}
13481
13482impl Embed<W32, W88> {
13483    /// Embed a `u32` value at W32 into a `u128` value at W88.
13484    #[inline]
13485    #[must_use]
13486    pub const fn apply(value: u32) -> u128 {
13487        value as u128
13488    }
13489}
13490
13491impl Embed<W32, W96> {
13492    /// Embed a `u32` value at W32 into a `u128` value at W96.
13493    #[inline]
13494    #[must_use]
13495    pub const fn apply(value: u32) -> u128 {
13496        value as u128
13497    }
13498}
13499
13500impl Embed<W32, W104> {
13501    /// Embed a `u32` value at W32 into a `u128` value at W104.
13502    #[inline]
13503    #[must_use]
13504    pub const fn apply(value: u32) -> u128 {
13505        value as u128
13506    }
13507}
13508
13509impl Embed<W32, W112> {
13510    /// Embed a `u32` value at W32 into a `u128` value at W112.
13511    #[inline]
13512    #[must_use]
13513    pub const fn apply(value: u32) -> u128 {
13514        value as u128
13515    }
13516}
13517
13518impl Embed<W32, W120> {
13519    /// Embed a `u32` value at W32 into a `u128` value at W120.
13520    #[inline]
13521    #[must_use]
13522    pub const fn apply(value: u32) -> u128 {
13523        value as u128
13524    }
13525}
13526
13527impl Embed<W32, W128> {
13528    /// Embed a `u32` value at W32 into a `u128` value at W128.
13529    #[inline]
13530    #[must_use]
13531    pub const fn apply(value: u32) -> u128 {
13532        value as u128
13533    }
13534}
13535
13536impl Embed<W40, W40> {
13537    /// Embed a `u64` value at W40 into a `u64` value at W40.
13538    #[inline]
13539    #[must_use]
13540    pub const fn apply(value: u64) -> u64 {
13541        value
13542    }
13543}
13544
13545impl Embed<W40, W48> {
13546    /// Embed a `u64` value at W40 into a `u64` value at W48.
13547    #[inline]
13548    #[must_use]
13549    pub const fn apply(value: u64) -> u64 {
13550        value
13551    }
13552}
13553
13554impl Embed<W40, W56> {
13555    /// Embed a `u64` value at W40 into a `u64` value at W56.
13556    #[inline]
13557    #[must_use]
13558    pub const fn apply(value: u64) -> u64 {
13559        value
13560    }
13561}
13562
13563impl Embed<W40, W64> {
13564    /// Embed a `u64` value at W40 into a `u64` value at W64.
13565    #[inline]
13566    #[must_use]
13567    pub const fn apply(value: u64) -> u64 {
13568        value
13569    }
13570}
13571
13572impl Embed<W40, W72> {
13573    /// Embed a `u64` value at W40 into a `u128` value at W72.
13574    #[inline]
13575    #[must_use]
13576    pub const fn apply(value: u64) -> u128 {
13577        value as u128
13578    }
13579}
13580
13581impl Embed<W40, W80> {
13582    /// Embed a `u64` value at W40 into a `u128` value at W80.
13583    #[inline]
13584    #[must_use]
13585    pub const fn apply(value: u64) -> u128 {
13586        value as u128
13587    }
13588}
13589
13590impl Embed<W40, W88> {
13591    /// Embed a `u64` value at W40 into a `u128` value at W88.
13592    #[inline]
13593    #[must_use]
13594    pub const fn apply(value: u64) -> u128 {
13595        value as u128
13596    }
13597}
13598
13599impl Embed<W40, W96> {
13600    /// Embed a `u64` value at W40 into a `u128` value at W96.
13601    #[inline]
13602    #[must_use]
13603    pub const fn apply(value: u64) -> u128 {
13604        value as u128
13605    }
13606}
13607
13608impl Embed<W40, W104> {
13609    /// Embed a `u64` value at W40 into a `u128` value at W104.
13610    #[inline]
13611    #[must_use]
13612    pub const fn apply(value: u64) -> u128 {
13613        value as u128
13614    }
13615}
13616
13617impl Embed<W40, W112> {
13618    /// Embed a `u64` value at W40 into a `u128` value at W112.
13619    #[inline]
13620    #[must_use]
13621    pub const fn apply(value: u64) -> u128 {
13622        value as u128
13623    }
13624}
13625
13626impl Embed<W40, W120> {
13627    /// Embed a `u64` value at W40 into a `u128` value at W120.
13628    #[inline]
13629    #[must_use]
13630    pub const fn apply(value: u64) -> u128 {
13631        value as u128
13632    }
13633}
13634
13635impl Embed<W40, W128> {
13636    /// Embed a `u64` value at W40 into a `u128` value at W128.
13637    #[inline]
13638    #[must_use]
13639    pub const fn apply(value: u64) -> u128 {
13640        value as u128
13641    }
13642}
13643
13644impl Embed<W48, W48> {
13645    /// Embed a `u64` value at W48 into a `u64` value at W48.
13646    #[inline]
13647    #[must_use]
13648    pub const fn apply(value: u64) -> u64 {
13649        value
13650    }
13651}
13652
13653impl Embed<W48, W56> {
13654    /// Embed a `u64` value at W48 into a `u64` value at W56.
13655    #[inline]
13656    #[must_use]
13657    pub const fn apply(value: u64) -> u64 {
13658        value
13659    }
13660}
13661
13662impl Embed<W48, W64> {
13663    /// Embed a `u64` value at W48 into a `u64` value at W64.
13664    #[inline]
13665    #[must_use]
13666    pub const fn apply(value: u64) -> u64 {
13667        value
13668    }
13669}
13670
13671impl Embed<W48, W72> {
13672    /// Embed a `u64` value at W48 into a `u128` value at W72.
13673    #[inline]
13674    #[must_use]
13675    pub const fn apply(value: u64) -> u128 {
13676        value as u128
13677    }
13678}
13679
13680impl Embed<W48, W80> {
13681    /// Embed a `u64` value at W48 into a `u128` value at W80.
13682    #[inline]
13683    #[must_use]
13684    pub const fn apply(value: u64) -> u128 {
13685        value as u128
13686    }
13687}
13688
13689impl Embed<W48, W88> {
13690    /// Embed a `u64` value at W48 into a `u128` value at W88.
13691    #[inline]
13692    #[must_use]
13693    pub const fn apply(value: u64) -> u128 {
13694        value as u128
13695    }
13696}
13697
13698impl Embed<W48, W96> {
13699    /// Embed a `u64` value at W48 into a `u128` value at W96.
13700    #[inline]
13701    #[must_use]
13702    pub const fn apply(value: u64) -> u128 {
13703        value as u128
13704    }
13705}
13706
13707impl Embed<W48, W104> {
13708    /// Embed a `u64` value at W48 into a `u128` value at W104.
13709    #[inline]
13710    #[must_use]
13711    pub const fn apply(value: u64) -> u128 {
13712        value as u128
13713    }
13714}
13715
13716impl Embed<W48, W112> {
13717    /// Embed a `u64` value at W48 into a `u128` value at W112.
13718    #[inline]
13719    #[must_use]
13720    pub const fn apply(value: u64) -> u128 {
13721        value as u128
13722    }
13723}
13724
13725impl Embed<W48, W120> {
13726    /// Embed a `u64` value at W48 into a `u128` value at W120.
13727    #[inline]
13728    #[must_use]
13729    pub const fn apply(value: u64) -> u128 {
13730        value as u128
13731    }
13732}
13733
13734impl Embed<W48, W128> {
13735    /// Embed a `u64` value at W48 into a `u128` value at W128.
13736    #[inline]
13737    #[must_use]
13738    pub const fn apply(value: u64) -> u128 {
13739        value as u128
13740    }
13741}
13742
13743impl Embed<W56, W56> {
13744    /// Embed a `u64` value at W56 into a `u64` value at W56.
13745    #[inline]
13746    #[must_use]
13747    pub const fn apply(value: u64) -> u64 {
13748        value
13749    }
13750}
13751
13752impl Embed<W56, W64> {
13753    /// Embed a `u64` value at W56 into a `u64` value at W64.
13754    #[inline]
13755    #[must_use]
13756    pub const fn apply(value: u64) -> u64 {
13757        value
13758    }
13759}
13760
13761impl Embed<W56, W72> {
13762    /// Embed a `u64` value at W56 into a `u128` value at W72.
13763    #[inline]
13764    #[must_use]
13765    pub const fn apply(value: u64) -> u128 {
13766        value as u128
13767    }
13768}
13769
13770impl Embed<W56, W80> {
13771    /// Embed a `u64` value at W56 into a `u128` value at W80.
13772    #[inline]
13773    #[must_use]
13774    pub const fn apply(value: u64) -> u128 {
13775        value as u128
13776    }
13777}
13778
13779impl Embed<W56, W88> {
13780    /// Embed a `u64` value at W56 into a `u128` value at W88.
13781    #[inline]
13782    #[must_use]
13783    pub const fn apply(value: u64) -> u128 {
13784        value as u128
13785    }
13786}
13787
13788impl Embed<W56, W96> {
13789    /// Embed a `u64` value at W56 into a `u128` value at W96.
13790    #[inline]
13791    #[must_use]
13792    pub const fn apply(value: u64) -> u128 {
13793        value as u128
13794    }
13795}
13796
13797impl Embed<W56, W104> {
13798    /// Embed a `u64` value at W56 into a `u128` value at W104.
13799    #[inline]
13800    #[must_use]
13801    pub const fn apply(value: u64) -> u128 {
13802        value as u128
13803    }
13804}
13805
13806impl Embed<W56, W112> {
13807    /// Embed a `u64` value at W56 into a `u128` value at W112.
13808    #[inline]
13809    #[must_use]
13810    pub const fn apply(value: u64) -> u128 {
13811        value as u128
13812    }
13813}
13814
13815impl Embed<W56, W120> {
13816    /// Embed a `u64` value at W56 into a `u128` value at W120.
13817    #[inline]
13818    #[must_use]
13819    pub const fn apply(value: u64) -> u128 {
13820        value as u128
13821    }
13822}
13823
13824impl Embed<W56, W128> {
13825    /// Embed a `u64` value at W56 into a `u128` value at W128.
13826    #[inline]
13827    #[must_use]
13828    pub const fn apply(value: u64) -> u128 {
13829        value as u128
13830    }
13831}
13832
13833impl Embed<W64, W64> {
13834    /// Embed a `u64` value at W64 into a `u64` value at W64.
13835    #[inline]
13836    #[must_use]
13837    pub const fn apply(value: u64) -> u64 {
13838        value
13839    }
13840}
13841
13842impl Embed<W64, W72> {
13843    /// Embed a `u64` value at W64 into a `u128` value at W72.
13844    #[inline]
13845    #[must_use]
13846    pub const fn apply(value: u64) -> u128 {
13847        value as u128
13848    }
13849}
13850
13851impl Embed<W64, W80> {
13852    /// Embed a `u64` value at W64 into a `u128` value at W80.
13853    #[inline]
13854    #[must_use]
13855    pub const fn apply(value: u64) -> u128 {
13856        value as u128
13857    }
13858}
13859
13860impl Embed<W64, W88> {
13861    /// Embed a `u64` value at W64 into a `u128` value at W88.
13862    #[inline]
13863    #[must_use]
13864    pub const fn apply(value: u64) -> u128 {
13865        value as u128
13866    }
13867}
13868
13869impl Embed<W64, W96> {
13870    /// Embed a `u64` value at W64 into a `u128` value at W96.
13871    #[inline]
13872    #[must_use]
13873    pub const fn apply(value: u64) -> u128 {
13874        value as u128
13875    }
13876}
13877
13878impl Embed<W64, W104> {
13879    /// Embed a `u64` value at W64 into a `u128` value at W104.
13880    #[inline]
13881    #[must_use]
13882    pub const fn apply(value: u64) -> u128 {
13883        value as u128
13884    }
13885}
13886
13887impl Embed<W64, W112> {
13888    /// Embed a `u64` value at W64 into a `u128` value at W112.
13889    #[inline]
13890    #[must_use]
13891    pub const fn apply(value: u64) -> u128 {
13892        value as u128
13893    }
13894}
13895
13896impl Embed<W64, W120> {
13897    /// Embed a `u64` value at W64 into a `u128` value at W120.
13898    #[inline]
13899    #[must_use]
13900    pub const fn apply(value: u64) -> u128 {
13901        value as u128
13902    }
13903}
13904
13905impl Embed<W64, W128> {
13906    /// Embed a `u64` value at W64 into a `u128` value at W128.
13907    #[inline]
13908    #[must_use]
13909    pub const fn apply(value: u64) -> u128 {
13910        value as u128
13911    }
13912}
13913
13914impl Embed<W72, W72> {
13915    /// Embed a `u128` value at W72 into a `u128` value at W72.
13916    #[inline]
13917    #[must_use]
13918    pub const fn apply(value: u128) -> u128 {
13919        value
13920    }
13921}
13922
13923impl Embed<W72, W80> {
13924    /// Embed a `u128` value at W72 into a `u128` value at W80.
13925    #[inline]
13926    #[must_use]
13927    pub const fn apply(value: u128) -> u128 {
13928        value
13929    }
13930}
13931
13932impl Embed<W72, W88> {
13933    /// Embed a `u128` value at W72 into a `u128` value at W88.
13934    #[inline]
13935    #[must_use]
13936    pub const fn apply(value: u128) -> u128 {
13937        value
13938    }
13939}
13940
13941impl Embed<W72, W96> {
13942    /// Embed a `u128` value at W72 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<W72, W104> {
13951    /// Embed a `u128` value at W72 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<W72, W112> {
13960    /// Embed a `u128` value at W72 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<W72, W120> {
13969    /// Embed a `u128` value at W72 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<W72, W128> {
13978    /// Embed a `u128` value at W72 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<W80, W80> {
13987    /// Embed a `u128` value at W80 into a `u128` value at W80.
13988    #[inline]
13989    #[must_use]
13990    pub const fn apply(value: u128) -> u128 {
13991        value
13992    }
13993}
13994
13995impl Embed<W80, W88> {
13996    /// Embed a `u128` value at W80 into a `u128` value at W88.
13997    #[inline]
13998    #[must_use]
13999    pub const fn apply(value: u128) -> u128 {
14000        value
14001    }
14002}
14003
14004impl Embed<W80, W96> {
14005    /// Embed a `u128` value at W80 into a `u128` value at W96.
14006    #[inline]
14007    #[must_use]
14008    pub const fn apply(value: u128) -> u128 {
14009        value
14010    }
14011}
14012
14013impl Embed<W80, W104> {
14014    /// Embed a `u128` value at W80 into a `u128` value at W104.
14015    #[inline]
14016    #[must_use]
14017    pub const fn apply(value: u128) -> u128 {
14018        value
14019    }
14020}
14021
14022impl Embed<W80, W112> {
14023    /// Embed a `u128` value at W80 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<W80, W120> {
14032    /// Embed a `u128` value at W80 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<W80, W128> {
14041    /// Embed a `u128` value at W80 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<W88, W88> {
14050    /// Embed a `u128` value at W88 into a `u128` value at W88.
14051    #[inline]
14052    #[must_use]
14053    pub const fn apply(value: u128) -> u128 {
14054        value
14055    }
14056}
14057
14058impl Embed<W88, W96> {
14059    /// Embed a `u128` value at W88 into a `u128` value at W96.
14060    #[inline]
14061    #[must_use]
14062    pub const fn apply(value: u128) -> u128 {
14063        value
14064    }
14065}
14066
14067impl Embed<W88, W104> {
14068    /// Embed a `u128` value at W88 into a `u128` value at W104.
14069    #[inline]
14070    #[must_use]
14071    pub const fn apply(value: u128) -> u128 {
14072        value
14073    }
14074}
14075
14076impl Embed<W88, W112> {
14077    /// Embed a `u128` value at W88 into a `u128` value at W112.
14078    #[inline]
14079    #[must_use]
14080    pub const fn apply(value: u128) -> u128 {
14081        value
14082    }
14083}
14084
14085impl Embed<W88, W120> {
14086    /// Embed a `u128` value at W88 into a `u128` value at W120.
14087    #[inline]
14088    #[must_use]
14089    pub const fn apply(value: u128) -> u128 {
14090        value
14091    }
14092}
14093
14094impl Embed<W88, W128> {
14095    /// Embed a `u128` value at W88 into a `u128` value at W128.
14096    #[inline]
14097    #[must_use]
14098    pub const fn apply(value: u128) -> u128 {
14099        value
14100    }
14101}
14102
14103impl Embed<W96, W96> {
14104    /// Embed a `u128` value at W96 into a `u128` value at W96.
14105    #[inline]
14106    #[must_use]
14107    pub const fn apply(value: u128) -> u128 {
14108        value
14109    }
14110}
14111
14112impl Embed<W96, W104> {
14113    /// Embed a `u128` value at W96 into a `u128` value at W104.
14114    #[inline]
14115    #[must_use]
14116    pub const fn apply(value: u128) -> u128 {
14117        value
14118    }
14119}
14120
14121impl Embed<W96, W112> {
14122    /// Embed a `u128` value at W96 into a `u128` value at W112.
14123    #[inline]
14124    #[must_use]
14125    pub const fn apply(value: u128) -> u128 {
14126        value
14127    }
14128}
14129
14130impl Embed<W96, W120> {
14131    /// Embed a `u128` value at W96 into a `u128` value at W120.
14132    #[inline]
14133    #[must_use]
14134    pub const fn apply(value: u128) -> u128 {
14135        value
14136    }
14137}
14138
14139impl Embed<W96, W128> {
14140    /// Embed a `u128` value at W96 into a `u128` value at W128.
14141    #[inline]
14142    #[must_use]
14143    pub const fn apply(value: u128) -> u128 {
14144        value
14145    }
14146}
14147
14148impl Embed<W104, W104> {
14149    /// Embed a `u128` value at W104 into a `u128` value at W104.
14150    #[inline]
14151    #[must_use]
14152    pub const fn apply(value: u128) -> u128 {
14153        value
14154    }
14155}
14156
14157impl Embed<W104, W112> {
14158    /// Embed a `u128` value at W104 into a `u128` value at W112.
14159    #[inline]
14160    #[must_use]
14161    pub const fn apply(value: u128) -> u128 {
14162        value
14163    }
14164}
14165
14166impl Embed<W104, W120> {
14167    /// Embed a `u128` value at W104 into a `u128` value at W120.
14168    #[inline]
14169    #[must_use]
14170    pub const fn apply(value: u128) -> u128 {
14171        value
14172    }
14173}
14174
14175impl Embed<W104, W128> {
14176    /// Embed a `u128` value at W104 into a `u128` value at W128.
14177    #[inline]
14178    #[must_use]
14179    pub const fn apply(value: u128) -> u128 {
14180        value
14181    }
14182}
14183
14184impl Embed<W112, W112> {
14185    /// Embed a `u128` value at W112 into a `u128` value at W112.
14186    #[inline]
14187    #[must_use]
14188    pub const fn apply(value: u128) -> u128 {
14189        value
14190    }
14191}
14192
14193impl Embed<W112, W120> {
14194    /// Embed a `u128` value at W112 into a `u128` value at W120.
14195    #[inline]
14196    #[must_use]
14197    pub const fn apply(value: u128) -> u128 {
14198        value
14199    }
14200}
14201
14202impl Embed<W112, W128> {
14203    /// Embed a `u128` value at W112 into a `u128` value at W128.
14204    #[inline]
14205    #[must_use]
14206    pub const fn apply(value: u128) -> u128 {
14207        value
14208    }
14209}
14210
14211impl Embed<W120, W120> {
14212    /// Embed a `u128` value at W120 into a `u128` value at W120.
14213    #[inline]
14214    #[must_use]
14215    pub const fn apply(value: u128) -> u128 {
14216        value
14217    }
14218}
14219
14220impl Embed<W120, W128> {
14221    /// Embed a `u128` value at W120 into a `u128` value at W128.
14222    #[inline]
14223    #[must_use]
14224    pub const fn apply(value: u128) -> u128 {
14225        value
14226    }
14227}
14228
14229impl Embed<W128, W128> {
14230    /// Embed a `u128` value at W128 into a `u128` value at W128.
14231    #[inline]
14232    #[must_use]
14233    pub const fn apply(value: u128) -> u128 {
14234        value
14235    }
14236}
14237
14238/// v0.2.2 Phase C.3: marker structs for Limbs-backed Witt levels.
14239/// Each level binds a const-generic `Limbs<N>` width at the type level.
14240/// W160 marker — 160-bit Witt level, Limbs-backed.
14241#[derive(Debug, Default, Clone, Copy)]
14242pub struct W160;
14243
14244/// W192 marker — 192-bit Witt level, Limbs-backed.
14245#[derive(Debug, Default, Clone, Copy)]
14246pub struct W192;
14247
14248/// W224 marker — 224-bit Witt level, Limbs-backed.
14249#[derive(Debug, Default, Clone, Copy)]
14250pub struct W224;
14251
14252/// W256 marker — 256-bit Witt level, Limbs-backed.
14253#[derive(Debug, Default, Clone, Copy)]
14254pub struct W256;
14255
14256/// W384 marker — 384-bit Witt level, Limbs-backed.
14257#[derive(Debug, Default, Clone, Copy)]
14258pub struct W384;
14259
14260/// W448 marker — 448-bit Witt level, Limbs-backed.
14261#[derive(Debug, Default, Clone, Copy)]
14262pub struct W448;
14263
14264/// W512 marker — 512-bit Witt level, Limbs-backed.
14265#[derive(Debug, Default, Clone, Copy)]
14266pub struct W512;
14267
14268/// W520 marker — 520-bit Witt level, Limbs-backed.
14269#[derive(Debug, Default, Clone, Copy)]
14270pub struct W520;
14271
14272/// W528 marker — 528-bit Witt level, Limbs-backed.
14273#[derive(Debug, Default, Clone, Copy)]
14274pub struct W528;
14275
14276/// W1024 marker — 1024-bit Witt level, Limbs-backed.
14277#[derive(Debug, Default, Clone, Copy)]
14278pub struct W1024;
14279
14280/// W2048 marker — 2048-bit Witt level, Limbs-backed.
14281#[derive(Debug, Default, Clone, Copy)]
14282pub struct W2048;
14283
14284/// W4096 marker — 4096-bit Witt level, Limbs-backed.
14285#[derive(Debug, Default, Clone, Copy)]
14286pub struct W4096;
14287
14288/// W8192 marker — 8192-bit Witt level, Limbs-backed.
14289#[derive(Debug, Default, Clone, Copy)]
14290pub struct W8192;
14291
14292/// W12288 marker — 12288-bit Witt level, Limbs-backed.
14293#[derive(Debug, Default, Clone, Copy)]
14294pub struct W12288;
14295
14296/// W16384 marker — 16384-bit Witt level, Limbs-backed.
14297#[derive(Debug, Default, Clone, Copy)]
14298pub struct W16384;
14299
14300/// W32768 marker — 32768-bit Witt level, Limbs-backed.
14301#[derive(Debug, Default, Clone, Copy)]
14302pub struct W32768;
14303
14304impl RingOp<W160> for Mul<W160> {
14305    type Operand = Limbs<3>;
14306    #[inline]
14307    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14308        a.wrapping_mul(b).mask_high_bits(160)
14309    }
14310}
14311
14312impl RingOp<W160> for Add<W160> {
14313    type Operand = Limbs<3>;
14314    #[inline]
14315    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14316        a.wrapping_add(b).mask_high_bits(160)
14317    }
14318}
14319
14320impl RingOp<W160> for Sub<W160> {
14321    type Operand = Limbs<3>;
14322    #[inline]
14323    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14324        a.wrapping_sub(b).mask_high_bits(160)
14325    }
14326}
14327
14328impl RingOp<W160> for Xor<W160> {
14329    type Operand = Limbs<3>;
14330    #[inline]
14331    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14332        a.xor(b).mask_high_bits(160)
14333    }
14334}
14335
14336impl RingOp<W160> for And<W160> {
14337    type Operand = Limbs<3>;
14338    #[inline]
14339    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14340        a.and(b).mask_high_bits(160)
14341    }
14342}
14343
14344impl RingOp<W160> for Or<W160> {
14345    type Operand = Limbs<3>;
14346    #[inline]
14347    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14348        a.or(b).mask_high_bits(160)
14349    }
14350}
14351
14352impl UnaryRingOp<W160> for Neg<W160> {
14353    type Operand = Limbs<3>;
14354    #[inline]
14355    fn apply(a: Limbs<3>) -> Limbs<3> {
14356        (Limbs::<3>::zero().wrapping_sub(a)).mask_high_bits(160)
14357    }
14358}
14359
14360impl UnaryRingOp<W160> for BNot<W160> {
14361    type Operand = Limbs<3>;
14362    #[inline]
14363    fn apply(a: Limbs<3>) -> Limbs<3> {
14364        (a.not()).mask_high_bits(160)
14365    }
14366}
14367
14368impl UnaryRingOp<W160> for Succ<W160> {
14369    type Operand = Limbs<3>;
14370    #[inline]
14371    fn apply(a: Limbs<3>) -> Limbs<3> {
14372        (a.wrapping_add(Limbs::<3>::from_words([1u64, 0u64, 0u64]))).mask_high_bits(160)
14373    }
14374}
14375
14376impl RingOp<W192> for Mul<W192> {
14377    type Operand = Limbs<3>;
14378    #[inline]
14379    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14380        a.wrapping_mul(b)
14381    }
14382}
14383
14384impl RingOp<W192> for Add<W192> {
14385    type Operand = Limbs<3>;
14386    #[inline]
14387    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14388        a.wrapping_add(b)
14389    }
14390}
14391
14392impl RingOp<W192> for Sub<W192> {
14393    type Operand = Limbs<3>;
14394    #[inline]
14395    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14396        a.wrapping_sub(b)
14397    }
14398}
14399
14400impl RingOp<W192> for Xor<W192> {
14401    type Operand = Limbs<3>;
14402    #[inline]
14403    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14404        a.xor(b)
14405    }
14406}
14407
14408impl RingOp<W192> for And<W192> {
14409    type Operand = Limbs<3>;
14410    #[inline]
14411    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14412        a.and(b)
14413    }
14414}
14415
14416impl RingOp<W192> for Or<W192> {
14417    type Operand = Limbs<3>;
14418    #[inline]
14419    fn apply(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
14420        a.or(b)
14421    }
14422}
14423
14424impl UnaryRingOp<W192> for Neg<W192> {
14425    type Operand = Limbs<3>;
14426    #[inline]
14427    fn apply(a: Limbs<3>) -> Limbs<3> {
14428        Limbs::<3>::zero().wrapping_sub(a)
14429    }
14430}
14431
14432impl UnaryRingOp<W192> for BNot<W192> {
14433    type Operand = Limbs<3>;
14434    #[inline]
14435    fn apply(a: Limbs<3>) -> Limbs<3> {
14436        a.not()
14437    }
14438}
14439
14440impl UnaryRingOp<W192> for Succ<W192> {
14441    type Operand = Limbs<3>;
14442    #[inline]
14443    fn apply(a: Limbs<3>) -> Limbs<3> {
14444        a.wrapping_add(Limbs::<3>::from_words([1u64, 0u64, 0u64]))
14445    }
14446}
14447
14448impl RingOp<W224> for Mul<W224> {
14449    type Operand = Limbs<4>;
14450    #[inline]
14451    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14452        a.wrapping_mul(b).mask_high_bits(224)
14453    }
14454}
14455
14456impl RingOp<W224> for Add<W224> {
14457    type Operand = Limbs<4>;
14458    #[inline]
14459    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14460        a.wrapping_add(b).mask_high_bits(224)
14461    }
14462}
14463
14464impl RingOp<W224> for Sub<W224> {
14465    type Operand = Limbs<4>;
14466    #[inline]
14467    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14468        a.wrapping_sub(b).mask_high_bits(224)
14469    }
14470}
14471
14472impl RingOp<W224> for Xor<W224> {
14473    type Operand = Limbs<4>;
14474    #[inline]
14475    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14476        a.xor(b).mask_high_bits(224)
14477    }
14478}
14479
14480impl RingOp<W224> for And<W224> {
14481    type Operand = Limbs<4>;
14482    #[inline]
14483    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14484        a.and(b).mask_high_bits(224)
14485    }
14486}
14487
14488impl RingOp<W224> for Or<W224> {
14489    type Operand = Limbs<4>;
14490    #[inline]
14491    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14492        a.or(b).mask_high_bits(224)
14493    }
14494}
14495
14496impl UnaryRingOp<W224> for Neg<W224> {
14497    type Operand = Limbs<4>;
14498    #[inline]
14499    fn apply(a: Limbs<4>) -> Limbs<4> {
14500        (Limbs::<4>::zero().wrapping_sub(a)).mask_high_bits(224)
14501    }
14502}
14503
14504impl UnaryRingOp<W224> for BNot<W224> {
14505    type Operand = Limbs<4>;
14506    #[inline]
14507    fn apply(a: Limbs<4>) -> Limbs<4> {
14508        (a.not()).mask_high_bits(224)
14509    }
14510}
14511
14512impl UnaryRingOp<W224> for Succ<W224> {
14513    type Operand = Limbs<4>;
14514    #[inline]
14515    fn apply(a: Limbs<4>) -> Limbs<4> {
14516        (a.wrapping_add(Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64]))).mask_high_bits(224)
14517    }
14518}
14519
14520impl RingOp<W256> for Mul<W256> {
14521    type Operand = Limbs<4>;
14522    #[inline]
14523    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14524        a.wrapping_mul(b)
14525    }
14526}
14527
14528impl RingOp<W256> for Add<W256> {
14529    type Operand = Limbs<4>;
14530    #[inline]
14531    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14532        a.wrapping_add(b)
14533    }
14534}
14535
14536impl RingOp<W256> for Sub<W256> {
14537    type Operand = Limbs<4>;
14538    #[inline]
14539    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14540        a.wrapping_sub(b)
14541    }
14542}
14543
14544impl RingOp<W256> for Xor<W256> {
14545    type Operand = Limbs<4>;
14546    #[inline]
14547    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14548        a.xor(b)
14549    }
14550}
14551
14552impl RingOp<W256> for And<W256> {
14553    type Operand = Limbs<4>;
14554    #[inline]
14555    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14556        a.and(b)
14557    }
14558}
14559
14560impl RingOp<W256> for Or<W256> {
14561    type Operand = Limbs<4>;
14562    #[inline]
14563    fn apply(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
14564        a.or(b)
14565    }
14566}
14567
14568impl UnaryRingOp<W256> for Neg<W256> {
14569    type Operand = Limbs<4>;
14570    #[inline]
14571    fn apply(a: Limbs<4>) -> Limbs<4> {
14572        Limbs::<4>::zero().wrapping_sub(a)
14573    }
14574}
14575
14576impl UnaryRingOp<W256> for BNot<W256> {
14577    type Operand = Limbs<4>;
14578    #[inline]
14579    fn apply(a: Limbs<4>) -> Limbs<4> {
14580        a.not()
14581    }
14582}
14583
14584impl UnaryRingOp<W256> for Succ<W256> {
14585    type Operand = Limbs<4>;
14586    #[inline]
14587    fn apply(a: Limbs<4>) -> Limbs<4> {
14588        a.wrapping_add(Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64]))
14589    }
14590}
14591
14592impl RingOp<W384> for Mul<W384> {
14593    type Operand = Limbs<6>;
14594    #[inline]
14595    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14596        a.wrapping_mul(b)
14597    }
14598}
14599
14600impl RingOp<W384> for Add<W384> {
14601    type Operand = Limbs<6>;
14602    #[inline]
14603    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14604        a.wrapping_add(b)
14605    }
14606}
14607
14608impl RingOp<W384> for Sub<W384> {
14609    type Operand = Limbs<6>;
14610    #[inline]
14611    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14612        a.wrapping_sub(b)
14613    }
14614}
14615
14616impl RingOp<W384> for Xor<W384> {
14617    type Operand = Limbs<6>;
14618    #[inline]
14619    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14620        a.xor(b)
14621    }
14622}
14623
14624impl RingOp<W384> for And<W384> {
14625    type Operand = Limbs<6>;
14626    #[inline]
14627    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14628        a.and(b)
14629    }
14630}
14631
14632impl RingOp<W384> for Or<W384> {
14633    type Operand = Limbs<6>;
14634    #[inline]
14635    fn apply(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
14636        a.or(b)
14637    }
14638}
14639
14640impl UnaryRingOp<W384> for Neg<W384> {
14641    type Operand = Limbs<6>;
14642    #[inline]
14643    fn apply(a: Limbs<6>) -> Limbs<6> {
14644        Limbs::<6>::zero().wrapping_sub(a)
14645    }
14646}
14647
14648impl UnaryRingOp<W384> for BNot<W384> {
14649    type Operand = Limbs<6>;
14650    #[inline]
14651    fn apply(a: Limbs<6>) -> Limbs<6> {
14652        a.not()
14653    }
14654}
14655
14656impl UnaryRingOp<W384> for Succ<W384> {
14657    type Operand = Limbs<6>;
14658    #[inline]
14659    fn apply(a: Limbs<6>) -> Limbs<6> {
14660        a.wrapping_add(Limbs::<6>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64]))
14661    }
14662}
14663
14664impl RingOp<W448> for Mul<W448> {
14665    type Operand = Limbs<7>;
14666    #[inline]
14667    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14668        a.wrapping_mul(b)
14669    }
14670}
14671
14672impl RingOp<W448> for Add<W448> {
14673    type Operand = Limbs<7>;
14674    #[inline]
14675    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14676        a.wrapping_add(b)
14677    }
14678}
14679
14680impl RingOp<W448> for Sub<W448> {
14681    type Operand = Limbs<7>;
14682    #[inline]
14683    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14684        a.wrapping_sub(b)
14685    }
14686}
14687
14688impl RingOp<W448> for Xor<W448> {
14689    type Operand = Limbs<7>;
14690    #[inline]
14691    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14692        a.xor(b)
14693    }
14694}
14695
14696impl RingOp<W448> for And<W448> {
14697    type Operand = Limbs<7>;
14698    #[inline]
14699    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14700        a.and(b)
14701    }
14702}
14703
14704impl RingOp<W448> for Or<W448> {
14705    type Operand = Limbs<7>;
14706    #[inline]
14707    fn apply(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
14708        a.or(b)
14709    }
14710}
14711
14712impl UnaryRingOp<W448> for Neg<W448> {
14713    type Operand = Limbs<7>;
14714    #[inline]
14715    fn apply(a: Limbs<7>) -> Limbs<7> {
14716        Limbs::<7>::zero().wrapping_sub(a)
14717    }
14718}
14719
14720impl UnaryRingOp<W448> for BNot<W448> {
14721    type Operand = Limbs<7>;
14722    #[inline]
14723    fn apply(a: Limbs<7>) -> Limbs<7> {
14724        a.not()
14725    }
14726}
14727
14728impl UnaryRingOp<W448> for Succ<W448> {
14729    type Operand = Limbs<7>;
14730    #[inline]
14731    fn apply(a: Limbs<7>) -> Limbs<7> {
14732        a.wrapping_add(Limbs::<7>::from_words([
14733            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14734        ]))
14735    }
14736}
14737
14738impl RingOp<W512> for Mul<W512> {
14739    type Operand = Limbs<8>;
14740    #[inline]
14741    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14742        a.wrapping_mul(b)
14743    }
14744}
14745
14746impl RingOp<W512> for Add<W512> {
14747    type Operand = Limbs<8>;
14748    #[inline]
14749    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14750        a.wrapping_add(b)
14751    }
14752}
14753
14754impl RingOp<W512> for Sub<W512> {
14755    type Operand = Limbs<8>;
14756    #[inline]
14757    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14758        a.wrapping_sub(b)
14759    }
14760}
14761
14762impl RingOp<W512> for Xor<W512> {
14763    type Operand = Limbs<8>;
14764    #[inline]
14765    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14766        a.xor(b)
14767    }
14768}
14769
14770impl RingOp<W512> for And<W512> {
14771    type Operand = Limbs<8>;
14772    #[inline]
14773    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14774        a.and(b)
14775    }
14776}
14777
14778impl RingOp<W512> for Or<W512> {
14779    type Operand = Limbs<8>;
14780    #[inline]
14781    fn apply(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
14782        a.or(b)
14783    }
14784}
14785
14786impl UnaryRingOp<W512> for Neg<W512> {
14787    type Operand = Limbs<8>;
14788    #[inline]
14789    fn apply(a: Limbs<8>) -> Limbs<8> {
14790        Limbs::<8>::zero().wrapping_sub(a)
14791    }
14792}
14793
14794impl UnaryRingOp<W512> for BNot<W512> {
14795    type Operand = Limbs<8>;
14796    #[inline]
14797    fn apply(a: Limbs<8>) -> Limbs<8> {
14798        a.not()
14799    }
14800}
14801
14802impl UnaryRingOp<W512> for Succ<W512> {
14803    type Operand = Limbs<8>;
14804    #[inline]
14805    fn apply(a: Limbs<8>) -> Limbs<8> {
14806        a.wrapping_add(Limbs::<8>::from_words([
14807            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14808        ]))
14809    }
14810}
14811
14812impl RingOp<W520> for Mul<W520> {
14813    type Operand = Limbs<9>;
14814    #[inline]
14815    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14816        a.wrapping_mul(b).mask_high_bits(520)
14817    }
14818}
14819
14820impl RingOp<W520> for Add<W520> {
14821    type Operand = Limbs<9>;
14822    #[inline]
14823    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14824        a.wrapping_add(b).mask_high_bits(520)
14825    }
14826}
14827
14828impl RingOp<W520> for Sub<W520> {
14829    type Operand = Limbs<9>;
14830    #[inline]
14831    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14832        a.wrapping_sub(b).mask_high_bits(520)
14833    }
14834}
14835
14836impl RingOp<W520> for Xor<W520> {
14837    type Operand = Limbs<9>;
14838    #[inline]
14839    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14840        a.xor(b).mask_high_bits(520)
14841    }
14842}
14843
14844impl RingOp<W520> for And<W520> {
14845    type Operand = Limbs<9>;
14846    #[inline]
14847    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14848        a.and(b).mask_high_bits(520)
14849    }
14850}
14851
14852impl RingOp<W520> for Or<W520> {
14853    type Operand = Limbs<9>;
14854    #[inline]
14855    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14856        a.or(b).mask_high_bits(520)
14857    }
14858}
14859
14860impl UnaryRingOp<W520> for Neg<W520> {
14861    type Operand = Limbs<9>;
14862    #[inline]
14863    fn apply(a: Limbs<9>) -> Limbs<9> {
14864        (Limbs::<9>::zero().wrapping_sub(a)).mask_high_bits(520)
14865    }
14866}
14867
14868impl UnaryRingOp<W520> for BNot<W520> {
14869    type Operand = Limbs<9>;
14870    #[inline]
14871    fn apply(a: Limbs<9>) -> Limbs<9> {
14872        (a.not()).mask_high_bits(520)
14873    }
14874}
14875
14876impl UnaryRingOp<W520> for Succ<W520> {
14877    type Operand = Limbs<9>;
14878    #[inline]
14879    fn apply(a: Limbs<9>) -> Limbs<9> {
14880        (a.wrapping_add(Limbs::<9>::from_words([
14881            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14882        ])))
14883        .mask_high_bits(520)
14884    }
14885}
14886
14887impl RingOp<W528> for Mul<W528> {
14888    type Operand = Limbs<9>;
14889    #[inline]
14890    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14891        a.wrapping_mul(b).mask_high_bits(528)
14892    }
14893}
14894
14895impl RingOp<W528> for Add<W528> {
14896    type Operand = Limbs<9>;
14897    #[inline]
14898    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14899        a.wrapping_add(b).mask_high_bits(528)
14900    }
14901}
14902
14903impl RingOp<W528> for Sub<W528> {
14904    type Operand = Limbs<9>;
14905    #[inline]
14906    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14907        a.wrapping_sub(b).mask_high_bits(528)
14908    }
14909}
14910
14911impl RingOp<W528> for Xor<W528> {
14912    type Operand = Limbs<9>;
14913    #[inline]
14914    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14915        a.xor(b).mask_high_bits(528)
14916    }
14917}
14918
14919impl RingOp<W528> for And<W528> {
14920    type Operand = Limbs<9>;
14921    #[inline]
14922    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14923        a.and(b).mask_high_bits(528)
14924    }
14925}
14926
14927impl RingOp<W528> for Or<W528> {
14928    type Operand = Limbs<9>;
14929    #[inline]
14930    fn apply(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
14931        a.or(b).mask_high_bits(528)
14932    }
14933}
14934
14935impl UnaryRingOp<W528> for Neg<W528> {
14936    type Operand = Limbs<9>;
14937    #[inline]
14938    fn apply(a: Limbs<9>) -> Limbs<9> {
14939        (Limbs::<9>::zero().wrapping_sub(a)).mask_high_bits(528)
14940    }
14941}
14942
14943impl UnaryRingOp<W528> for BNot<W528> {
14944    type Operand = Limbs<9>;
14945    #[inline]
14946    fn apply(a: Limbs<9>) -> Limbs<9> {
14947        (a.not()).mask_high_bits(528)
14948    }
14949}
14950
14951impl UnaryRingOp<W528> for Succ<W528> {
14952    type Operand = Limbs<9>;
14953    #[inline]
14954    fn apply(a: Limbs<9>) -> Limbs<9> {
14955        (a.wrapping_add(Limbs::<9>::from_words([
14956            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
14957        ])))
14958        .mask_high_bits(528)
14959    }
14960}
14961
14962impl RingOp<W1024> for Mul<W1024> {
14963    type Operand = Limbs<16>;
14964    #[inline]
14965    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14966        a.wrapping_mul(b)
14967    }
14968}
14969
14970impl RingOp<W1024> for Add<W1024> {
14971    type Operand = Limbs<16>;
14972    #[inline]
14973    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14974        a.wrapping_add(b)
14975    }
14976}
14977
14978impl RingOp<W1024> for Sub<W1024> {
14979    type Operand = Limbs<16>;
14980    #[inline]
14981    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14982        a.wrapping_sub(b)
14983    }
14984}
14985
14986impl RingOp<W1024> for Xor<W1024> {
14987    type Operand = Limbs<16>;
14988    #[inline]
14989    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14990        a.xor(b)
14991    }
14992}
14993
14994impl RingOp<W1024> for And<W1024> {
14995    type Operand = Limbs<16>;
14996    #[inline]
14997    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
14998        a.and(b)
14999    }
15000}
15001
15002impl RingOp<W1024> for Or<W1024> {
15003    type Operand = Limbs<16>;
15004    #[inline]
15005    fn apply(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
15006        a.or(b)
15007    }
15008}
15009
15010impl UnaryRingOp<W1024> for Neg<W1024> {
15011    type Operand = Limbs<16>;
15012    #[inline]
15013    fn apply(a: Limbs<16>) -> Limbs<16> {
15014        Limbs::<16>::zero().wrapping_sub(a)
15015    }
15016}
15017
15018impl UnaryRingOp<W1024> for BNot<W1024> {
15019    type Operand = Limbs<16>;
15020    #[inline]
15021    fn apply(a: Limbs<16>) -> Limbs<16> {
15022        a.not()
15023    }
15024}
15025
15026impl UnaryRingOp<W1024> for Succ<W1024> {
15027    type Operand = Limbs<16>;
15028    #[inline]
15029    fn apply(a: Limbs<16>) -> Limbs<16> {
15030        a.wrapping_add(Limbs::<16>::from_words([
15031            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15032            0u64, 0u64,
15033        ]))
15034    }
15035}
15036
15037impl RingOp<W2048> for Mul<W2048> {
15038    type Operand = Limbs<32>;
15039    #[inline]
15040    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
15041        a.wrapping_mul(b)
15042    }
15043}
15044
15045impl RingOp<W2048> for Add<W2048> {
15046    type Operand = Limbs<32>;
15047    #[inline]
15048    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
15049        a.wrapping_add(b)
15050    }
15051}
15052
15053impl RingOp<W2048> for Sub<W2048> {
15054    type Operand = Limbs<32>;
15055    #[inline]
15056    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
15057        a.wrapping_sub(b)
15058    }
15059}
15060
15061impl RingOp<W2048> for Xor<W2048> {
15062    type Operand = Limbs<32>;
15063    #[inline]
15064    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
15065        a.xor(b)
15066    }
15067}
15068
15069impl RingOp<W2048> for And<W2048> {
15070    type Operand = Limbs<32>;
15071    #[inline]
15072    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
15073        a.and(b)
15074    }
15075}
15076
15077impl RingOp<W2048> for Or<W2048> {
15078    type Operand = Limbs<32>;
15079    #[inline]
15080    fn apply(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
15081        a.or(b)
15082    }
15083}
15084
15085impl UnaryRingOp<W2048> for Neg<W2048> {
15086    type Operand = Limbs<32>;
15087    #[inline]
15088    fn apply(a: Limbs<32>) -> Limbs<32> {
15089        Limbs::<32>::zero().wrapping_sub(a)
15090    }
15091}
15092
15093impl UnaryRingOp<W2048> for BNot<W2048> {
15094    type Operand = Limbs<32>;
15095    #[inline]
15096    fn apply(a: Limbs<32>) -> Limbs<32> {
15097        a.not()
15098    }
15099}
15100
15101impl UnaryRingOp<W2048> for Succ<W2048> {
15102    type Operand = Limbs<32>;
15103    #[inline]
15104    fn apply(a: Limbs<32>) -> Limbs<32> {
15105        a.wrapping_add(Limbs::<32>::from_words([
15106            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15107            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15108            0u64, 0u64, 0u64, 0u64,
15109        ]))
15110    }
15111}
15112
15113impl RingOp<W4096> for Mul<W4096> {
15114    type Operand = Limbs<64>;
15115    #[inline]
15116    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
15117        a.wrapping_mul(b)
15118    }
15119}
15120
15121impl RingOp<W4096> for Add<W4096> {
15122    type Operand = Limbs<64>;
15123    #[inline]
15124    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
15125        a.wrapping_add(b)
15126    }
15127}
15128
15129impl RingOp<W4096> for Sub<W4096> {
15130    type Operand = Limbs<64>;
15131    #[inline]
15132    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
15133        a.wrapping_sub(b)
15134    }
15135}
15136
15137impl RingOp<W4096> for Xor<W4096> {
15138    type Operand = Limbs<64>;
15139    #[inline]
15140    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
15141        a.xor(b)
15142    }
15143}
15144
15145impl RingOp<W4096> for And<W4096> {
15146    type Operand = Limbs<64>;
15147    #[inline]
15148    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
15149        a.and(b)
15150    }
15151}
15152
15153impl RingOp<W4096> for Or<W4096> {
15154    type Operand = Limbs<64>;
15155    #[inline]
15156    fn apply(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
15157        a.or(b)
15158    }
15159}
15160
15161impl UnaryRingOp<W4096> for Neg<W4096> {
15162    type Operand = Limbs<64>;
15163    #[inline]
15164    fn apply(a: Limbs<64>) -> Limbs<64> {
15165        Limbs::<64>::zero().wrapping_sub(a)
15166    }
15167}
15168
15169impl UnaryRingOp<W4096> for BNot<W4096> {
15170    type Operand = Limbs<64>;
15171    #[inline]
15172    fn apply(a: Limbs<64>) -> Limbs<64> {
15173        a.not()
15174    }
15175}
15176
15177impl UnaryRingOp<W4096> for Succ<W4096> {
15178    type Operand = Limbs<64>;
15179    #[inline]
15180    fn apply(a: Limbs<64>) -> Limbs<64> {
15181        a.wrapping_add(Limbs::<64>::from_words([
15182            1u64, 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,
15187        ]))
15188    }
15189}
15190
15191impl RingOp<W8192> for Mul<W8192> {
15192    type Operand = Limbs<128>;
15193    #[inline]
15194    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15195        a.wrapping_mul(b)
15196    }
15197}
15198
15199impl RingOp<W8192> for Add<W8192> {
15200    type Operand = Limbs<128>;
15201    #[inline]
15202    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15203        a.wrapping_add(b)
15204    }
15205}
15206
15207impl RingOp<W8192> for Sub<W8192> {
15208    type Operand = Limbs<128>;
15209    #[inline]
15210    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15211        a.wrapping_sub(b)
15212    }
15213}
15214
15215impl RingOp<W8192> for Xor<W8192> {
15216    type Operand = Limbs<128>;
15217    #[inline]
15218    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15219        a.xor(b)
15220    }
15221}
15222
15223impl RingOp<W8192> for And<W8192> {
15224    type Operand = Limbs<128>;
15225    #[inline]
15226    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15227        a.and(b)
15228    }
15229}
15230
15231impl RingOp<W8192> for Or<W8192> {
15232    type Operand = Limbs<128>;
15233    #[inline]
15234    fn apply(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
15235        a.or(b)
15236    }
15237}
15238
15239impl UnaryRingOp<W8192> for Neg<W8192> {
15240    type Operand = Limbs<128>;
15241    #[inline]
15242    fn apply(a: Limbs<128>) -> Limbs<128> {
15243        Limbs::<128>::zero().wrapping_sub(a)
15244    }
15245}
15246
15247impl UnaryRingOp<W8192> for BNot<W8192> {
15248    type Operand = Limbs<128>;
15249    #[inline]
15250    fn apply(a: Limbs<128>) -> Limbs<128> {
15251        a.not()
15252    }
15253}
15254
15255impl UnaryRingOp<W8192> for Succ<W8192> {
15256    type Operand = Limbs<128>;
15257    #[inline]
15258    fn apply(a: Limbs<128>) -> Limbs<128> {
15259        a.wrapping_add(Limbs::<128>::from_words([
15260            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15261            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15262            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15263            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15264            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15265            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15266            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15267            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15268            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15269            0u64, 0u64,
15270        ]))
15271    }
15272}
15273
15274impl RingOp<W12288> for Mul<W12288> {
15275    type Operand = Limbs<192>;
15276    #[inline]
15277    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15278        a.wrapping_mul(b)
15279    }
15280}
15281
15282impl RingOp<W12288> for Add<W12288> {
15283    type Operand = Limbs<192>;
15284    #[inline]
15285    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15286        a.wrapping_add(b)
15287    }
15288}
15289
15290impl RingOp<W12288> for Sub<W12288> {
15291    type Operand = Limbs<192>;
15292    #[inline]
15293    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15294        a.wrapping_sub(b)
15295    }
15296}
15297
15298impl RingOp<W12288> for Xor<W12288> {
15299    type Operand = Limbs<192>;
15300    #[inline]
15301    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15302        a.xor(b)
15303    }
15304}
15305
15306impl RingOp<W12288> for And<W12288> {
15307    type Operand = Limbs<192>;
15308    #[inline]
15309    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15310        a.and(b)
15311    }
15312}
15313
15314impl RingOp<W12288> for Or<W12288> {
15315    type Operand = Limbs<192>;
15316    #[inline]
15317    fn apply(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
15318        a.or(b)
15319    }
15320}
15321
15322impl UnaryRingOp<W12288> for Neg<W12288> {
15323    type Operand = Limbs<192>;
15324    #[inline]
15325    fn apply(a: Limbs<192>) -> Limbs<192> {
15326        Limbs::<192>::zero().wrapping_sub(a)
15327    }
15328}
15329
15330impl UnaryRingOp<W12288> for BNot<W12288> {
15331    type Operand = Limbs<192>;
15332    #[inline]
15333    fn apply(a: Limbs<192>) -> Limbs<192> {
15334        a.not()
15335    }
15336}
15337
15338impl UnaryRingOp<W12288> for Succ<W12288> {
15339    type Operand = Limbs<192>;
15340    #[inline]
15341    fn apply(a: Limbs<192>) -> Limbs<192> {
15342        a.wrapping_add(Limbs::<192>::from_words([
15343            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15344            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15345            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15346            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15347            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15348            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15349            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15350            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15351            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15352            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15353            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15354            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15355            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15356            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15357        ]))
15358    }
15359}
15360
15361impl RingOp<W16384> for Mul<W16384> {
15362    type Operand = Limbs<256>;
15363    #[inline]
15364    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15365        a.wrapping_mul(b)
15366    }
15367}
15368
15369impl RingOp<W16384> for Add<W16384> {
15370    type Operand = Limbs<256>;
15371    #[inline]
15372    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15373        a.wrapping_add(b)
15374    }
15375}
15376
15377impl RingOp<W16384> for Sub<W16384> {
15378    type Operand = Limbs<256>;
15379    #[inline]
15380    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15381        a.wrapping_sub(b)
15382    }
15383}
15384
15385impl RingOp<W16384> for Xor<W16384> {
15386    type Operand = Limbs<256>;
15387    #[inline]
15388    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15389        a.xor(b)
15390    }
15391}
15392
15393impl RingOp<W16384> for And<W16384> {
15394    type Operand = Limbs<256>;
15395    #[inline]
15396    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15397        a.and(b)
15398    }
15399}
15400
15401impl RingOp<W16384> for Or<W16384> {
15402    type Operand = Limbs<256>;
15403    #[inline]
15404    fn apply(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
15405        a.or(b)
15406    }
15407}
15408
15409impl UnaryRingOp<W16384> for Neg<W16384> {
15410    type Operand = Limbs<256>;
15411    #[inline]
15412    fn apply(a: Limbs<256>) -> Limbs<256> {
15413        Limbs::<256>::zero().wrapping_sub(a)
15414    }
15415}
15416
15417impl UnaryRingOp<W16384> for BNot<W16384> {
15418    type Operand = Limbs<256>;
15419    #[inline]
15420    fn apply(a: Limbs<256>) -> Limbs<256> {
15421        a.not()
15422    }
15423}
15424
15425impl UnaryRingOp<W16384> for Succ<W16384> {
15426    type Operand = Limbs<256>;
15427    #[inline]
15428    fn apply(a: Limbs<256>) -> Limbs<256> {
15429        a.wrapping_add(Limbs::<256>::from_words([
15430            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15431            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15432            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15433            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15434            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15435            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15436            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15437            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15438            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15439            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15440            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15441            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15442            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15443            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15444            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15445            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15446            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15447            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15448            0u64, 0u64, 0u64, 0u64,
15449        ]))
15450    }
15451}
15452
15453impl RingOp<W32768> for Mul<W32768> {
15454    type Operand = Limbs<512>;
15455    #[inline]
15456    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15457        a.wrapping_mul(b)
15458    }
15459}
15460
15461impl RingOp<W32768> for Add<W32768> {
15462    type Operand = Limbs<512>;
15463    #[inline]
15464    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15465        a.wrapping_add(b)
15466    }
15467}
15468
15469impl RingOp<W32768> for Sub<W32768> {
15470    type Operand = Limbs<512>;
15471    #[inline]
15472    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15473        a.wrapping_sub(b)
15474    }
15475}
15476
15477impl RingOp<W32768> for Xor<W32768> {
15478    type Operand = Limbs<512>;
15479    #[inline]
15480    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15481        a.xor(b)
15482    }
15483}
15484
15485impl RingOp<W32768> for And<W32768> {
15486    type Operand = Limbs<512>;
15487    #[inline]
15488    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15489        a.and(b)
15490    }
15491}
15492
15493impl RingOp<W32768> for Or<W32768> {
15494    type Operand = Limbs<512>;
15495    #[inline]
15496    fn apply(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
15497        a.or(b)
15498    }
15499}
15500
15501impl UnaryRingOp<W32768> for Neg<W32768> {
15502    type Operand = Limbs<512>;
15503    #[inline]
15504    fn apply(a: Limbs<512>) -> Limbs<512> {
15505        Limbs::<512>::zero().wrapping_sub(a)
15506    }
15507}
15508
15509impl UnaryRingOp<W32768> for BNot<W32768> {
15510    type Operand = Limbs<512>;
15511    #[inline]
15512    fn apply(a: Limbs<512>) -> Limbs<512> {
15513        a.not()
15514    }
15515}
15516
15517impl UnaryRingOp<W32768> for Succ<W32768> {
15518    type Operand = Limbs<512>;
15519    #[inline]
15520    fn apply(a: Limbs<512>) -> Limbs<512> {
15521        a.wrapping_add(Limbs::<512>::from_words([
15522            1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15523            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15524            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15525            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15526            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15527            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15528            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15529            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15530            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15531            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15532            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15533            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15534            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15535            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15536            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15537            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15538            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15539            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15540            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15541            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15542            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15543            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15544            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15545            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15546            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15547            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15548            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15549            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15550            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15551            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15552            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15553            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15554            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15555            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15556            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15557            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15558            0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
15559        ]))
15560    }
15561}
15562
15563/// Phase L.2 (target §4.5): `const_ring_eval_w{n}` helpers for Limbs-backed
15564/// Witt levels. Each helper runs a `PrimitiveOp` over two `Limbs<N>` operands
15565/// and applies the level's bit-width mask to the result.
15566/// These helpers are always const-fn; whether `rustc` can complete a specific
15567/// compile-time evaluation within the developer's budget is a function of the
15568/// invocation (see target §4.5 Q2 practicality table).
15569#[inline]
15570#[must_use]
15571pub const fn const_ring_eval_w160(op: PrimitiveOp, a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
15572    let raw = match op {
15573        PrimitiveOp::Add => a.wrapping_add(b),
15574        PrimitiveOp::Sub => a.wrapping_sub(b),
15575        PrimitiveOp::Mul => a.wrapping_mul(b),
15576        PrimitiveOp::And => a.and(b),
15577        PrimitiveOp::Or => a.or(b),
15578        PrimitiveOp::Xor => a.xor(b),
15579        PrimitiveOp::Neg => Limbs::<3>::zero().wrapping_sub(a),
15580        PrimitiveOp::Bnot => a.not(),
15581        PrimitiveOp::Succ => a.wrapping_add(limbs_one_3()),
15582        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_3()),
15583        PrimitiveOp::Le => {
15584            if limbs_le_3(a, b) {
15585                limbs_one_3()
15586            } else {
15587                Limbs::<3>::zero()
15588            }
15589        }
15590        PrimitiveOp::Lt => {
15591            if limbs_lt_3(a, b) {
15592                limbs_one_3()
15593            } else {
15594                Limbs::<3>::zero()
15595            }
15596        }
15597        PrimitiveOp::Ge => {
15598            if limbs_le_3(b, a) {
15599                limbs_one_3()
15600            } else {
15601                Limbs::<3>::zero()
15602            }
15603        }
15604        PrimitiveOp::Gt => {
15605            if limbs_lt_3(b, a) {
15606                limbs_one_3()
15607            } else {
15608                Limbs::<3>::zero()
15609            }
15610        }
15611        PrimitiveOp::Concat => Limbs::<3>::zero(),
15612        PrimitiveOp::Div => {
15613            if limbs_is_zero_3(b) {
15614                Limbs::<3>::zero()
15615            } else {
15616                limbs_div_3(a, b)
15617            }
15618        }
15619        PrimitiveOp::Mod => {
15620            if limbs_is_zero_3(b) {
15621                Limbs::<3>::zero()
15622            } else {
15623                limbs_mod_3(a, b)
15624            }
15625        }
15626        PrimitiveOp::Pow => limbs_pow_3(a, b),
15627    };
15628    raw.mask_high_bits(160)
15629}
15630
15631#[inline]
15632#[must_use]
15633pub const fn const_ring_eval_w192(op: PrimitiveOp, a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
15634    match op {
15635        PrimitiveOp::Add => a.wrapping_add(b),
15636        PrimitiveOp::Sub => a.wrapping_sub(b),
15637        PrimitiveOp::Mul => a.wrapping_mul(b),
15638        PrimitiveOp::And => a.and(b),
15639        PrimitiveOp::Or => a.or(b),
15640        PrimitiveOp::Xor => a.xor(b),
15641        PrimitiveOp::Neg => Limbs::<3>::zero().wrapping_sub(a),
15642        PrimitiveOp::Bnot => a.not(),
15643        PrimitiveOp::Succ => a.wrapping_add(limbs_one_3()),
15644        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_3()),
15645        PrimitiveOp::Le => {
15646            if limbs_le_3(a, b) {
15647                limbs_one_3()
15648            } else {
15649                Limbs::<3>::zero()
15650            }
15651        }
15652        PrimitiveOp::Lt => {
15653            if limbs_lt_3(a, b) {
15654                limbs_one_3()
15655            } else {
15656                Limbs::<3>::zero()
15657            }
15658        }
15659        PrimitiveOp::Ge => {
15660            if limbs_le_3(b, a) {
15661                limbs_one_3()
15662            } else {
15663                Limbs::<3>::zero()
15664            }
15665        }
15666        PrimitiveOp::Gt => {
15667            if limbs_lt_3(b, a) {
15668                limbs_one_3()
15669            } else {
15670                Limbs::<3>::zero()
15671            }
15672        }
15673        PrimitiveOp::Concat => Limbs::<3>::zero(),
15674        PrimitiveOp::Div => {
15675            if limbs_is_zero_3(b) {
15676                Limbs::<3>::zero()
15677            } else {
15678                limbs_div_3(a, b)
15679            }
15680        }
15681        PrimitiveOp::Mod => {
15682            if limbs_is_zero_3(b) {
15683                Limbs::<3>::zero()
15684            } else {
15685                limbs_mod_3(a, b)
15686            }
15687        }
15688        PrimitiveOp::Pow => limbs_pow_3(a, b),
15689    }
15690}
15691
15692#[inline]
15693#[must_use]
15694pub const fn const_ring_eval_w224(op: PrimitiveOp, a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
15695    let raw = match op {
15696        PrimitiveOp::Add => a.wrapping_add(b),
15697        PrimitiveOp::Sub => a.wrapping_sub(b),
15698        PrimitiveOp::Mul => a.wrapping_mul(b),
15699        PrimitiveOp::And => a.and(b),
15700        PrimitiveOp::Or => a.or(b),
15701        PrimitiveOp::Xor => a.xor(b),
15702        PrimitiveOp::Neg => Limbs::<4>::zero().wrapping_sub(a),
15703        PrimitiveOp::Bnot => a.not(),
15704        PrimitiveOp::Succ => a.wrapping_add(limbs_one_4()),
15705        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_4()),
15706        PrimitiveOp::Le => {
15707            if limbs_le_4(a, b) {
15708                limbs_one_4()
15709            } else {
15710                Limbs::<4>::zero()
15711            }
15712        }
15713        PrimitiveOp::Lt => {
15714            if limbs_lt_4(a, b) {
15715                limbs_one_4()
15716            } else {
15717                Limbs::<4>::zero()
15718            }
15719        }
15720        PrimitiveOp::Ge => {
15721            if limbs_le_4(b, a) {
15722                limbs_one_4()
15723            } else {
15724                Limbs::<4>::zero()
15725            }
15726        }
15727        PrimitiveOp::Gt => {
15728            if limbs_lt_4(b, a) {
15729                limbs_one_4()
15730            } else {
15731                Limbs::<4>::zero()
15732            }
15733        }
15734        PrimitiveOp::Concat => Limbs::<4>::zero(),
15735        PrimitiveOp::Div => {
15736            if limbs_is_zero_4(b) {
15737                Limbs::<4>::zero()
15738            } else {
15739                limbs_div_4(a, b)
15740            }
15741        }
15742        PrimitiveOp::Mod => {
15743            if limbs_is_zero_4(b) {
15744                Limbs::<4>::zero()
15745            } else {
15746                limbs_mod_4(a, b)
15747            }
15748        }
15749        PrimitiveOp::Pow => limbs_pow_4(a, b),
15750    };
15751    raw.mask_high_bits(224)
15752}
15753
15754#[inline]
15755#[must_use]
15756pub const fn const_ring_eval_w256(op: PrimitiveOp, a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
15757    match op {
15758        PrimitiveOp::Add => a.wrapping_add(b),
15759        PrimitiveOp::Sub => a.wrapping_sub(b),
15760        PrimitiveOp::Mul => a.wrapping_mul(b),
15761        PrimitiveOp::And => a.and(b),
15762        PrimitiveOp::Or => a.or(b),
15763        PrimitiveOp::Xor => a.xor(b),
15764        PrimitiveOp::Neg => Limbs::<4>::zero().wrapping_sub(a),
15765        PrimitiveOp::Bnot => a.not(),
15766        PrimitiveOp::Succ => a.wrapping_add(limbs_one_4()),
15767        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_4()),
15768        PrimitiveOp::Le => {
15769            if limbs_le_4(a, b) {
15770                limbs_one_4()
15771            } else {
15772                Limbs::<4>::zero()
15773            }
15774        }
15775        PrimitiveOp::Lt => {
15776            if limbs_lt_4(a, b) {
15777                limbs_one_4()
15778            } else {
15779                Limbs::<4>::zero()
15780            }
15781        }
15782        PrimitiveOp::Ge => {
15783            if limbs_le_4(b, a) {
15784                limbs_one_4()
15785            } else {
15786                Limbs::<4>::zero()
15787            }
15788        }
15789        PrimitiveOp::Gt => {
15790            if limbs_lt_4(b, a) {
15791                limbs_one_4()
15792            } else {
15793                Limbs::<4>::zero()
15794            }
15795        }
15796        PrimitiveOp::Concat => Limbs::<4>::zero(),
15797        PrimitiveOp::Div => {
15798            if limbs_is_zero_4(b) {
15799                Limbs::<4>::zero()
15800            } else {
15801                limbs_div_4(a, b)
15802            }
15803        }
15804        PrimitiveOp::Mod => {
15805            if limbs_is_zero_4(b) {
15806                Limbs::<4>::zero()
15807            } else {
15808                limbs_mod_4(a, b)
15809            }
15810        }
15811        PrimitiveOp::Pow => limbs_pow_4(a, b),
15812    }
15813}
15814
15815#[inline]
15816#[must_use]
15817pub const fn const_ring_eval_w384(op: PrimitiveOp, a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
15818    match op {
15819        PrimitiveOp::Add => a.wrapping_add(b),
15820        PrimitiveOp::Sub => a.wrapping_sub(b),
15821        PrimitiveOp::Mul => a.wrapping_mul(b),
15822        PrimitiveOp::And => a.and(b),
15823        PrimitiveOp::Or => a.or(b),
15824        PrimitiveOp::Xor => a.xor(b),
15825        PrimitiveOp::Neg => Limbs::<6>::zero().wrapping_sub(a),
15826        PrimitiveOp::Bnot => a.not(),
15827        PrimitiveOp::Succ => a.wrapping_add(limbs_one_6()),
15828        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_6()),
15829        PrimitiveOp::Le => {
15830            if limbs_le_6(a, b) {
15831                limbs_one_6()
15832            } else {
15833                Limbs::<6>::zero()
15834            }
15835        }
15836        PrimitiveOp::Lt => {
15837            if limbs_lt_6(a, b) {
15838                limbs_one_6()
15839            } else {
15840                Limbs::<6>::zero()
15841            }
15842        }
15843        PrimitiveOp::Ge => {
15844            if limbs_le_6(b, a) {
15845                limbs_one_6()
15846            } else {
15847                Limbs::<6>::zero()
15848            }
15849        }
15850        PrimitiveOp::Gt => {
15851            if limbs_lt_6(b, a) {
15852                limbs_one_6()
15853            } else {
15854                Limbs::<6>::zero()
15855            }
15856        }
15857        PrimitiveOp::Concat => Limbs::<6>::zero(),
15858        PrimitiveOp::Div => {
15859            if limbs_is_zero_6(b) {
15860                Limbs::<6>::zero()
15861            } else {
15862                limbs_div_6(a, b)
15863            }
15864        }
15865        PrimitiveOp::Mod => {
15866            if limbs_is_zero_6(b) {
15867                Limbs::<6>::zero()
15868            } else {
15869                limbs_mod_6(a, b)
15870            }
15871        }
15872        PrimitiveOp::Pow => limbs_pow_6(a, b),
15873    }
15874}
15875
15876#[inline]
15877#[must_use]
15878pub const fn const_ring_eval_w448(op: PrimitiveOp, a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
15879    match op {
15880        PrimitiveOp::Add => a.wrapping_add(b),
15881        PrimitiveOp::Sub => a.wrapping_sub(b),
15882        PrimitiveOp::Mul => a.wrapping_mul(b),
15883        PrimitiveOp::And => a.and(b),
15884        PrimitiveOp::Or => a.or(b),
15885        PrimitiveOp::Xor => a.xor(b),
15886        PrimitiveOp::Neg => Limbs::<7>::zero().wrapping_sub(a),
15887        PrimitiveOp::Bnot => a.not(),
15888        PrimitiveOp::Succ => a.wrapping_add(limbs_one_7()),
15889        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_7()),
15890        PrimitiveOp::Le => {
15891            if limbs_le_7(a, b) {
15892                limbs_one_7()
15893            } else {
15894                Limbs::<7>::zero()
15895            }
15896        }
15897        PrimitiveOp::Lt => {
15898            if limbs_lt_7(a, b) {
15899                limbs_one_7()
15900            } else {
15901                Limbs::<7>::zero()
15902            }
15903        }
15904        PrimitiveOp::Ge => {
15905            if limbs_le_7(b, a) {
15906                limbs_one_7()
15907            } else {
15908                Limbs::<7>::zero()
15909            }
15910        }
15911        PrimitiveOp::Gt => {
15912            if limbs_lt_7(b, a) {
15913                limbs_one_7()
15914            } else {
15915                Limbs::<7>::zero()
15916            }
15917        }
15918        PrimitiveOp::Concat => Limbs::<7>::zero(),
15919        PrimitiveOp::Div => {
15920            if limbs_is_zero_7(b) {
15921                Limbs::<7>::zero()
15922            } else {
15923                limbs_div_7(a, b)
15924            }
15925        }
15926        PrimitiveOp::Mod => {
15927            if limbs_is_zero_7(b) {
15928                Limbs::<7>::zero()
15929            } else {
15930                limbs_mod_7(a, b)
15931            }
15932        }
15933        PrimitiveOp::Pow => limbs_pow_7(a, b),
15934    }
15935}
15936
15937#[inline]
15938#[must_use]
15939pub const fn const_ring_eval_w512(op: PrimitiveOp, a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
15940    match op {
15941        PrimitiveOp::Add => a.wrapping_add(b),
15942        PrimitiveOp::Sub => a.wrapping_sub(b),
15943        PrimitiveOp::Mul => a.wrapping_mul(b),
15944        PrimitiveOp::And => a.and(b),
15945        PrimitiveOp::Or => a.or(b),
15946        PrimitiveOp::Xor => a.xor(b),
15947        PrimitiveOp::Neg => Limbs::<8>::zero().wrapping_sub(a),
15948        PrimitiveOp::Bnot => a.not(),
15949        PrimitiveOp::Succ => a.wrapping_add(limbs_one_8()),
15950        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_8()),
15951        PrimitiveOp::Le => {
15952            if limbs_le_8(a, b) {
15953                limbs_one_8()
15954            } else {
15955                Limbs::<8>::zero()
15956            }
15957        }
15958        PrimitiveOp::Lt => {
15959            if limbs_lt_8(a, b) {
15960                limbs_one_8()
15961            } else {
15962                Limbs::<8>::zero()
15963            }
15964        }
15965        PrimitiveOp::Ge => {
15966            if limbs_le_8(b, a) {
15967                limbs_one_8()
15968            } else {
15969                Limbs::<8>::zero()
15970            }
15971        }
15972        PrimitiveOp::Gt => {
15973            if limbs_lt_8(b, a) {
15974                limbs_one_8()
15975            } else {
15976                Limbs::<8>::zero()
15977            }
15978        }
15979        PrimitiveOp::Concat => Limbs::<8>::zero(),
15980        PrimitiveOp::Div => {
15981            if limbs_is_zero_8(b) {
15982                Limbs::<8>::zero()
15983            } else {
15984                limbs_div_8(a, b)
15985            }
15986        }
15987        PrimitiveOp::Mod => {
15988            if limbs_is_zero_8(b) {
15989                Limbs::<8>::zero()
15990            } else {
15991                limbs_mod_8(a, b)
15992            }
15993        }
15994        PrimitiveOp::Pow => limbs_pow_8(a, b),
15995    }
15996}
15997
15998#[inline]
15999#[must_use]
16000pub const fn const_ring_eval_w520(op: PrimitiveOp, a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
16001    let raw = match op {
16002        PrimitiveOp::Add => a.wrapping_add(b),
16003        PrimitiveOp::Sub => a.wrapping_sub(b),
16004        PrimitiveOp::Mul => a.wrapping_mul(b),
16005        PrimitiveOp::And => a.and(b),
16006        PrimitiveOp::Or => a.or(b),
16007        PrimitiveOp::Xor => a.xor(b),
16008        PrimitiveOp::Neg => Limbs::<9>::zero().wrapping_sub(a),
16009        PrimitiveOp::Bnot => a.not(),
16010        PrimitiveOp::Succ => a.wrapping_add(limbs_one_9()),
16011        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_9()),
16012        PrimitiveOp::Le => {
16013            if limbs_le_9(a, b) {
16014                limbs_one_9()
16015            } else {
16016                Limbs::<9>::zero()
16017            }
16018        }
16019        PrimitiveOp::Lt => {
16020            if limbs_lt_9(a, b) {
16021                limbs_one_9()
16022            } else {
16023                Limbs::<9>::zero()
16024            }
16025        }
16026        PrimitiveOp::Ge => {
16027            if limbs_le_9(b, a) {
16028                limbs_one_9()
16029            } else {
16030                Limbs::<9>::zero()
16031            }
16032        }
16033        PrimitiveOp::Gt => {
16034            if limbs_lt_9(b, a) {
16035                limbs_one_9()
16036            } else {
16037                Limbs::<9>::zero()
16038            }
16039        }
16040        PrimitiveOp::Concat => Limbs::<9>::zero(),
16041        PrimitiveOp::Div => {
16042            if limbs_is_zero_9(b) {
16043                Limbs::<9>::zero()
16044            } else {
16045                limbs_div_9(a, b)
16046            }
16047        }
16048        PrimitiveOp::Mod => {
16049            if limbs_is_zero_9(b) {
16050                Limbs::<9>::zero()
16051            } else {
16052                limbs_mod_9(a, b)
16053            }
16054        }
16055        PrimitiveOp::Pow => limbs_pow_9(a, b),
16056    };
16057    raw.mask_high_bits(520)
16058}
16059
16060#[inline]
16061#[must_use]
16062pub const fn const_ring_eval_w528(op: PrimitiveOp, a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
16063    let raw = match op {
16064        PrimitiveOp::Add => a.wrapping_add(b),
16065        PrimitiveOp::Sub => a.wrapping_sub(b),
16066        PrimitiveOp::Mul => a.wrapping_mul(b),
16067        PrimitiveOp::And => a.and(b),
16068        PrimitiveOp::Or => a.or(b),
16069        PrimitiveOp::Xor => a.xor(b),
16070        PrimitiveOp::Neg => Limbs::<9>::zero().wrapping_sub(a),
16071        PrimitiveOp::Bnot => a.not(),
16072        PrimitiveOp::Succ => a.wrapping_add(limbs_one_9()),
16073        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_9()),
16074        PrimitiveOp::Le => {
16075            if limbs_le_9(a, b) {
16076                limbs_one_9()
16077            } else {
16078                Limbs::<9>::zero()
16079            }
16080        }
16081        PrimitiveOp::Lt => {
16082            if limbs_lt_9(a, b) {
16083                limbs_one_9()
16084            } else {
16085                Limbs::<9>::zero()
16086            }
16087        }
16088        PrimitiveOp::Ge => {
16089            if limbs_le_9(b, a) {
16090                limbs_one_9()
16091            } else {
16092                Limbs::<9>::zero()
16093            }
16094        }
16095        PrimitiveOp::Gt => {
16096            if limbs_lt_9(b, a) {
16097                limbs_one_9()
16098            } else {
16099                Limbs::<9>::zero()
16100            }
16101        }
16102        PrimitiveOp::Concat => Limbs::<9>::zero(),
16103        PrimitiveOp::Div => {
16104            if limbs_is_zero_9(b) {
16105                Limbs::<9>::zero()
16106            } else {
16107                limbs_div_9(a, b)
16108            }
16109        }
16110        PrimitiveOp::Mod => {
16111            if limbs_is_zero_9(b) {
16112                Limbs::<9>::zero()
16113            } else {
16114                limbs_mod_9(a, b)
16115            }
16116        }
16117        PrimitiveOp::Pow => limbs_pow_9(a, b),
16118    };
16119    raw.mask_high_bits(528)
16120}
16121
16122#[inline]
16123#[must_use]
16124pub const fn const_ring_eval_w1024(op: PrimitiveOp, a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
16125    match op {
16126        PrimitiveOp::Add => a.wrapping_add(b),
16127        PrimitiveOp::Sub => a.wrapping_sub(b),
16128        PrimitiveOp::Mul => a.wrapping_mul(b),
16129        PrimitiveOp::And => a.and(b),
16130        PrimitiveOp::Or => a.or(b),
16131        PrimitiveOp::Xor => a.xor(b),
16132        PrimitiveOp::Neg => Limbs::<16>::zero().wrapping_sub(a),
16133        PrimitiveOp::Bnot => a.not(),
16134        PrimitiveOp::Succ => a.wrapping_add(limbs_one_16()),
16135        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_16()),
16136        PrimitiveOp::Le => {
16137            if limbs_le_16(a, b) {
16138                limbs_one_16()
16139            } else {
16140                Limbs::<16>::zero()
16141            }
16142        }
16143        PrimitiveOp::Lt => {
16144            if limbs_lt_16(a, b) {
16145                limbs_one_16()
16146            } else {
16147                Limbs::<16>::zero()
16148            }
16149        }
16150        PrimitiveOp::Ge => {
16151            if limbs_le_16(b, a) {
16152                limbs_one_16()
16153            } else {
16154                Limbs::<16>::zero()
16155            }
16156        }
16157        PrimitiveOp::Gt => {
16158            if limbs_lt_16(b, a) {
16159                limbs_one_16()
16160            } else {
16161                Limbs::<16>::zero()
16162            }
16163        }
16164        PrimitiveOp::Concat => Limbs::<16>::zero(),
16165        PrimitiveOp::Div => {
16166            if limbs_is_zero_16(b) {
16167                Limbs::<16>::zero()
16168            } else {
16169                limbs_div_16(a, b)
16170            }
16171        }
16172        PrimitiveOp::Mod => {
16173            if limbs_is_zero_16(b) {
16174                Limbs::<16>::zero()
16175            } else {
16176                limbs_mod_16(a, b)
16177            }
16178        }
16179        PrimitiveOp::Pow => limbs_pow_16(a, b),
16180    }
16181}
16182
16183#[inline]
16184#[must_use]
16185pub const fn const_ring_eval_w2048(op: PrimitiveOp, a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
16186    match op {
16187        PrimitiveOp::Add => a.wrapping_add(b),
16188        PrimitiveOp::Sub => a.wrapping_sub(b),
16189        PrimitiveOp::Mul => a.wrapping_mul(b),
16190        PrimitiveOp::And => a.and(b),
16191        PrimitiveOp::Or => a.or(b),
16192        PrimitiveOp::Xor => a.xor(b),
16193        PrimitiveOp::Neg => Limbs::<32>::zero().wrapping_sub(a),
16194        PrimitiveOp::Bnot => a.not(),
16195        PrimitiveOp::Succ => a.wrapping_add(limbs_one_32()),
16196        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_32()),
16197        PrimitiveOp::Le => {
16198            if limbs_le_32(a, b) {
16199                limbs_one_32()
16200            } else {
16201                Limbs::<32>::zero()
16202            }
16203        }
16204        PrimitiveOp::Lt => {
16205            if limbs_lt_32(a, b) {
16206                limbs_one_32()
16207            } else {
16208                Limbs::<32>::zero()
16209            }
16210        }
16211        PrimitiveOp::Ge => {
16212            if limbs_le_32(b, a) {
16213                limbs_one_32()
16214            } else {
16215                Limbs::<32>::zero()
16216            }
16217        }
16218        PrimitiveOp::Gt => {
16219            if limbs_lt_32(b, a) {
16220                limbs_one_32()
16221            } else {
16222                Limbs::<32>::zero()
16223            }
16224        }
16225        PrimitiveOp::Concat => Limbs::<32>::zero(),
16226        PrimitiveOp::Div => {
16227            if limbs_is_zero_32(b) {
16228                Limbs::<32>::zero()
16229            } else {
16230                limbs_div_32(a, b)
16231            }
16232        }
16233        PrimitiveOp::Mod => {
16234            if limbs_is_zero_32(b) {
16235                Limbs::<32>::zero()
16236            } else {
16237                limbs_mod_32(a, b)
16238            }
16239        }
16240        PrimitiveOp::Pow => limbs_pow_32(a, b),
16241    }
16242}
16243
16244#[inline]
16245#[must_use]
16246pub const fn const_ring_eval_w4096(op: PrimitiveOp, a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
16247    match op {
16248        PrimitiveOp::Add => a.wrapping_add(b),
16249        PrimitiveOp::Sub => a.wrapping_sub(b),
16250        PrimitiveOp::Mul => a.wrapping_mul(b),
16251        PrimitiveOp::And => a.and(b),
16252        PrimitiveOp::Or => a.or(b),
16253        PrimitiveOp::Xor => a.xor(b),
16254        PrimitiveOp::Neg => Limbs::<64>::zero().wrapping_sub(a),
16255        PrimitiveOp::Bnot => a.not(),
16256        PrimitiveOp::Succ => a.wrapping_add(limbs_one_64()),
16257        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_64()),
16258        PrimitiveOp::Le => {
16259            if limbs_le_64(a, b) {
16260                limbs_one_64()
16261            } else {
16262                Limbs::<64>::zero()
16263            }
16264        }
16265        PrimitiveOp::Lt => {
16266            if limbs_lt_64(a, b) {
16267                limbs_one_64()
16268            } else {
16269                Limbs::<64>::zero()
16270            }
16271        }
16272        PrimitiveOp::Ge => {
16273            if limbs_le_64(b, a) {
16274                limbs_one_64()
16275            } else {
16276                Limbs::<64>::zero()
16277            }
16278        }
16279        PrimitiveOp::Gt => {
16280            if limbs_lt_64(b, a) {
16281                limbs_one_64()
16282            } else {
16283                Limbs::<64>::zero()
16284            }
16285        }
16286        PrimitiveOp::Concat => Limbs::<64>::zero(),
16287        PrimitiveOp::Div => {
16288            if limbs_is_zero_64(b) {
16289                Limbs::<64>::zero()
16290            } else {
16291                limbs_div_64(a, b)
16292            }
16293        }
16294        PrimitiveOp::Mod => {
16295            if limbs_is_zero_64(b) {
16296                Limbs::<64>::zero()
16297            } else {
16298                limbs_mod_64(a, b)
16299            }
16300        }
16301        PrimitiveOp::Pow => limbs_pow_64(a, b),
16302    }
16303}
16304
16305#[inline]
16306#[must_use]
16307pub const fn const_ring_eval_w8192(op: PrimitiveOp, a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
16308    match op {
16309        PrimitiveOp::Add => a.wrapping_add(b),
16310        PrimitiveOp::Sub => a.wrapping_sub(b),
16311        PrimitiveOp::Mul => a.wrapping_mul(b),
16312        PrimitiveOp::And => a.and(b),
16313        PrimitiveOp::Or => a.or(b),
16314        PrimitiveOp::Xor => a.xor(b),
16315        PrimitiveOp::Neg => Limbs::<128>::zero().wrapping_sub(a),
16316        PrimitiveOp::Bnot => a.not(),
16317        PrimitiveOp::Succ => a.wrapping_add(limbs_one_128()),
16318        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_128()),
16319        PrimitiveOp::Le => {
16320            if limbs_le_128(a, b) {
16321                limbs_one_128()
16322            } else {
16323                Limbs::<128>::zero()
16324            }
16325        }
16326        PrimitiveOp::Lt => {
16327            if limbs_lt_128(a, b) {
16328                limbs_one_128()
16329            } else {
16330                Limbs::<128>::zero()
16331            }
16332        }
16333        PrimitiveOp::Ge => {
16334            if limbs_le_128(b, a) {
16335                limbs_one_128()
16336            } else {
16337                Limbs::<128>::zero()
16338            }
16339        }
16340        PrimitiveOp::Gt => {
16341            if limbs_lt_128(b, a) {
16342                limbs_one_128()
16343            } else {
16344                Limbs::<128>::zero()
16345            }
16346        }
16347        PrimitiveOp::Concat => Limbs::<128>::zero(),
16348        PrimitiveOp::Div => {
16349            if limbs_is_zero_128(b) {
16350                Limbs::<128>::zero()
16351            } else {
16352                limbs_div_128(a, b)
16353            }
16354        }
16355        PrimitiveOp::Mod => {
16356            if limbs_is_zero_128(b) {
16357                Limbs::<128>::zero()
16358            } else {
16359                limbs_mod_128(a, b)
16360            }
16361        }
16362        PrimitiveOp::Pow => limbs_pow_128(a, b),
16363    }
16364}
16365
16366#[inline]
16367#[must_use]
16368pub const fn const_ring_eval_w12288(op: PrimitiveOp, a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
16369    match op {
16370        PrimitiveOp::Add => a.wrapping_add(b),
16371        PrimitiveOp::Sub => a.wrapping_sub(b),
16372        PrimitiveOp::Mul => a.wrapping_mul(b),
16373        PrimitiveOp::And => a.and(b),
16374        PrimitiveOp::Or => a.or(b),
16375        PrimitiveOp::Xor => a.xor(b),
16376        PrimitiveOp::Neg => Limbs::<192>::zero().wrapping_sub(a),
16377        PrimitiveOp::Bnot => a.not(),
16378        PrimitiveOp::Succ => a.wrapping_add(limbs_one_192()),
16379        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_192()),
16380        PrimitiveOp::Le => {
16381            if limbs_le_192(a, b) {
16382                limbs_one_192()
16383            } else {
16384                Limbs::<192>::zero()
16385            }
16386        }
16387        PrimitiveOp::Lt => {
16388            if limbs_lt_192(a, b) {
16389                limbs_one_192()
16390            } else {
16391                Limbs::<192>::zero()
16392            }
16393        }
16394        PrimitiveOp::Ge => {
16395            if limbs_le_192(b, a) {
16396                limbs_one_192()
16397            } else {
16398                Limbs::<192>::zero()
16399            }
16400        }
16401        PrimitiveOp::Gt => {
16402            if limbs_lt_192(b, a) {
16403                limbs_one_192()
16404            } else {
16405                Limbs::<192>::zero()
16406            }
16407        }
16408        PrimitiveOp::Concat => Limbs::<192>::zero(),
16409        PrimitiveOp::Div => {
16410            if limbs_is_zero_192(b) {
16411                Limbs::<192>::zero()
16412            } else {
16413                limbs_div_192(a, b)
16414            }
16415        }
16416        PrimitiveOp::Mod => {
16417            if limbs_is_zero_192(b) {
16418                Limbs::<192>::zero()
16419            } else {
16420                limbs_mod_192(a, b)
16421            }
16422        }
16423        PrimitiveOp::Pow => limbs_pow_192(a, b),
16424    }
16425}
16426
16427#[inline]
16428#[must_use]
16429pub const fn const_ring_eval_w16384(op: PrimitiveOp, a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
16430    match op {
16431        PrimitiveOp::Add => a.wrapping_add(b),
16432        PrimitiveOp::Sub => a.wrapping_sub(b),
16433        PrimitiveOp::Mul => a.wrapping_mul(b),
16434        PrimitiveOp::And => a.and(b),
16435        PrimitiveOp::Or => a.or(b),
16436        PrimitiveOp::Xor => a.xor(b),
16437        PrimitiveOp::Neg => Limbs::<256>::zero().wrapping_sub(a),
16438        PrimitiveOp::Bnot => a.not(),
16439        PrimitiveOp::Succ => a.wrapping_add(limbs_one_256()),
16440        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_256()),
16441        PrimitiveOp::Le => {
16442            if limbs_le_256(a, b) {
16443                limbs_one_256()
16444            } else {
16445                Limbs::<256>::zero()
16446            }
16447        }
16448        PrimitiveOp::Lt => {
16449            if limbs_lt_256(a, b) {
16450                limbs_one_256()
16451            } else {
16452                Limbs::<256>::zero()
16453            }
16454        }
16455        PrimitiveOp::Ge => {
16456            if limbs_le_256(b, a) {
16457                limbs_one_256()
16458            } else {
16459                Limbs::<256>::zero()
16460            }
16461        }
16462        PrimitiveOp::Gt => {
16463            if limbs_lt_256(b, a) {
16464                limbs_one_256()
16465            } else {
16466                Limbs::<256>::zero()
16467            }
16468        }
16469        PrimitiveOp::Concat => Limbs::<256>::zero(),
16470        PrimitiveOp::Div => {
16471            if limbs_is_zero_256(b) {
16472                Limbs::<256>::zero()
16473            } else {
16474                limbs_div_256(a, b)
16475            }
16476        }
16477        PrimitiveOp::Mod => {
16478            if limbs_is_zero_256(b) {
16479                Limbs::<256>::zero()
16480            } else {
16481                limbs_mod_256(a, b)
16482            }
16483        }
16484        PrimitiveOp::Pow => limbs_pow_256(a, b),
16485    }
16486}
16487
16488#[inline]
16489#[must_use]
16490pub const fn const_ring_eval_w32768(op: PrimitiveOp, a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
16491    match op {
16492        PrimitiveOp::Add => a.wrapping_add(b),
16493        PrimitiveOp::Sub => a.wrapping_sub(b),
16494        PrimitiveOp::Mul => a.wrapping_mul(b),
16495        PrimitiveOp::And => a.and(b),
16496        PrimitiveOp::Or => a.or(b),
16497        PrimitiveOp::Xor => a.xor(b),
16498        PrimitiveOp::Neg => Limbs::<512>::zero().wrapping_sub(a),
16499        PrimitiveOp::Bnot => a.not(),
16500        PrimitiveOp::Succ => a.wrapping_add(limbs_one_512()),
16501        PrimitiveOp::Pred => a.wrapping_sub(limbs_one_512()),
16502        PrimitiveOp::Le => {
16503            if limbs_le_512(a, b) {
16504                limbs_one_512()
16505            } else {
16506                Limbs::<512>::zero()
16507            }
16508        }
16509        PrimitiveOp::Lt => {
16510            if limbs_lt_512(a, b) {
16511                limbs_one_512()
16512            } else {
16513                Limbs::<512>::zero()
16514            }
16515        }
16516        PrimitiveOp::Ge => {
16517            if limbs_le_512(b, a) {
16518                limbs_one_512()
16519            } else {
16520                Limbs::<512>::zero()
16521            }
16522        }
16523        PrimitiveOp::Gt => {
16524            if limbs_lt_512(b, a) {
16525                limbs_one_512()
16526            } else {
16527                Limbs::<512>::zero()
16528            }
16529        }
16530        PrimitiveOp::Concat => Limbs::<512>::zero(),
16531        PrimitiveOp::Div => {
16532            if limbs_is_zero_512(b) {
16533                Limbs::<512>::zero()
16534            } else {
16535                limbs_div_512(a, b)
16536            }
16537        }
16538        PrimitiveOp::Mod => {
16539            if limbs_is_zero_512(b) {
16540                Limbs::<512>::zero()
16541            } else {
16542                limbs_mod_512(a, b)
16543            }
16544        }
16545        PrimitiveOp::Pow => limbs_pow_512(a, b),
16546    }
16547}
16548
16549/// Phase L.2: one-constant helpers for `Limbs<N>::from_words([1, 0, ...])`.
16550#[inline]
16551#[must_use]
16552const fn limbs_one_3() -> Limbs<3> {
16553    Limbs::<3>::from_words([1u64, 0u64, 0u64])
16554}
16555
16556#[inline]
16557#[must_use]
16558const fn limbs_one_4() -> Limbs<4> {
16559    Limbs::<4>::from_words([1u64, 0u64, 0u64, 0u64])
16560}
16561
16562#[inline]
16563#[must_use]
16564const fn limbs_one_6() -> Limbs<6> {
16565    Limbs::<6>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16566}
16567
16568#[inline]
16569#[must_use]
16570const fn limbs_one_7() -> Limbs<7> {
16571    Limbs::<7>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16572}
16573
16574#[inline]
16575#[must_use]
16576const fn limbs_one_8() -> Limbs<8> {
16577    Limbs::<8>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16578}
16579
16580#[inline]
16581#[must_use]
16582const fn limbs_one_9() -> Limbs<9> {
16583    Limbs::<9>::from_words([1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64])
16584}
16585
16586#[inline]
16587#[must_use]
16588const fn limbs_one_16() -> Limbs<16> {
16589    Limbs::<16>::from_words([
16590        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16591        0u64,
16592    ])
16593}
16594
16595#[inline]
16596#[must_use]
16597const fn limbs_one_32() -> Limbs<32> {
16598    Limbs::<32>::from_words([
16599        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16600        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16601        0u64, 0u64,
16602    ])
16603}
16604
16605#[inline]
16606#[must_use]
16607const fn limbs_one_64() -> Limbs<64> {
16608    Limbs::<64>::from_words([
16609        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16610        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16611        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16612        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16613        0u64, 0u64, 0u64, 0u64,
16614    ])
16615}
16616
16617#[inline]
16618#[must_use]
16619const fn limbs_one_128() -> Limbs<128> {
16620    Limbs::<128>::from_words([
16621        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16622        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16623        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16624        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16625        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16626        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16627        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16628        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16629        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16630    ])
16631}
16632
16633#[inline]
16634#[must_use]
16635const fn limbs_one_192() -> Limbs<192> {
16636    Limbs::<192>::from_words([
16637        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16638        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16639        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16640        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16641        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16642        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16643        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16644        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16645        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16646        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16647        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16648        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16649        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16650    ])
16651}
16652
16653#[inline]
16654#[must_use]
16655const fn limbs_one_256() -> Limbs<256> {
16656    Limbs::<256>::from_words([
16657        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16658        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16659        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16660        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16661        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16662        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16663        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16664        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16665        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16666        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16667        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16668        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16669        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16670        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16671        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16672        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16673        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16674        0u64,
16675    ])
16676}
16677
16678#[inline]
16679#[must_use]
16680const fn limbs_one_512() -> Limbs<512> {
16681    Limbs::<512>::from_words([
16682        1u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16683        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16684        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16685        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16686        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16687        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16688        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16689        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16690        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16691        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16692        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16693        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16694        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16695        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16696        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16697        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16698        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16699        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16700        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16701        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16702        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16703        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16704        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16705        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16706        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16707        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16708        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16709        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16710        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16711        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16712        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16713        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16714        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16715        0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64, 0u64,
16716        0u64, 0u64,
16717    ])
16718}
16719
16720/// ADR-013/TR-08: const-fn limb comparisons used by `const_ring_eval_w{n}`
16721/// to lift the comparison primitives to 0/1-valued ring indicators.
16722#[inline]
16723#[must_use]
16724const fn limbs_lt_3(a: Limbs<3>, b: Limbs<3>) -> bool {
16725    let aw = a.words();
16726    let bw = b.words();
16727    let mut i = 3;
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    false
16738}
16739
16740#[inline]
16741#[must_use]
16742const fn limbs_le_3(a: Limbs<3>, b: Limbs<3>) -> bool {
16743    let aw = a.words();
16744    let bw = b.words();
16745    let mut i = 3;
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    true
16756}
16757
16758#[inline]
16759#[must_use]
16760const fn limbs_lt_4(a: Limbs<4>, b: Limbs<4>) -> bool {
16761    let aw = a.words();
16762    let bw = b.words();
16763    let mut i = 4;
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    false
16774}
16775
16776#[inline]
16777#[must_use]
16778const fn limbs_le_4(a: Limbs<4>, b: Limbs<4>) -> bool {
16779    let aw = a.words();
16780    let bw = b.words();
16781    let mut i = 4;
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    true
16792}
16793
16794#[inline]
16795#[must_use]
16796const fn limbs_lt_6(a: Limbs<6>, b: Limbs<6>) -> bool {
16797    let aw = a.words();
16798    let bw = b.words();
16799    let mut i = 6;
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    false
16810}
16811
16812#[inline]
16813#[must_use]
16814const fn limbs_le_6(a: Limbs<6>, b: Limbs<6>) -> bool {
16815    let aw = a.words();
16816    let bw = b.words();
16817    let mut i = 6;
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    true
16828}
16829
16830#[inline]
16831#[must_use]
16832const fn limbs_lt_7(a: Limbs<7>, b: Limbs<7>) -> bool {
16833    let aw = a.words();
16834    let bw = b.words();
16835    let mut i = 7;
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    false
16846}
16847
16848#[inline]
16849#[must_use]
16850const fn limbs_le_7(a: Limbs<7>, b: Limbs<7>) -> bool {
16851    let aw = a.words();
16852    let bw = b.words();
16853    let mut i = 7;
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    true
16864}
16865
16866#[inline]
16867#[must_use]
16868const fn limbs_lt_8(a: Limbs<8>, b: Limbs<8>) -> bool {
16869    let aw = a.words();
16870    let bw = b.words();
16871    let mut i = 8;
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    false
16882}
16883
16884#[inline]
16885#[must_use]
16886const fn limbs_le_8(a: Limbs<8>, b: Limbs<8>) -> bool {
16887    let aw = a.words();
16888    let bw = b.words();
16889    let mut i = 8;
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    true
16900}
16901
16902#[inline]
16903#[must_use]
16904const fn limbs_lt_9(a: Limbs<9>, b: Limbs<9>) -> bool {
16905    let aw = a.words();
16906    let bw = b.words();
16907    let mut i = 9;
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    false
16918}
16919
16920#[inline]
16921#[must_use]
16922const fn limbs_le_9(a: Limbs<9>, b: Limbs<9>) -> bool {
16923    let aw = a.words();
16924    let bw = b.words();
16925    let mut i = 9;
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    true
16936}
16937
16938#[inline]
16939#[must_use]
16940const fn limbs_lt_16(a: Limbs<16>, b: Limbs<16>) -> bool {
16941    let aw = a.words();
16942    let bw = b.words();
16943    let mut i = 16;
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    false
16954}
16955
16956#[inline]
16957#[must_use]
16958const fn limbs_le_16(a: Limbs<16>, b: Limbs<16>) -> bool {
16959    let aw = a.words();
16960    let bw = b.words();
16961    let mut i = 16;
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    true
16972}
16973
16974#[inline]
16975#[must_use]
16976const fn limbs_lt_32(a: Limbs<32>, b: Limbs<32>) -> bool {
16977    let aw = a.words();
16978    let bw = b.words();
16979    let mut i = 32;
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    false
16990}
16991
16992#[inline]
16993#[must_use]
16994const fn limbs_le_32(a: Limbs<32>, b: Limbs<32>) -> bool {
16995    let aw = a.words();
16996    let bw = b.words();
16997    let mut i = 32;
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    true
17008}
17009
17010#[inline]
17011#[must_use]
17012const fn limbs_lt_64(a: Limbs<64>, b: Limbs<64>) -> bool {
17013    let aw = a.words();
17014    let bw = b.words();
17015    let mut i = 64;
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    false
17026}
17027
17028#[inline]
17029#[must_use]
17030const fn limbs_le_64(a: Limbs<64>, b: Limbs<64>) -> bool {
17031    let aw = a.words();
17032    let bw = b.words();
17033    let mut i = 64;
17034    while i > 0 {
17035        i -= 1;
17036        if aw[i] < bw[i] {
17037            return true;
17038        }
17039        if aw[i] > bw[i] {
17040            return false;
17041        }
17042    }
17043    true
17044}
17045
17046#[inline]
17047#[must_use]
17048const fn limbs_lt_128(a: Limbs<128>, b: Limbs<128>) -> bool {
17049    let aw = a.words();
17050    let bw = b.words();
17051    let mut i = 128;
17052    while i > 0 {
17053        i -= 1;
17054        if aw[i] < bw[i] {
17055            return true;
17056        }
17057        if aw[i] > bw[i] {
17058            return false;
17059        }
17060    }
17061    false
17062}
17063
17064#[inline]
17065#[must_use]
17066const fn limbs_le_128(a: Limbs<128>, b: Limbs<128>) -> bool {
17067    let aw = a.words();
17068    let bw = b.words();
17069    let mut i = 128;
17070    while i > 0 {
17071        i -= 1;
17072        if aw[i] < bw[i] {
17073            return true;
17074        }
17075        if aw[i] > bw[i] {
17076            return false;
17077        }
17078    }
17079    true
17080}
17081
17082#[inline]
17083#[must_use]
17084const fn limbs_lt_192(a: Limbs<192>, b: Limbs<192>) -> bool {
17085    let aw = a.words();
17086    let bw = b.words();
17087    let mut i = 192;
17088    while i > 0 {
17089        i -= 1;
17090        if aw[i] < bw[i] {
17091            return true;
17092        }
17093        if aw[i] > bw[i] {
17094            return false;
17095        }
17096    }
17097    false
17098}
17099
17100#[inline]
17101#[must_use]
17102const fn limbs_le_192(a: Limbs<192>, b: Limbs<192>) -> bool {
17103    let aw = a.words();
17104    let bw = b.words();
17105    let mut i = 192;
17106    while i > 0 {
17107        i -= 1;
17108        if aw[i] < bw[i] {
17109            return true;
17110        }
17111        if aw[i] > bw[i] {
17112            return false;
17113        }
17114    }
17115    true
17116}
17117
17118#[inline]
17119#[must_use]
17120const fn limbs_lt_256(a: Limbs<256>, b: Limbs<256>) -> bool {
17121    let aw = a.words();
17122    let bw = b.words();
17123    let mut i = 256;
17124    while i > 0 {
17125        i -= 1;
17126        if aw[i] < bw[i] {
17127            return true;
17128        }
17129        if aw[i] > bw[i] {
17130            return false;
17131        }
17132    }
17133    false
17134}
17135
17136#[inline]
17137#[must_use]
17138const fn limbs_le_256(a: Limbs<256>, b: Limbs<256>) -> bool {
17139    let aw = a.words();
17140    let bw = b.words();
17141    let mut i = 256;
17142    while i > 0 {
17143        i -= 1;
17144        if aw[i] < bw[i] {
17145            return true;
17146        }
17147        if aw[i] > bw[i] {
17148            return false;
17149        }
17150    }
17151    true
17152}
17153
17154#[inline]
17155#[must_use]
17156const fn limbs_lt_512(a: Limbs<512>, b: Limbs<512>) -> bool {
17157    let aw = a.words();
17158    let bw = b.words();
17159    let mut i = 512;
17160    while i > 0 {
17161        i -= 1;
17162        if aw[i] < bw[i] {
17163            return true;
17164        }
17165        if aw[i] > bw[i] {
17166            return false;
17167        }
17168    }
17169    false
17170}
17171
17172#[inline]
17173#[must_use]
17174const fn limbs_le_512(a: Limbs<512>, b: Limbs<512>) -> bool {
17175    let aw = a.words();
17176    let bw = b.words();
17177    let mut i = 512;
17178    while i > 0 {
17179        i -= 1;
17180        if aw[i] < bw[i] {
17181            return true;
17182        }
17183        if aw[i] > bw[i] {
17184            return false;
17185        }
17186    }
17187    true
17188}
17189
17190/// ADR-053: zero-check, binary-long-division, and square-and-multiply
17191/// helpers used by the const-fn `Div`/`Mod`/`Pow` arms of `const_ring_eval_w{n}`.
17192#[inline]
17193#[must_use]
17194const fn limbs_is_zero_3(a: Limbs<3>) -> bool {
17195    let aw = a.words();
17196    let mut i = 0usize;
17197    while i < 3 {
17198        if aw[i] != 0 {
17199            return false;
17200        }
17201        i += 1;
17202    }
17203    true
17204}
17205
17206#[inline]
17207#[must_use]
17208const fn limbs_shl1_3(a: Limbs<3>) -> Limbs<3> {
17209    let aw = a.words();
17210    let mut out = [0u64; 3];
17211    let mut carry: u64 = 0;
17212    let mut i = 0usize;
17213    while i < 3 {
17214        let v = aw[i];
17215        out[i] = (v << 1) | carry;
17216        carry = v >> 63;
17217        i += 1;
17218    }
17219    Limbs::<3>::from_words(out)
17220}
17221
17222#[inline]
17223#[must_use]
17224const fn limbs_set_bit0_3(a: Limbs<3>) -> Limbs<3> {
17225    let aw = a.words();
17226    let mut out = [0u64; 3];
17227    let mut i = 0usize;
17228    while i < 3 {
17229        out[i] = aw[i];
17230        i += 1;
17231    }
17232    out[0] |= 1u64;
17233    Limbs::<3>::from_words(out)
17234}
17235
17236#[inline]
17237#[must_use]
17238const fn limbs_bit_msb_3(a: Limbs<3>, msb_index: usize) -> u64 {
17239    let aw = a.words();
17240    let total_bits = 3 * 64;
17241    let lsb_index = total_bits - 1 - msb_index;
17242    let word = lsb_index / 64;
17243    let bit = lsb_index % 64;
17244    (aw[word] >> bit) & 1u64
17245}
17246
17247#[inline]
17248#[must_use]
17249const fn limbs_divmod_3(a: Limbs<3>, b: Limbs<3>) -> (Limbs<3>, Limbs<3>) {
17250    let mut q = Limbs::<3>::zero();
17251    let mut r = Limbs::<3>::zero();
17252    let total_bits = 3 * 64;
17253    let mut i = 0usize;
17254    while i < total_bits {
17255        r = limbs_shl1_3(r);
17256        if limbs_bit_msb_3(a, i) == 1 {
17257            r = limbs_set_bit0_3(r);
17258        }
17259        if limbs_le_3(b, r) {
17260            r = r.wrapping_sub(b);
17261            q = limbs_shl1_3(q);
17262            q = limbs_set_bit0_3(q);
17263        } else {
17264            q = limbs_shl1_3(q);
17265        }
17266        i += 1;
17267    }
17268    (q, r)
17269}
17270
17271#[inline]
17272#[must_use]
17273const fn limbs_div_3(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
17274    let (q, _) = limbs_divmod_3(a, b);
17275    q
17276}
17277
17278#[inline]
17279#[must_use]
17280const fn limbs_mod_3(a: Limbs<3>, b: Limbs<3>) -> Limbs<3> {
17281    let (_, r) = limbs_divmod_3(a, b);
17282    r
17283}
17284
17285#[inline]
17286#[must_use]
17287const fn limbs_pow_3(base: Limbs<3>, exp: Limbs<3>) -> Limbs<3> {
17288    let mut result = limbs_one_3();
17289    let mut b = base;
17290    let ew = exp.words();
17291    let mut word = 0usize;
17292    while word < 3 {
17293        let mut bit = 0u32;
17294        while bit < 64 {
17295            if ((ew[word] >> bit) & 1u64) == 1u64 {
17296                result = result.wrapping_mul(b);
17297            }
17298            b = b.wrapping_mul(b);
17299            bit += 1;
17300        }
17301        word += 1;
17302    }
17303    result
17304}
17305
17306#[inline]
17307#[must_use]
17308const fn limbs_is_zero_4(a: Limbs<4>) -> bool {
17309    let aw = a.words();
17310    let mut i = 0usize;
17311    while i < 4 {
17312        if aw[i] != 0 {
17313            return false;
17314        }
17315        i += 1;
17316    }
17317    true
17318}
17319
17320#[inline]
17321#[must_use]
17322const fn limbs_shl1_4(a: Limbs<4>) -> Limbs<4> {
17323    let aw = a.words();
17324    let mut out = [0u64; 4];
17325    let mut carry: u64 = 0;
17326    let mut i = 0usize;
17327    while i < 4 {
17328        let v = aw[i];
17329        out[i] = (v << 1) | carry;
17330        carry = v >> 63;
17331        i += 1;
17332    }
17333    Limbs::<4>::from_words(out)
17334}
17335
17336#[inline]
17337#[must_use]
17338const fn limbs_set_bit0_4(a: Limbs<4>) -> Limbs<4> {
17339    let aw = a.words();
17340    let mut out = [0u64; 4];
17341    let mut i = 0usize;
17342    while i < 4 {
17343        out[i] = aw[i];
17344        i += 1;
17345    }
17346    out[0] |= 1u64;
17347    Limbs::<4>::from_words(out)
17348}
17349
17350#[inline]
17351#[must_use]
17352const fn limbs_bit_msb_4(a: Limbs<4>, msb_index: usize) -> u64 {
17353    let aw = a.words();
17354    let total_bits = 4 * 64;
17355    let lsb_index = total_bits - 1 - msb_index;
17356    let word = lsb_index / 64;
17357    let bit = lsb_index % 64;
17358    (aw[word] >> bit) & 1u64
17359}
17360
17361#[inline]
17362#[must_use]
17363const fn limbs_divmod_4(a: Limbs<4>, b: Limbs<4>) -> (Limbs<4>, Limbs<4>) {
17364    let mut q = Limbs::<4>::zero();
17365    let mut r = Limbs::<4>::zero();
17366    let total_bits = 4 * 64;
17367    let mut i = 0usize;
17368    while i < total_bits {
17369        r = limbs_shl1_4(r);
17370        if limbs_bit_msb_4(a, i) == 1 {
17371            r = limbs_set_bit0_4(r);
17372        }
17373        if limbs_le_4(b, r) {
17374            r = r.wrapping_sub(b);
17375            q = limbs_shl1_4(q);
17376            q = limbs_set_bit0_4(q);
17377        } else {
17378            q = limbs_shl1_4(q);
17379        }
17380        i += 1;
17381    }
17382    (q, r)
17383}
17384
17385#[inline]
17386#[must_use]
17387const fn limbs_div_4(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
17388    let (q, _) = limbs_divmod_4(a, b);
17389    q
17390}
17391
17392#[inline]
17393#[must_use]
17394const fn limbs_mod_4(a: Limbs<4>, b: Limbs<4>) -> Limbs<4> {
17395    let (_, r) = limbs_divmod_4(a, b);
17396    r
17397}
17398
17399#[inline]
17400#[must_use]
17401const fn limbs_pow_4(base: Limbs<4>, exp: Limbs<4>) -> Limbs<4> {
17402    let mut result = limbs_one_4();
17403    let mut b = base;
17404    let ew = exp.words();
17405    let mut word = 0usize;
17406    while word < 4 {
17407        let mut bit = 0u32;
17408        while bit < 64 {
17409            if ((ew[word] >> bit) & 1u64) == 1u64 {
17410                result = result.wrapping_mul(b);
17411            }
17412            b = b.wrapping_mul(b);
17413            bit += 1;
17414        }
17415        word += 1;
17416    }
17417    result
17418}
17419
17420#[inline]
17421#[must_use]
17422const fn limbs_is_zero_6(a: Limbs<6>) -> bool {
17423    let aw = a.words();
17424    let mut i = 0usize;
17425    while i < 6 {
17426        if aw[i] != 0 {
17427            return false;
17428        }
17429        i += 1;
17430    }
17431    true
17432}
17433
17434#[inline]
17435#[must_use]
17436const fn limbs_shl1_6(a: Limbs<6>) -> Limbs<6> {
17437    let aw = a.words();
17438    let mut out = [0u64; 6];
17439    let mut carry: u64 = 0;
17440    let mut i = 0usize;
17441    while i < 6 {
17442        let v = aw[i];
17443        out[i] = (v << 1) | carry;
17444        carry = v >> 63;
17445        i += 1;
17446    }
17447    Limbs::<6>::from_words(out)
17448}
17449
17450#[inline]
17451#[must_use]
17452const fn limbs_set_bit0_6(a: Limbs<6>) -> Limbs<6> {
17453    let aw = a.words();
17454    let mut out = [0u64; 6];
17455    let mut i = 0usize;
17456    while i < 6 {
17457        out[i] = aw[i];
17458        i += 1;
17459    }
17460    out[0] |= 1u64;
17461    Limbs::<6>::from_words(out)
17462}
17463
17464#[inline]
17465#[must_use]
17466const fn limbs_bit_msb_6(a: Limbs<6>, msb_index: usize) -> u64 {
17467    let aw = a.words();
17468    let total_bits = 6 * 64;
17469    let lsb_index = total_bits - 1 - msb_index;
17470    let word = lsb_index / 64;
17471    let bit = lsb_index % 64;
17472    (aw[word] >> bit) & 1u64
17473}
17474
17475#[inline]
17476#[must_use]
17477const fn limbs_divmod_6(a: Limbs<6>, b: Limbs<6>) -> (Limbs<6>, Limbs<6>) {
17478    let mut q = Limbs::<6>::zero();
17479    let mut r = Limbs::<6>::zero();
17480    let total_bits = 6 * 64;
17481    let mut i = 0usize;
17482    while i < total_bits {
17483        r = limbs_shl1_6(r);
17484        if limbs_bit_msb_6(a, i) == 1 {
17485            r = limbs_set_bit0_6(r);
17486        }
17487        if limbs_le_6(b, r) {
17488            r = r.wrapping_sub(b);
17489            q = limbs_shl1_6(q);
17490            q = limbs_set_bit0_6(q);
17491        } else {
17492            q = limbs_shl1_6(q);
17493        }
17494        i += 1;
17495    }
17496    (q, r)
17497}
17498
17499#[inline]
17500#[must_use]
17501const fn limbs_div_6(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
17502    let (q, _) = limbs_divmod_6(a, b);
17503    q
17504}
17505
17506#[inline]
17507#[must_use]
17508const fn limbs_mod_6(a: Limbs<6>, b: Limbs<6>) -> Limbs<6> {
17509    let (_, r) = limbs_divmod_6(a, b);
17510    r
17511}
17512
17513#[inline]
17514#[must_use]
17515const fn limbs_pow_6(base: Limbs<6>, exp: Limbs<6>) -> Limbs<6> {
17516    let mut result = limbs_one_6();
17517    let mut b = base;
17518    let ew = exp.words();
17519    let mut word = 0usize;
17520    while word < 6 {
17521        let mut bit = 0u32;
17522        while bit < 64 {
17523            if ((ew[word] >> bit) & 1u64) == 1u64 {
17524                result = result.wrapping_mul(b);
17525            }
17526            b = b.wrapping_mul(b);
17527            bit += 1;
17528        }
17529        word += 1;
17530    }
17531    result
17532}
17533
17534#[inline]
17535#[must_use]
17536const fn limbs_is_zero_7(a: Limbs<7>) -> bool {
17537    let aw = a.words();
17538    let mut i = 0usize;
17539    while i < 7 {
17540        if aw[i] != 0 {
17541            return false;
17542        }
17543        i += 1;
17544    }
17545    true
17546}
17547
17548#[inline]
17549#[must_use]
17550const fn limbs_shl1_7(a: Limbs<7>) -> Limbs<7> {
17551    let aw = a.words();
17552    let mut out = [0u64; 7];
17553    let mut carry: u64 = 0;
17554    let mut i = 0usize;
17555    while i < 7 {
17556        let v = aw[i];
17557        out[i] = (v << 1) | carry;
17558        carry = v >> 63;
17559        i += 1;
17560    }
17561    Limbs::<7>::from_words(out)
17562}
17563
17564#[inline]
17565#[must_use]
17566const fn limbs_set_bit0_7(a: Limbs<7>) -> Limbs<7> {
17567    let aw = a.words();
17568    let mut out = [0u64; 7];
17569    let mut i = 0usize;
17570    while i < 7 {
17571        out[i] = aw[i];
17572        i += 1;
17573    }
17574    out[0] |= 1u64;
17575    Limbs::<7>::from_words(out)
17576}
17577
17578#[inline]
17579#[must_use]
17580const fn limbs_bit_msb_7(a: Limbs<7>, msb_index: usize) -> u64 {
17581    let aw = a.words();
17582    let total_bits = 7 * 64;
17583    let lsb_index = total_bits - 1 - msb_index;
17584    let word = lsb_index / 64;
17585    let bit = lsb_index % 64;
17586    (aw[word] >> bit) & 1u64
17587}
17588
17589#[inline]
17590#[must_use]
17591const fn limbs_divmod_7(a: Limbs<7>, b: Limbs<7>) -> (Limbs<7>, Limbs<7>) {
17592    let mut q = Limbs::<7>::zero();
17593    let mut r = Limbs::<7>::zero();
17594    let total_bits = 7 * 64;
17595    let mut i = 0usize;
17596    while i < total_bits {
17597        r = limbs_shl1_7(r);
17598        if limbs_bit_msb_7(a, i) == 1 {
17599            r = limbs_set_bit0_7(r);
17600        }
17601        if limbs_le_7(b, r) {
17602            r = r.wrapping_sub(b);
17603            q = limbs_shl1_7(q);
17604            q = limbs_set_bit0_7(q);
17605        } else {
17606            q = limbs_shl1_7(q);
17607        }
17608        i += 1;
17609    }
17610    (q, r)
17611}
17612
17613#[inline]
17614#[must_use]
17615const fn limbs_div_7(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
17616    let (q, _) = limbs_divmod_7(a, b);
17617    q
17618}
17619
17620#[inline]
17621#[must_use]
17622const fn limbs_mod_7(a: Limbs<7>, b: Limbs<7>) -> Limbs<7> {
17623    let (_, r) = limbs_divmod_7(a, b);
17624    r
17625}
17626
17627#[inline]
17628#[must_use]
17629const fn limbs_pow_7(base: Limbs<7>, exp: Limbs<7>) -> Limbs<7> {
17630    let mut result = limbs_one_7();
17631    let mut b = base;
17632    let ew = exp.words();
17633    let mut word = 0usize;
17634    while word < 7 {
17635        let mut bit = 0u32;
17636        while bit < 64 {
17637            if ((ew[word] >> bit) & 1u64) == 1u64 {
17638                result = result.wrapping_mul(b);
17639            }
17640            b = b.wrapping_mul(b);
17641            bit += 1;
17642        }
17643        word += 1;
17644    }
17645    result
17646}
17647
17648#[inline]
17649#[must_use]
17650const fn limbs_is_zero_8(a: Limbs<8>) -> bool {
17651    let aw = a.words();
17652    let mut i = 0usize;
17653    while i < 8 {
17654        if aw[i] != 0 {
17655            return false;
17656        }
17657        i += 1;
17658    }
17659    true
17660}
17661
17662#[inline]
17663#[must_use]
17664const fn limbs_shl1_8(a: Limbs<8>) -> Limbs<8> {
17665    let aw = a.words();
17666    let mut out = [0u64; 8];
17667    let mut carry: u64 = 0;
17668    let mut i = 0usize;
17669    while i < 8 {
17670        let v = aw[i];
17671        out[i] = (v << 1) | carry;
17672        carry = v >> 63;
17673        i += 1;
17674    }
17675    Limbs::<8>::from_words(out)
17676}
17677
17678#[inline]
17679#[must_use]
17680const fn limbs_set_bit0_8(a: Limbs<8>) -> Limbs<8> {
17681    let aw = a.words();
17682    let mut out = [0u64; 8];
17683    let mut i = 0usize;
17684    while i < 8 {
17685        out[i] = aw[i];
17686        i += 1;
17687    }
17688    out[0] |= 1u64;
17689    Limbs::<8>::from_words(out)
17690}
17691
17692#[inline]
17693#[must_use]
17694const fn limbs_bit_msb_8(a: Limbs<8>, msb_index: usize) -> u64 {
17695    let aw = a.words();
17696    let total_bits = 8 * 64;
17697    let lsb_index = total_bits - 1 - msb_index;
17698    let word = lsb_index / 64;
17699    let bit = lsb_index % 64;
17700    (aw[word] >> bit) & 1u64
17701}
17702
17703#[inline]
17704#[must_use]
17705const fn limbs_divmod_8(a: Limbs<8>, b: Limbs<8>) -> (Limbs<8>, Limbs<8>) {
17706    let mut q = Limbs::<8>::zero();
17707    let mut r = Limbs::<8>::zero();
17708    let total_bits = 8 * 64;
17709    let mut i = 0usize;
17710    while i < total_bits {
17711        r = limbs_shl1_8(r);
17712        if limbs_bit_msb_8(a, i) == 1 {
17713            r = limbs_set_bit0_8(r);
17714        }
17715        if limbs_le_8(b, r) {
17716            r = r.wrapping_sub(b);
17717            q = limbs_shl1_8(q);
17718            q = limbs_set_bit0_8(q);
17719        } else {
17720            q = limbs_shl1_8(q);
17721        }
17722        i += 1;
17723    }
17724    (q, r)
17725}
17726
17727#[inline]
17728#[must_use]
17729const fn limbs_div_8(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
17730    let (q, _) = limbs_divmod_8(a, b);
17731    q
17732}
17733
17734#[inline]
17735#[must_use]
17736const fn limbs_mod_8(a: Limbs<8>, b: Limbs<8>) -> Limbs<8> {
17737    let (_, r) = limbs_divmod_8(a, b);
17738    r
17739}
17740
17741#[inline]
17742#[must_use]
17743const fn limbs_pow_8(base: Limbs<8>, exp: Limbs<8>) -> Limbs<8> {
17744    let mut result = limbs_one_8();
17745    let mut b = base;
17746    let ew = exp.words();
17747    let mut word = 0usize;
17748    while word < 8 {
17749        let mut bit = 0u32;
17750        while bit < 64 {
17751            if ((ew[word] >> bit) & 1u64) == 1u64 {
17752                result = result.wrapping_mul(b);
17753            }
17754            b = b.wrapping_mul(b);
17755            bit += 1;
17756        }
17757        word += 1;
17758    }
17759    result
17760}
17761
17762#[inline]
17763#[must_use]
17764const fn limbs_is_zero_9(a: Limbs<9>) -> bool {
17765    let aw = a.words();
17766    let mut i = 0usize;
17767    while i < 9 {
17768        if aw[i] != 0 {
17769            return false;
17770        }
17771        i += 1;
17772    }
17773    true
17774}
17775
17776#[inline]
17777#[must_use]
17778const fn limbs_shl1_9(a: Limbs<9>) -> Limbs<9> {
17779    let aw = a.words();
17780    let mut out = [0u64; 9];
17781    let mut carry: u64 = 0;
17782    let mut i = 0usize;
17783    while i < 9 {
17784        let v = aw[i];
17785        out[i] = (v << 1) | carry;
17786        carry = v >> 63;
17787        i += 1;
17788    }
17789    Limbs::<9>::from_words(out)
17790}
17791
17792#[inline]
17793#[must_use]
17794const fn limbs_set_bit0_9(a: Limbs<9>) -> Limbs<9> {
17795    let aw = a.words();
17796    let mut out = [0u64; 9];
17797    let mut i = 0usize;
17798    while i < 9 {
17799        out[i] = aw[i];
17800        i += 1;
17801    }
17802    out[0] |= 1u64;
17803    Limbs::<9>::from_words(out)
17804}
17805
17806#[inline]
17807#[must_use]
17808const fn limbs_bit_msb_9(a: Limbs<9>, msb_index: usize) -> u64 {
17809    let aw = a.words();
17810    let total_bits = 9 * 64;
17811    let lsb_index = total_bits - 1 - msb_index;
17812    let word = lsb_index / 64;
17813    let bit = lsb_index % 64;
17814    (aw[word] >> bit) & 1u64
17815}
17816
17817#[inline]
17818#[must_use]
17819const fn limbs_divmod_9(a: Limbs<9>, b: Limbs<9>) -> (Limbs<9>, Limbs<9>) {
17820    let mut q = Limbs::<9>::zero();
17821    let mut r = Limbs::<9>::zero();
17822    let total_bits = 9 * 64;
17823    let mut i = 0usize;
17824    while i < total_bits {
17825        r = limbs_shl1_9(r);
17826        if limbs_bit_msb_9(a, i) == 1 {
17827            r = limbs_set_bit0_9(r);
17828        }
17829        if limbs_le_9(b, r) {
17830            r = r.wrapping_sub(b);
17831            q = limbs_shl1_9(q);
17832            q = limbs_set_bit0_9(q);
17833        } else {
17834            q = limbs_shl1_9(q);
17835        }
17836        i += 1;
17837    }
17838    (q, r)
17839}
17840
17841#[inline]
17842#[must_use]
17843const fn limbs_div_9(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
17844    let (q, _) = limbs_divmod_9(a, b);
17845    q
17846}
17847
17848#[inline]
17849#[must_use]
17850const fn limbs_mod_9(a: Limbs<9>, b: Limbs<9>) -> Limbs<9> {
17851    let (_, r) = limbs_divmod_9(a, b);
17852    r
17853}
17854
17855#[inline]
17856#[must_use]
17857const fn limbs_pow_9(base: Limbs<9>, exp: Limbs<9>) -> Limbs<9> {
17858    let mut result = limbs_one_9();
17859    let mut b = base;
17860    let ew = exp.words();
17861    let mut word = 0usize;
17862    while word < 9 {
17863        let mut bit = 0u32;
17864        while bit < 64 {
17865            if ((ew[word] >> bit) & 1u64) == 1u64 {
17866                result = result.wrapping_mul(b);
17867            }
17868            b = b.wrapping_mul(b);
17869            bit += 1;
17870        }
17871        word += 1;
17872    }
17873    result
17874}
17875
17876#[inline]
17877#[must_use]
17878const fn limbs_is_zero_16(a: Limbs<16>) -> bool {
17879    let aw = a.words();
17880    let mut i = 0usize;
17881    while i < 16 {
17882        if aw[i] != 0 {
17883            return false;
17884        }
17885        i += 1;
17886    }
17887    true
17888}
17889
17890#[inline]
17891#[must_use]
17892const fn limbs_shl1_16(a: Limbs<16>) -> Limbs<16> {
17893    let aw = a.words();
17894    let mut out = [0u64; 16];
17895    let mut carry: u64 = 0;
17896    let mut i = 0usize;
17897    while i < 16 {
17898        let v = aw[i];
17899        out[i] = (v << 1) | carry;
17900        carry = v >> 63;
17901        i += 1;
17902    }
17903    Limbs::<16>::from_words(out)
17904}
17905
17906#[inline]
17907#[must_use]
17908const fn limbs_set_bit0_16(a: Limbs<16>) -> Limbs<16> {
17909    let aw = a.words();
17910    let mut out = [0u64; 16];
17911    let mut i = 0usize;
17912    while i < 16 {
17913        out[i] = aw[i];
17914        i += 1;
17915    }
17916    out[0] |= 1u64;
17917    Limbs::<16>::from_words(out)
17918}
17919
17920#[inline]
17921#[must_use]
17922const fn limbs_bit_msb_16(a: Limbs<16>, msb_index: usize) -> u64 {
17923    let aw = a.words();
17924    let total_bits = 16 * 64;
17925    let lsb_index = total_bits - 1 - msb_index;
17926    let word = lsb_index / 64;
17927    let bit = lsb_index % 64;
17928    (aw[word] >> bit) & 1u64
17929}
17930
17931#[inline]
17932#[must_use]
17933const fn limbs_divmod_16(a: Limbs<16>, b: Limbs<16>) -> (Limbs<16>, Limbs<16>) {
17934    let mut q = Limbs::<16>::zero();
17935    let mut r = Limbs::<16>::zero();
17936    let total_bits = 16 * 64;
17937    let mut i = 0usize;
17938    while i < total_bits {
17939        r = limbs_shl1_16(r);
17940        if limbs_bit_msb_16(a, i) == 1 {
17941            r = limbs_set_bit0_16(r);
17942        }
17943        if limbs_le_16(b, r) {
17944            r = r.wrapping_sub(b);
17945            q = limbs_shl1_16(q);
17946            q = limbs_set_bit0_16(q);
17947        } else {
17948            q = limbs_shl1_16(q);
17949        }
17950        i += 1;
17951    }
17952    (q, r)
17953}
17954
17955#[inline]
17956#[must_use]
17957const fn limbs_div_16(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
17958    let (q, _) = limbs_divmod_16(a, b);
17959    q
17960}
17961
17962#[inline]
17963#[must_use]
17964const fn limbs_mod_16(a: Limbs<16>, b: Limbs<16>) -> Limbs<16> {
17965    let (_, r) = limbs_divmod_16(a, b);
17966    r
17967}
17968
17969#[inline]
17970#[must_use]
17971const fn limbs_pow_16(base: Limbs<16>, exp: Limbs<16>) -> Limbs<16> {
17972    let mut result = limbs_one_16();
17973    let mut b = base;
17974    let ew = exp.words();
17975    let mut word = 0usize;
17976    while word < 16 {
17977        let mut bit = 0u32;
17978        while bit < 64 {
17979            if ((ew[word] >> bit) & 1u64) == 1u64 {
17980                result = result.wrapping_mul(b);
17981            }
17982            b = b.wrapping_mul(b);
17983            bit += 1;
17984        }
17985        word += 1;
17986    }
17987    result
17988}
17989
17990#[inline]
17991#[must_use]
17992const fn limbs_is_zero_32(a: Limbs<32>) -> bool {
17993    let aw = a.words();
17994    let mut i = 0usize;
17995    while i < 32 {
17996        if aw[i] != 0 {
17997            return false;
17998        }
17999        i += 1;
18000    }
18001    true
18002}
18003
18004#[inline]
18005#[must_use]
18006const fn limbs_shl1_32(a: Limbs<32>) -> Limbs<32> {
18007    let aw = a.words();
18008    let mut out = [0u64; 32];
18009    let mut carry: u64 = 0;
18010    let mut i = 0usize;
18011    while i < 32 {
18012        let v = aw[i];
18013        out[i] = (v << 1) | carry;
18014        carry = v >> 63;
18015        i += 1;
18016    }
18017    Limbs::<32>::from_words(out)
18018}
18019
18020#[inline]
18021#[must_use]
18022const fn limbs_set_bit0_32(a: Limbs<32>) -> Limbs<32> {
18023    let aw = a.words();
18024    let mut out = [0u64; 32];
18025    let mut i = 0usize;
18026    while i < 32 {
18027        out[i] = aw[i];
18028        i += 1;
18029    }
18030    out[0] |= 1u64;
18031    Limbs::<32>::from_words(out)
18032}
18033
18034#[inline]
18035#[must_use]
18036const fn limbs_bit_msb_32(a: Limbs<32>, msb_index: usize) -> u64 {
18037    let aw = a.words();
18038    let total_bits = 32 * 64;
18039    let lsb_index = total_bits - 1 - msb_index;
18040    let word = lsb_index / 64;
18041    let bit = lsb_index % 64;
18042    (aw[word] >> bit) & 1u64
18043}
18044
18045#[inline]
18046#[must_use]
18047const fn limbs_divmod_32(a: Limbs<32>, b: Limbs<32>) -> (Limbs<32>, Limbs<32>) {
18048    let mut q = Limbs::<32>::zero();
18049    let mut r = Limbs::<32>::zero();
18050    let total_bits = 32 * 64;
18051    let mut i = 0usize;
18052    while i < total_bits {
18053        r = limbs_shl1_32(r);
18054        if limbs_bit_msb_32(a, i) == 1 {
18055            r = limbs_set_bit0_32(r);
18056        }
18057        if limbs_le_32(b, r) {
18058            r = r.wrapping_sub(b);
18059            q = limbs_shl1_32(q);
18060            q = limbs_set_bit0_32(q);
18061        } else {
18062            q = limbs_shl1_32(q);
18063        }
18064        i += 1;
18065    }
18066    (q, r)
18067}
18068
18069#[inline]
18070#[must_use]
18071const fn limbs_div_32(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
18072    let (q, _) = limbs_divmod_32(a, b);
18073    q
18074}
18075
18076#[inline]
18077#[must_use]
18078const fn limbs_mod_32(a: Limbs<32>, b: Limbs<32>) -> Limbs<32> {
18079    let (_, r) = limbs_divmod_32(a, b);
18080    r
18081}
18082
18083#[inline]
18084#[must_use]
18085const fn limbs_pow_32(base: Limbs<32>, exp: Limbs<32>) -> Limbs<32> {
18086    let mut result = limbs_one_32();
18087    let mut b = base;
18088    let ew = exp.words();
18089    let mut word = 0usize;
18090    while word < 32 {
18091        let mut bit = 0u32;
18092        while bit < 64 {
18093            if ((ew[word] >> bit) & 1u64) == 1u64 {
18094                result = result.wrapping_mul(b);
18095            }
18096            b = b.wrapping_mul(b);
18097            bit += 1;
18098        }
18099        word += 1;
18100    }
18101    result
18102}
18103
18104#[inline]
18105#[must_use]
18106const fn limbs_is_zero_64(a: Limbs<64>) -> bool {
18107    let aw = a.words();
18108    let mut i = 0usize;
18109    while i < 64 {
18110        if aw[i] != 0 {
18111            return false;
18112        }
18113        i += 1;
18114    }
18115    true
18116}
18117
18118#[inline]
18119#[must_use]
18120const fn limbs_shl1_64(a: Limbs<64>) -> Limbs<64> {
18121    let aw = a.words();
18122    let mut out = [0u64; 64];
18123    let mut carry: u64 = 0;
18124    let mut i = 0usize;
18125    while i < 64 {
18126        let v = aw[i];
18127        out[i] = (v << 1) | carry;
18128        carry = v >> 63;
18129        i += 1;
18130    }
18131    Limbs::<64>::from_words(out)
18132}
18133
18134#[inline]
18135#[must_use]
18136const fn limbs_set_bit0_64(a: Limbs<64>) -> Limbs<64> {
18137    let aw = a.words();
18138    let mut out = [0u64; 64];
18139    let mut i = 0usize;
18140    while i < 64 {
18141        out[i] = aw[i];
18142        i += 1;
18143    }
18144    out[0] |= 1u64;
18145    Limbs::<64>::from_words(out)
18146}
18147
18148#[inline]
18149#[must_use]
18150const fn limbs_bit_msb_64(a: Limbs<64>, msb_index: usize) -> u64 {
18151    let aw = a.words();
18152    let total_bits = 64 * 64;
18153    let lsb_index = total_bits - 1 - msb_index;
18154    let word = lsb_index / 64;
18155    let bit = lsb_index % 64;
18156    (aw[word] >> bit) & 1u64
18157}
18158
18159#[inline]
18160#[must_use]
18161const fn limbs_divmod_64(a: Limbs<64>, b: Limbs<64>) -> (Limbs<64>, Limbs<64>) {
18162    let mut q = Limbs::<64>::zero();
18163    let mut r = Limbs::<64>::zero();
18164    let total_bits = 64 * 64;
18165    let mut i = 0usize;
18166    while i < total_bits {
18167        r = limbs_shl1_64(r);
18168        if limbs_bit_msb_64(a, i) == 1 {
18169            r = limbs_set_bit0_64(r);
18170        }
18171        if limbs_le_64(b, r) {
18172            r = r.wrapping_sub(b);
18173            q = limbs_shl1_64(q);
18174            q = limbs_set_bit0_64(q);
18175        } else {
18176            q = limbs_shl1_64(q);
18177        }
18178        i += 1;
18179    }
18180    (q, r)
18181}
18182
18183#[inline]
18184#[must_use]
18185const fn limbs_div_64(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
18186    let (q, _) = limbs_divmod_64(a, b);
18187    q
18188}
18189
18190#[inline]
18191#[must_use]
18192const fn limbs_mod_64(a: Limbs<64>, b: Limbs<64>) -> Limbs<64> {
18193    let (_, r) = limbs_divmod_64(a, b);
18194    r
18195}
18196
18197#[inline]
18198#[must_use]
18199const fn limbs_pow_64(base: Limbs<64>, exp: Limbs<64>) -> Limbs<64> {
18200    let mut result = limbs_one_64();
18201    let mut b = base;
18202    let ew = exp.words();
18203    let mut word = 0usize;
18204    while word < 64 {
18205        let mut bit = 0u32;
18206        while bit < 64 {
18207            if ((ew[word] >> bit) & 1u64) == 1u64 {
18208                result = result.wrapping_mul(b);
18209            }
18210            b = b.wrapping_mul(b);
18211            bit += 1;
18212        }
18213        word += 1;
18214    }
18215    result
18216}
18217
18218#[inline]
18219#[must_use]
18220const fn limbs_is_zero_128(a: Limbs<128>) -> bool {
18221    let aw = a.words();
18222    let mut i = 0usize;
18223    while i < 128 {
18224        if aw[i] != 0 {
18225            return false;
18226        }
18227        i += 1;
18228    }
18229    true
18230}
18231
18232#[inline]
18233#[must_use]
18234const fn limbs_shl1_128(a: Limbs<128>) -> Limbs<128> {
18235    let aw = a.words();
18236    let mut out = [0u64; 128];
18237    let mut carry: u64 = 0;
18238    let mut i = 0usize;
18239    while i < 128 {
18240        let v = aw[i];
18241        out[i] = (v << 1) | carry;
18242        carry = v >> 63;
18243        i += 1;
18244    }
18245    Limbs::<128>::from_words(out)
18246}
18247
18248#[inline]
18249#[must_use]
18250const fn limbs_set_bit0_128(a: Limbs<128>) -> Limbs<128> {
18251    let aw = a.words();
18252    let mut out = [0u64; 128];
18253    let mut i = 0usize;
18254    while i < 128 {
18255        out[i] = aw[i];
18256        i += 1;
18257    }
18258    out[0] |= 1u64;
18259    Limbs::<128>::from_words(out)
18260}
18261
18262#[inline]
18263#[must_use]
18264const fn limbs_bit_msb_128(a: Limbs<128>, msb_index: usize) -> u64 {
18265    let aw = a.words();
18266    let total_bits = 128 * 64;
18267    let lsb_index = total_bits - 1 - msb_index;
18268    let word = lsb_index / 64;
18269    let bit = lsb_index % 64;
18270    (aw[word] >> bit) & 1u64
18271}
18272
18273#[inline]
18274#[must_use]
18275const fn limbs_divmod_128(a: Limbs<128>, b: Limbs<128>) -> (Limbs<128>, Limbs<128>) {
18276    let mut q = Limbs::<128>::zero();
18277    let mut r = Limbs::<128>::zero();
18278    let total_bits = 128 * 64;
18279    let mut i = 0usize;
18280    while i < total_bits {
18281        r = limbs_shl1_128(r);
18282        if limbs_bit_msb_128(a, i) == 1 {
18283            r = limbs_set_bit0_128(r);
18284        }
18285        if limbs_le_128(b, r) {
18286            r = r.wrapping_sub(b);
18287            q = limbs_shl1_128(q);
18288            q = limbs_set_bit0_128(q);
18289        } else {
18290            q = limbs_shl1_128(q);
18291        }
18292        i += 1;
18293    }
18294    (q, r)
18295}
18296
18297#[inline]
18298#[must_use]
18299const fn limbs_div_128(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
18300    let (q, _) = limbs_divmod_128(a, b);
18301    q
18302}
18303
18304#[inline]
18305#[must_use]
18306const fn limbs_mod_128(a: Limbs<128>, b: Limbs<128>) -> Limbs<128> {
18307    let (_, r) = limbs_divmod_128(a, b);
18308    r
18309}
18310
18311#[inline]
18312#[must_use]
18313const fn limbs_pow_128(base: Limbs<128>, exp: Limbs<128>) -> Limbs<128> {
18314    let mut result = limbs_one_128();
18315    let mut b = base;
18316    let ew = exp.words();
18317    let mut word = 0usize;
18318    while word < 128 {
18319        let mut bit = 0u32;
18320        while bit < 64 {
18321            if ((ew[word] >> bit) & 1u64) == 1u64 {
18322                result = result.wrapping_mul(b);
18323            }
18324            b = b.wrapping_mul(b);
18325            bit += 1;
18326        }
18327        word += 1;
18328    }
18329    result
18330}
18331
18332#[inline]
18333#[must_use]
18334const fn limbs_is_zero_192(a: Limbs<192>) -> bool {
18335    let aw = a.words();
18336    let mut i = 0usize;
18337    while i < 192 {
18338        if aw[i] != 0 {
18339            return false;
18340        }
18341        i += 1;
18342    }
18343    true
18344}
18345
18346#[inline]
18347#[must_use]
18348const fn limbs_shl1_192(a: Limbs<192>) -> Limbs<192> {
18349    let aw = a.words();
18350    let mut out = [0u64; 192];
18351    let mut carry: u64 = 0;
18352    let mut i = 0usize;
18353    while i < 192 {
18354        let v = aw[i];
18355        out[i] = (v << 1) | carry;
18356        carry = v >> 63;
18357        i += 1;
18358    }
18359    Limbs::<192>::from_words(out)
18360}
18361
18362#[inline]
18363#[must_use]
18364const fn limbs_set_bit0_192(a: Limbs<192>) -> Limbs<192> {
18365    let aw = a.words();
18366    let mut out = [0u64; 192];
18367    let mut i = 0usize;
18368    while i < 192 {
18369        out[i] = aw[i];
18370        i += 1;
18371    }
18372    out[0] |= 1u64;
18373    Limbs::<192>::from_words(out)
18374}
18375
18376#[inline]
18377#[must_use]
18378const fn limbs_bit_msb_192(a: Limbs<192>, msb_index: usize) -> u64 {
18379    let aw = a.words();
18380    let total_bits = 192 * 64;
18381    let lsb_index = total_bits - 1 - msb_index;
18382    let word = lsb_index / 64;
18383    let bit = lsb_index % 64;
18384    (aw[word] >> bit) & 1u64
18385}
18386
18387#[inline]
18388#[must_use]
18389const fn limbs_divmod_192(a: Limbs<192>, b: Limbs<192>) -> (Limbs<192>, Limbs<192>) {
18390    let mut q = Limbs::<192>::zero();
18391    let mut r = Limbs::<192>::zero();
18392    let total_bits = 192 * 64;
18393    let mut i = 0usize;
18394    while i < total_bits {
18395        r = limbs_shl1_192(r);
18396        if limbs_bit_msb_192(a, i) == 1 {
18397            r = limbs_set_bit0_192(r);
18398        }
18399        if limbs_le_192(b, r) {
18400            r = r.wrapping_sub(b);
18401            q = limbs_shl1_192(q);
18402            q = limbs_set_bit0_192(q);
18403        } else {
18404            q = limbs_shl1_192(q);
18405        }
18406        i += 1;
18407    }
18408    (q, r)
18409}
18410
18411#[inline]
18412#[must_use]
18413const fn limbs_div_192(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
18414    let (q, _) = limbs_divmod_192(a, b);
18415    q
18416}
18417
18418#[inline]
18419#[must_use]
18420const fn limbs_mod_192(a: Limbs<192>, b: Limbs<192>) -> Limbs<192> {
18421    let (_, r) = limbs_divmod_192(a, b);
18422    r
18423}
18424
18425#[inline]
18426#[must_use]
18427const fn limbs_pow_192(base: Limbs<192>, exp: Limbs<192>) -> Limbs<192> {
18428    let mut result = limbs_one_192();
18429    let mut b = base;
18430    let ew = exp.words();
18431    let mut word = 0usize;
18432    while word < 192 {
18433        let mut bit = 0u32;
18434        while bit < 64 {
18435            if ((ew[word] >> bit) & 1u64) == 1u64 {
18436                result = result.wrapping_mul(b);
18437            }
18438            b = b.wrapping_mul(b);
18439            bit += 1;
18440        }
18441        word += 1;
18442    }
18443    result
18444}
18445
18446#[inline]
18447#[must_use]
18448const fn limbs_is_zero_256(a: Limbs<256>) -> bool {
18449    let aw = a.words();
18450    let mut i = 0usize;
18451    while i < 256 {
18452        if aw[i] != 0 {
18453            return false;
18454        }
18455        i += 1;
18456    }
18457    true
18458}
18459
18460#[inline]
18461#[must_use]
18462const fn limbs_shl1_256(a: Limbs<256>) -> Limbs<256> {
18463    let aw = a.words();
18464    let mut out = [0u64; 256];
18465    let mut carry: u64 = 0;
18466    let mut i = 0usize;
18467    while i < 256 {
18468        let v = aw[i];
18469        out[i] = (v << 1) | carry;
18470        carry = v >> 63;
18471        i += 1;
18472    }
18473    Limbs::<256>::from_words(out)
18474}
18475
18476#[inline]
18477#[must_use]
18478const fn limbs_set_bit0_256(a: Limbs<256>) -> Limbs<256> {
18479    let aw = a.words();
18480    let mut out = [0u64; 256];
18481    let mut i = 0usize;
18482    while i < 256 {
18483        out[i] = aw[i];
18484        i += 1;
18485    }
18486    out[0] |= 1u64;
18487    Limbs::<256>::from_words(out)
18488}
18489
18490#[inline]
18491#[must_use]
18492const fn limbs_bit_msb_256(a: Limbs<256>, msb_index: usize) -> u64 {
18493    let aw = a.words();
18494    let total_bits = 256 * 64;
18495    let lsb_index = total_bits - 1 - msb_index;
18496    let word = lsb_index / 64;
18497    let bit = lsb_index % 64;
18498    (aw[word] >> bit) & 1u64
18499}
18500
18501#[inline]
18502#[must_use]
18503const fn limbs_divmod_256(a: Limbs<256>, b: Limbs<256>) -> (Limbs<256>, Limbs<256>) {
18504    let mut q = Limbs::<256>::zero();
18505    let mut r = Limbs::<256>::zero();
18506    let total_bits = 256 * 64;
18507    let mut i = 0usize;
18508    while i < total_bits {
18509        r = limbs_shl1_256(r);
18510        if limbs_bit_msb_256(a, i) == 1 {
18511            r = limbs_set_bit0_256(r);
18512        }
18513        if limbs_le_256(b, r) {
18514            r = r.wrapping_sub(b);
18515            q = limbs_shl1_256(q);
18516            q = limbs_set_bit0_256(q);
18517        } else {
18518            q = limbs_shl1_256(q);
18519        }
18520        i += 1;
18521    }
18522    (q, r)
18523}
18524
18525#[inline]
18526#[must_use]
18527const fn limbs_div_256(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
18528    let (q, _) = limbs_divmod_256(a, b);
18529    q
18530}
18531
18532#[inline]
18533#[must_use]
18534const fn limbs_mod_256(a: Limbs<256>, b: Limbs<256>) -> Limbs<256> {
18535    let (_, r) = limbs_divmod_256(a, b);
18536    r
18537}
18538
18539#[inline]
18540#[must_use]
18541const fn limbs_pow_256(base: Limbs<256>, exp: Limbs<256>) -> Limbs<256> {
18542    let mut result = limbs_one_256();
18543    let mut b = base;
18544    let ew = exp.words();
18545    let mut word = 0usize;
18546    while word < 256 {
18547        let mut bit = 0u32;
18548        while bit < 64 {
18549            if ((ew[word] >> bit) & 1u64) == 1u64 {
18550                result = result.wrapping_mul(b);
18551            }
18552            b = b.wrapping_mul(b);
18553            bit += 1;
18554        }
18555        word += 1;
18556    }
18557    result
18558}
18559
18560#[inline]
18561#[must_use]
18562const fn limbs_is_zero_512(a: Limbs<512>) -> bool {
18563    let aw = a.words();
18564    let mut i = 0usize;
18565    while i < 512 {
18566        if aw[i] != 0 {
18567            return false;
18568        }
18569        i += 1;
18570    }
18571    true
18572}
18573
18574#[inline]
18575#[must_use]
18576const fn limbs_shl1_512(a: Limbs<512>) -> Limbs<512> {
18577    let aw = a.words();
18578    let mut out = [0u64; 512];
18579    let mut carry: u64 = 0;
18580    let mut i = 0usize;
18581    while i < 512 {
18582        let v = aw[i];
18583        out[i] = (v << 1) | carry;
18584        carry = v >> 63;
18585        i += 1;
18586    }
18587    Limbs::<512>::from_words(out)
18588}
18589
18590#[inline]
18591#[must_use]
18592const fn limbs_set_bit0_512(a: Limbs<512>) -> Limbs<512> {
18593    let aw = a.words();
18594    let mut out = [0u64; 512];
18595    let mut i = 0usize;
18596    while i < 512 {
18597        out[i] = aw[i];
18598        i += 1;
18599    }
18600    out[0] |= 1u64;
18601    Limbs::<512>::from_words(out)
18602}
18603
18604#[inline]
18605#[must_use]
18606const fn limbs_bit_msb_512(a: Limbs<512>, msb_index: usize) -> u64 {
18607    let aw = a.words();
18608    let total_bits = 512 * 64;
18609    let lsb_index = total_bits - 1 - msb_index;
18610    let word = lsb_index / 64;
18611    let bit = lsb_index % 64;
18612    (aw[word] >> bit) & 1u64
18613}
18614
18615#[inline]
18616#[must_use]
18617const fn limbs_divmod_512(a: Limbs<512>, b: Limbs<512>) -> (Limbs<512>, Limbs<512>) {
18618    let mut q = Limbs::<512>::zero();
18619    let mut r = Limbs::<512>::zero();
18620    let total_bits = 512 * 64;
18621    let mut i = 0usize;
18622    while i < total_bits {
18623        r = limbs_shl1_512(r);
18624        if limbs_bit_msb_512(a, i) == 1 {
18625            r = limbs_set_bit0_512(r);
18626        }
18627        if limbs_le_512(b, r) {
18628            r = r.wrapping_sub(b);
18629            q = limbs_shl1_512(q);
18630            q = limbs_set_bit0_512(q);
18631        } else {
18632            q = limbs_shl1_512(q);
18633        }
18634        i += 1;
18635    }
18636    (q, r)
18637}
18638
18639#[inline]
18640#[must_use]
18641const fn limbs_div_512(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
18642    let (q, _) = limbs_divmod_512(a, b);
18643    q
18644}
18645
18646#[inline]
18647#[must_use]
18648const fn limbs_mod_512(a: Limbs<512>, b: Limbs<512>) -> Limbs<512> {
18649    let (_, r) = limbs_divmod_512(a, b);
18650    r
18651}
18652
18653#[inline]
18654#[must_use]
18655const fn limbs_pow_512(base: Limbs<512>, exp: Limbs<512>) -> Limbs<512> {
18656    let mut result = limbs_one_512();
18657    let mut b = base;
18658    let ew = exp.words();
18659    let mut word = 0usize;
18660    while word < 512 {
18661        let mut bit = 0u32;
18662        while bit < 64 {
18663            if ((ew[word] >> bit) & 1u64) == 1u64 {
18664                result = result.wrapping_mul(b);
18665            }
18666            b = b.wrapping_mul(b);
18667            bit += 1;
18668        }
18669        word += 1;
18670    }
18671    result
18672}
18673
18674/// Sealed marker trait for fragment classifiers (Is2SatShape, IsHornShape,
18675/// IsResidualFragment) emitted parametrically from the predicate individuals
18676/// referenced by `predicate:InhabitanceDispatchTable`.
18677pub trait FragmentMarker: fragment_sealed::Sealed {}
18678
18679mod fragment_sealed {
18680    /// Private supertrait.
18681    pub trait Sealed {}
18682    impl Sealed for super::Is2SatShape {}
18683    impl Sealed for super::IsHornShape {}
18684    impl Sealed for super::IsResidualFragment {}
18685}
18686
18687/// Fragment marker for `predicate:Is2SatShape`. Zero-sized.
18688#[derive(Debug, Default, Clone, Copy)]
18689pub struct Is2SatShape;
18690impl FragmentMarker for Is2SatShape {}
18691
18692/// Fragment marker for `predicate:IsHornShape`. Zero-sized.
18693#[derive(Debug, Default, Clone, Copy)]
18694pub struct IsHornShape;
18695impl FragmentMarker for IsHornShape {}
18696
18697/// Fragment marker for `predicate:IsResidualFragment`. Zero-sized.
18698#[derive(Debug, Default, Clone, Copy)]
18699pub struct IsResidualFragment;
18700impl FragmentMarker for IsResidualFragment {}
18701
18702/// A single dispatch rule entry pairing a predicate IRI, a target resolver
18703/// name, and an evaluation priority.
18704#[derive(Debug, Clone, Copy)]
18705pub struct DispatchRule {
18706    /// IRI of the predicate that selects this rule.
18707    pub predicate_iri: &'static str,
18708    /// IRI of the target resolver class invoked when the predicate holds.
18709    pub target_resolver_iri: &'static str,
18710    /// Evaluation order; lower values evaluate first.
18711    pub priority: u32,
18712}
18713
18714/// A static dispatch table — an ordered slice of `DispatchRule` entries.
18715pub type DispatchTable = &'static [DispatchRule];
18716
18717/// v0.2.1 dispatch table generated from `predicate:InhabitanceDispatchTable`.
18718pub const INHABITANCE_DISPATCH_TABLE: DispatchTable = &[
18719    DispatchRule {
18720        predicate_iri: "https://uor.foundation/predicate/Is2SatShape",
18721        target_resolver_iri: "https://uor.foundation/resolver/TwoSatDecider",
18722        priority: 0,
18723    },
18724    DispatchRule {
18725        predicate_iri: "https://uor.foundation/predicate/IsHornShape",
18726        target_resolver_iri: "https://uor.foundation/resolver/HornSatDecider",
18727        priority: 1,
18728    },
18729    DispatchRule {
18730        predicate_iri: "https://uor.foundation/predicate/IsResidualFragment",
18731        target_resolver_iri: "https://uor.foundation/resolver/ResidualVerdictResolver",
18732        priority: 2,
18733    },
18734];
18735
18736/// v0.2.1 `Deref` impl for `Validated<T: OntologyTarget>` so consumers can call
18737/// certificate methods directly: `cert.target_level()` rather than
18738/// `cert.inner().target_level()`. The bound `T: OntologyTarget` keeps the
18739/// auto-deref scoped to foundation-produced types.
18740impl<T: OntologyTarget> core::ops::Deref for Validated<T> {
18741    type Target = T;
18742    #[inline]
18743    fn deref(&self) -> &T {
18744        &self.inner
18745    }
18746}
18747
18748mod bound_constraint_sealed {
18749    /// Sealed supertrait for the closed Observable catalogue.
18750    pub trait ObservableSealed {}
18751    /// Sealed supertrait for the closed BoundShape catalogue.
18752    pub trait BoundShapeSealed {}
18753}
18754
18755/// Sealed marker trait identifying the closed catalogue of observables
18756/// admissible in BoundConstraint. Implemented by unit structs emitted
18757/// below per `observable:Observable` subclass referenced by a
18758/// BoundConstraint kind individual.
18759pub trait Observable: bound_constraint_sealed::ObservableSealed {
18760    /// Ontology IRI of this observable class.
18761    const IRI: &'static str;
18762}
18763
18764/// Sealed marker trait identifying the closed catalogue of bound shapes.
18765/// Exactly six individuals: EqualBound, LessEqBound, GreaterEqBound,
18766/// RangeContainBound, ResidueClassBound, AffineEqualBound.
18767pub trait BoundShape: bound_constraint_sealed::BoundShapeSealed {
18768    /// Ontology IRI of this bound shape individual.
18769    const IRI: &'static str;
18770}
18771
18772/// Observes a Datum's value modulo a configurable modulus.
18773#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18774pub struct ValueModObservable;
18775impl bound_constraint_sealed::ObservableSealed for ValueModObservable {}
18776impl Observable for ValueModObservable {
18777    const IRI: &'static str = "https://uor.foundation/observable/ValueModObservable";
18778}
18779
18780/// Distance between two ring elements under the Hamming metric.
18781#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18782pub struct HammingMetric;
18783impl bound_constraint_sealed::ObservableSealed for HammingMetric {}
18784impl Observable for HammingMetric {
18785    const IRI: &'static str = "https://uor.foundation/observable/HammingMetric";
18786}
18787
18788/// Observes the derivation depth of a Datum.
18789#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18790pub struct DerivationDepthObservable;
18791impl bound_constraint_sealed::ObservableSealed for DerivationDepthObservable {}
18792impl Observable for DerivationDepthObservable {
18793    const IRI: &'static str = "https://uor.foundation/derivation/DerivationDepthObservable";
18794}
18795
18796/// Observes the carry depth of a Datum in the W₂ tower.
18797#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18798pub struct CarryDepthObservable;
18799impl bound_constraint_sealed::ObservableSealed for CarryDepthObservable {}
18800impl Observable for CarryDepthObservable {
18801    const IRI: &'static str = "https://uor.foundation/carry/CarryDepthObservable";
18802}
18803
18804/// Observes the free-rank of the partition associated with a Datum.
18805#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18806pub struct FreeRankObservable;
18807impl bound_constraint_sealed::ObservableSealed for FreeRankObservable {}
18808impl Observable for FreeRankObservable {
18809    const IRI: &'static str = "https://uor.foundation/partition/FreeRankObservable";
18810}
18811
18812/// Predicate form: `observable(datum) == target`.
18813#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18814pub struct EqualBound;
18815impl bound_constraint_sealed::BoundShapeSealed for EqualBound {}
18816impl BoundShape for EqualBound {
18817    const IRI: &'static str = "https://uor.foundation/type/EqualBound";
18818}
18819
18820/// Predicate form: `observable(datum) <= bound`.
18821#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18822pub struct LessEqBound;
18823impl bound_constraint_sealed::BoundShapeSealed for LessEqBound {}
18824impl BoundShape for LessEqBound {
18825    const IRI: &'static str = "https://uor.foundation/type/LessEqBound";
18826}
18827
18828/// Predicate form: `observable(datum) >= bound`.
18829#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18830pub struct GreaterEqBound;
18831impl bound_constraint_sealed::BoundShapeSealed for GreaterEqBound {}
18832impl BoundShape for GreaterEqBound {
18833    const IRI: &'static str = "https://uor.foundation/type/GreaterEqBound";
18834}
18835
18836/// Predicate form: `lo <= observable(datum) <= hi`.
18837#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18838pub struct RangeContainBound;
18839impl bound_constraint_sealed::BoundShapeSealed for RangeContainBound {}
18840impl BoundShape for RangeContainBound {
18841    const IRI: &'static str = "https://uor.foundation/type/RangeContainBound";
18842}
18843
18844/// Predicate form: `observable(datum) ≡ residue (mod modulus)`.
18845#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18846pub struct ResidueClassBound;
18847impl bound_constraint_sealed::BoundShapeSealed for ResidueClassBound {}
18848impl BoundShape for ResidueClassBound {
18849    const IRI: &'static str = "https://uor.foundation/type/ResidueClassBound";
18850}
18851
18852/// Predicate form: `observable(datum) == offset + affine combination`.
18853#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18854pub struct AffineEqualBound;
18855impl bound_constraint_sealed::BoundShapeSealed for AffineEqualBound {}
18856impl BoundShape for AffineEqualBound {
18857    const IRI: &'static str = "https://uor.foundation/type/AffineEqualBound";
18858}
18859
18860/// Parameter value type for `BoundConstraint` arguments.
18861/// Sealed enum over the closed set of primitive kinds the bound-shape
18862/// catalogue requires. No heap, no `String`.
18863#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18864pub enum BoundArgValue {
18865    /// Unsigned 64-bit integer.
18866    U64(u64),
18867    /// Signed 64-bit integer.
18868    I64(i64),
18869    /// Fixed 32-byte content-addressed value.
18870    Bytes32([u8; 32]),
18871}
18872
18873/// Fixed-size arguments carrier for a `BoundConstraint`.
18874/// Holds up to eight `(name, value)` pairs inline. The closed
18875/// bound-shape catalogue requires at most three parameters per kind;
18876/// the extra slots are reserved for future kind additions without
18877/// changing the carrier layout.
18878#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18879pub struct BoundArguments {
18880    entries: [Option<BoundArgEntry>; 8],
18881}
18882
18883/// A single named parameter in a `BoundArguments` table.
18884#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18885pub struct BoundArgEntry {
18886    /// Parameter name (a `&'static str` intentional over heap-owned).
18887    pub name: &'static str,
18888    /// Parameter value.
18889    pub value: BoundArgValue,
18890}
18891
18892impl BoundArguments {
18893    /// Construct an empty argument table.
18894    #[inline]
18895    #[must_use]
18896    pub const fn empty() -> Self {
18897        Self { entries: [None; 8] }
18898    }
18899
18900    /// Construct a table with a single `(name, value)` pair.
18901    #[inline]
18902    #[must_use]
18903    pub const fn single(name: &'static str, value: BoundArgValue) -> Self {
18904        let mut entries = [None; 8];
18905        entries[0] = Some(BoundArgEntry { name, value });
18906        Self { entries }
18907    }
18908
18909    /// Construct a table with two `(name, value)` pairs.
18910    #[inline]
18911    #[must_use]
18912    pub const fn pair(
18913        first: (&'static str, BoundArgValue),
18914        second: (&'static str, BoundArgValue),
18915    ) -> Self {
18916        let mut entries = [None; 8];
18917        entries[0] = Some(BoundArgEntry {
18918            name: first.0,
18919            value: first.1,
18920        });
18921        entries[1] = Some(BoundArgEntry {
18922            name: second.0,
18923            value: second.1,
18924        });
18925        Self { entries }
18926    }
18927
18928    /// Access the stored entries.
18929    #[inline]
18930    #[must_use]
18931    pub const fn entries(&self) -> &[Option<BoundArgEntry>; 8] {
18932        &self.entries
18933    }
18934}
18935
18936/// Parametric constraint carrier (v0.2.2 Phase D).
18937/// Generic over `O: Observable` and `B: BoundShape`. The seven
18938/// legacy constraint kinds are preserved as type aliases over this
18939/// carrier; see `ResidueConstraint`, `HammingConstraint`, etc. below.
18940#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18941pub struct BoundConstraint<O: Observable, B: BoundShape> {
18942    observable: O,
18943    bound: B,
18944    args: BoundArguments,
18945    _sealed: (),
18946}
18947
18948impl<O: Observable, B: BoundShape> BoundConstraint<O, B> {
18949    /// Crate-internal constructor. Downstream obtains values through
18950    /// the per-type-alias `pub const fn new` constructors.
18951    #[inline]
18952    #[must_use]
18953    pub(crate) const fn from_parts(observable: O, bound: B, args: BoundArguments) -> Self {
18954        Self {
18955            observable,
18956            bound,
18957            args,
18958            _sealed: (),
18959        }
18960    }
18961
18962    /// Access the bound observable.
18963    #[inline]
18964    #[must_use]
18965    pub const fn observable(&self) -> &O {
18966        &self.observable
18967    }
18968
18969    /// Access the bound shape.
18970    #[inline]
18971    #[must_use]
18972    pub const fn bound(&self) -> &B {
18973        &self.bound
18974    }
18975
18976    /// Access the bound arguments.
18977    #[inline]
18978    #[must_use]
18979    pub const fn args(&self) -> &BoundArguments {
18980        &self.args
18981    }
18982}
18983
18984/// Parametric conjunction of `BoundConstraint` kinds (v0.2.2 Phase D).
18985/// Replaces the v0.2.1 `CompositeConstraint` enumeration; the legacy
18986/// name survives as the type alias `CompositeConstraint<N>` below.
18987#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18988pub struct Conjunction<const N: usize> {
18989    len: usize,
18990    _sealed: (),
18991}
18992
18993impl<const N: usize> Conjunction<N> {
18994    /// Construct a new Conjunction with `len` conjuncts.
18995    #[inline]
18996    #[must_use]
18997    pub const fn new(len: usize) -> Self {
18998        Self { len, _sealed: () }
18999    }
19000
19001    /// The number of conjuncts in this Conjunction.
19002    #[inline]
19003    #[must_use]
19004    pub const fn len(&self) -> usize {
19005        self.len
19006    }
19007
19008    /// Whether the Conjunction is empty.
19009    #[inline]
19010    #[must_use]
19011    pub const fn is_empty(&self) -> bool {
19012        self.len == 0
19013    }
19014}
19015
19016/// v0.2.1 legacy type alias: a `BoundConstraint` kind asserting
19017/// residue-class membership (`value mod m == r`).
19018pub type ResidueConstraint = BoundConstraint<ValueModObservable, ResidueClassBound>;
19019
19020impl ResidueConstraint {
19021    /// Construct a residue constraint with the given modulus and residue.
19022    #[inline]
19023    #[must_use]
19024    pub const fn new(modulus: u64, residue: u64) -> Self {
19025        let args = BoundArguments::pair(
19026            ("modulus", BoundArgValue::U64(modulus)),
19027            ("residue", BoundArgValue::U64(residue)),
19028        );
19029        BoundConstraint::from_parts(ValueModObservable, ResidueClassBound, args)
19030    }
19031}
19032
19033/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
19034/// Hamming weight of the Datum (`weight <= bound`).
19035pub type HammingConstraint = BoundConstraint<HammingMetric, LessEqBound>;
19036
19037impl HammingConstraint {
19038    /// Construct a Hamming constraint with the given upper bound.
19039    #[inline]
19040    #[must_use]
19041    pub const fn new(bound: u64) -> Self {
19042        let args = BoundArguments::single("bound", BoundArgValue::U64(bound));
19043        BoundConstraint::from_parts(HammingMetric, LessEqBound, args)
19044    }
19045}
19046
19047/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
19048/// derivation depth of the Datum.
19049pub type DepthConstraint = BoundConstraint<DerivationDepthObservable, LessEqBound>;
19050
19051impl DepthConstraint {
19052    /// Construct a depth constraint with min and max depths.
19053    #[inline]
19054    #[must_use]
19055    pub const fn new(min_depth: u64, max_depth: u64) -> Self {
19056        let args = BoundArguments::pair(
19057            ("min_depth", BoundArgValue::U64(min_depth)),
19058            ("max_depth", BoundArgValue::U64(max_depth)),
19059        );
19060        BoundConstraint::from_parts(DerivationDepthObservable, LessEqBound, args)
19061    }
19062}
19063
19064/// v0.2.1 legacy type alias: a `BoundConstraint` kind bounding the
19065/// carry depth of the Datum in the W₂ tower.
19066pub type CarryConstraint = BoundConstraint<CarryDepthObservable, LessEqBound>;
19067
19068impl CarryConstraint {
19069    /// Construct a carry constraint with the given upper bound.
19070    #[inline]
19071    #[must_use]
19072    pub const fn new(bound: u64) -> Self {
19073        let args = BoundArguments::single("bound", BoundArgValue::U64(bound));
19074        BoundConstraint::from_parts(CarryDepthObservable, LessEqBound, args)
19075    }
19076}
19077
19078/// v0.2.1 legacy type alias: a `BoundConstraint` kind pinning a
19079/// single site coordinate.
19080pub type SiteConstraint = BoundConstraint<FreeRankObservable, LessEqBound>;
19081
19082impl SiteConstraint {
19083    /// Construct a site constraint with the given site index.
19084    #[inline]
19085    #[must_use]
19086    pub const fn new(site_index: u64) -> Self {
19087        let args = BoundArguments::single("site_index", BoundArgValue::U64(site_index));
19088        BoundConstraint::from_parts(FreeRankObservable, LessEqBound, args)
19089    }
19090}
19091
19092/// v0.2.1 legacy type alias: a `BoundConstraint` kind pinning an
19093/// affine relationship on the Datum's value projection.
19094pub type AffineConstraint = BoundConstraint<ValueModObservable, AffineEqualBound>;
19095
19096impl AffineConstraint {
19097    /// Construct an affine constraint with the given offset.
19098    #[inline]
19099    #[must_use]
19100    pub const fn new(offset: u64) -> Self {
19101        let args = BoundArguments::single("offset", BoundArgValue::U64(offset));
19102        BoundConstraint::from_parts(ValueModObservable, AffineEqualBound, args)
19103    }
19104}
19105
19106/// v0.2.1 legacy type alias: a `Conjunction` over `N` BoundConstraint
19107/// kinds (`CompositeConstraint<3>` = 3-way conjunction).
19108pub type CompositeConstraint<const N: usize> = Conjunction<N>;
19109
19110/// v0.2.2 Phase E: sealed query handle.
19111#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19112pub struct Query {
19113    address: ContentAddress,
19114    _sealed: (),
19115}
19116
19117impl Query {
19118    /// Returns the content-hashed query address.
19119    #[inline]
19120    #[must_use]
19121    pub const fn address(&self) -> ContentAddress {
19122        self.address
19123    }
19124
19125    /// Crate-internal constructor.
19126    #[inline]
19127    #[must_use]
19128    #[allow(dead_code)]
19129    pub(crate) const fn new(address: ContentAddress) -> Self {
19130        Self {
19131            address,
19132            _sealed: (),
19133        }
19134    }
19135}
19136
19137/// v0.2.2 Phase E: typed query coordinate parametric over WittLevel.
19138#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19139pub struct Coordinate<L> {
19140    stratum: u64,
19141    spectrum: u64,
19142    address: u64,
19143    _level: PhantomData<L>,
19144    _sealed: (),
19145}
19146
19147impl<L> Coordinate<L> {
19148    /// Returns the stratum coordinate.
19149    #[inline]
19150    #[must_use]
19151    pub const fn stratum(&self) -> u64 {
19152        self.stratum
19153    }
19154
19155    /// Returns the spectrum coordinate.
19156    #[inline]
19157    #[must_use]
19158    pub const fn spectrum(&self) -> u64 {
19159        self.spectrum
19160    }
19161
19162    /// Returns the address coordinate.
19163    #[inline]
19164    #[must_use]
19165    pub const fn address(&self) -> u64 {
19166        self.address
19167    }
19168
19169    /// Crate-internal constructor.
19170    #[inline]
19171    #[must_use]
19172    #[allow(dead_code)]
19173    pub(crate) const fn new(stratum: u64, spectrum: u64, address: u64) -> Self {
19174        Self {
19175            stratum,
19176            spectrum,
19177            address,
19178            _level: PhantomData,
19179            _sealed: (),
19180        }
19181    }
19182}
19183
19184/// v0.2.2 Phase E: sealed binding query handle.
19185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19186pub struct BindingQuery {
19187    address: ContentAddress,
19188    _sealed: (),
19189}
19190
19191impl BindingQuery {
19192    /// Returns the content-hashed binding query address.
19193    #[inline]
19194    #[must_use]
19195    pub const fn address(&self) -> ContentAddress {
19196        self.address
19197    }
19198
19199    /// Crate-internal constructor.
19200    #[inline]
19201    #[must_use]
19202    #[allow(dead_code)]
19203    pub(crate) const fn new(address: ContentAddress) -> Self {
19204        Self {
19205            address,
19206            _sealed: (),
19207        }
19208    }
19209}
19210
19211/// v0.2.2 Phase E: sealed Partition handle over the bridge:partition
19212/// component classification produced during grounding.
19213#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19214pub struct Partition {
19215    component: PartitionComponent,
19216    _sealed: (),
19217}
19218
19219impl Partition {
19220    /// Returns the component classification.
19221    #[inline]
19222    #[must_use]
19223    pub const fn component(&self) -> PartitionComponent {
19224        self.component
19225    }
19226
19227    /// Crate-internal constructor.
19228    #[inline]
19229    #[must_use]
19230    #[allow(dead_code)]
19231    pub(crate) const fn new(component: PartitionComponent) -> Self {
19232        Self {
19233            component,
19234            _sealed: (),
19235        }
19236    }
19237}
19238
19239/// v0.2.2 Phase E: a single event in a derivation Trace.
19240/// Fixed-size event; content-addressed so Trace replays are stable
19241/// across builds. The verifier in `uor-foundation-verify` (Phase H)
19242/// reconstructs the witness chain by walking a `Trace` iterator.
19243#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19244pub struct TraceEvent {
19245    /// Step index in the derivation.
19246    step_index: u32,
19247    /// Primitive op applied at this step.
19248    op: PrimitiveOp,
19249    /// Content-hashed target address the op produced.
19250    target: ContentAddress,
19251    /// Sealing marker.
19252    _sealed: (),
19253}
19254
19255impl TraceEvent {
19256    /// Returns the step index.
19257    #[inline]
19258    #[must_use]
19259    pub const fn step_index(&self) -> u32 {
19260        self.step_index
19261    }
19262
19263    /// Returns the primitive op applied at this step.
19264    #[inline]
19265    #[must_use]
19266    pub const fn op(&self) -> PrimitiveOp {
19267        self.op
19268    }
19269
19270    /// Returns the content-hashed target address.
19271    #[inline]
19272    #[must_use]
19273    pub const fn target(&self) -> ContentAddress {
19274        self.target
19275    }
19276
19277    /// Crate-internal constructor.
19278    #[inline]
19279    #[must_use]
19280    #[allow(dead_code)]
19281    pub(crate) const fn new(step_index: u32, op: PrimitiveOp, target: ContentAddress) -> Self {
19282        Self {
19283            step_index,
19284            op,
19285            target,
19286            _sealed: (),
19287        }
19288    }
19289}
19290
19291/// Fixed-capacity derivation trace. Holds up to `TR_MAX` events inline;
19292/// no heap. Produced by `Derivation::replay()` and consumed by
19293/// `uor-foundation-verify`. `TR_MAX` is the const-generic that carries
19294/// the application's selected `<MyBounds as HostBounds>::TRACE_MAX_EVENTS`;
19295/// the default const-generic resolves to the conventional 256.
19296/// Carries `witt_level_bits` and `content_fingerprint` so `verify_trace`
19297/// can reconstruct the source `GroundingCertificate` via structural-
19298/// validation + fingerprint passthrough (no hash recomputation).
19299#[derive(Debug, Clone, Copy)]
19300pub struct Trace<const TR_MAX: usize = 256, const FP_MAX: usize = 32> {
19301    events: [Option<TraceEvent>; TR_MAX],
19302    len: u16,
19303    /// Witt level the source grounding was minted at, packed
19304    /// by `Derivation::replay` from the parent `Grounded::witt_level_bits`.
19305    /// `verify_trace` reads this back to populate the certificate.
19306    witt_level_bits: u16,
19307    /// Parametric content fingerprint of the source unit's full state,
19308    /// computed at grounding time by the consumer-supplied `Hasher` and
19309    /// packed in by `Derivation::replay`. `verify_trace` passes it through
19310    /// unchanged. The fingerprint's `FP_MAX` follows the application's
19311    /// selected `<MyBounds as HostBounds>::FINGERPRINT_MAX_BYTES`; this
19312    /// field uses the default-bound `ContentFingerprint`.
19313    content_fingerprint: ContentFingerprint<FP_MAX>,
19314    _sealed: (),
19315}
19316
19317impl<const TR_MAX: usize, const FP_MAX: usize> Trace<TR_MAX, FP_MAX> {
19318    /// An empty Trace.
19319    #[inline]
19320    #[must_use]
19321    pub const fn empty() -> Self {
19322        Self {
19323            events: [None; TR_MAX],
19324            len: 0,
19325            witt_level_bits: 0,
19326            content_fingerprint: ContentFingerprint::zero(),
19327            _sealed: (),
19328        }
19329    }
19330
19331    /// Crate-internal ctor for `Derivation::replay()` only.
19332    /// Bypasses validation because `replay()` constructs events from
19333    /// foundation-guaranteed-valid state (monotonic, contiguous, non-zero
19334    /// seed). No public path reaches this constructor; downstream uses the
19335    /// validating `try_from_events` instead.
19336    #[inline]
19337    #[must_use]
19338    #[allow(dead_code)]
19339    pub(crate) const fn from_replay_events_const(
19340        events: [Option<TraceEvent>; TR_MAX],
19341        len: u16,
19342        witt_level_bits: u16,
19343        content_fingerprint: ContentFingerprint<FP_MAX>,
19344    ) -> Self {
19345        Self {
19346            events,
19347            len,
19348            witt_level_bits,
19349            content_fingerprint,
19350            _sealed: (),
19351        }
19352    }
19353
19354    /// Number of events recorded.
19355    #[inline]
19356    #[must_use]
19357    pub const fn len(&self) -> u16 {
19358        self.len
19359    }
19360
19361    /// Whether the Trace is empty.
19362    #[inline]
19363    #[must_use]
19364    pub const fn is_empty(&self) -> bool {
19365        self.len == 0
19366    }
19367
19368    /// Access the event at the given index, or `None` if out of range.
19369    #[inline]
19370    #[must_use]
19371    pub fn event(&self, index: usize) -> Option<&TraceEvent> {
19372        self.events.get(index).and_then(|e| e.as_ref())
19373    }
19374
19375    /// v0.2.2 T5: returns the Witt level the source grounding was minted at.
19376    /// Carried through replay so `verify_trace` can populate the certificate.
19377    #[inline]
19378    #[must_use]
19379    pub const fn witt_level_bits(&self) -> u16 {
19380        self.witt_level_bits
19381    }
19382
19383    /// v0.2.2 T5: returns the parametric content fingerprint of the source
19384    /// unit, computed at grounding time by the consumer-supplied `Hasher`.
19385    /// `verify_trace` passes this through unchanged into the re-derived
19386    /// certificate, upholding the round-trip property.
19387    #[inline]
19388    #[must_use]
19389    pub const fn content_fingerprint(&self) -> ContentFingerprint<FP_MAX> {
19390        self.content_fingerprint
19391    }
19392
19393    /// Validating constructor. Checks every invariant the verify path
19394    /// relies on: events are contiguous from index 0, no event has a zero
19395    /// target, and the slice fits within `TR_MAX` events.
19396    /// # Errors
19397    /// - `ReplayError::EmptyTrace` if `events.is_empty()`.
19398    /// - `ReplayError::CapacityExceeded { declared, provided }` if the
19399    ///   slice exceeds `TR_MAX`.
19400    /// - `ReplayError::OutOfOrderEvent { index }` if the event at `index`
19401    ///   has a `step_index` not equal to `index` (strict contiguity).
19402    /// - `ReplayError::ZeroTarget { index }` if any event carries a zero
19403    ///   `ContentAddress` target.
19404    pub fn try_from_events(
19405        events: &[TraceEvent],
19406        witt_level_bits: u16,
19407        content_fingerprint: ContentFingerprint<FP_MAX>,
19408    ) -> Result<Self, ReplayError> {
19409        if events.is_empty() {
19410            return Err(ReplayError::EmptyTrace);
19411        }
19412        if events.len() > TR_MAX {
19413            return Err(ReplayError::CapacityExceeded {
19414                declared: TR_MAX as u16,
19415                provided: events.len() as u32,
19416            });
19417        }
19418        let mut i = 0usize;
19419        while i < events.len() {
19420            let e = &events[i];
19421            if e.step_index() as usize != i {
19422                return Err(ReplayError::OutOfOrderEvent { index: i });
19423            }
19424            if e.target().is_zero() {
19425                return Err(ReplayError::ZeroTarget { index: i });
19426            }
19427            i += 1;
19428        }
19429        let mut arr = [None; TR_MAX];
19430        let mut j = 0usize;
19431        while j < events.len() {
19432            arr[j] = Some(events[j]);
19433            j += 1;
19434        }
19435        Ok(Self {
19436            events: arr,
19437            len: events.len() as u16,
19438            witt_level_bits,
19439            content_fingerprint,
19440            _sealed: (),
19441        })
19442    }
19443}
19444
19445impl<const TR_MAX: usize> Default for Trace<TR_MAX> {
19446    #[inline]
19447    fn default() -> Self {
19448        Self::empty()
19449    }
19450}
19451
19452/// v0.2.2 Phase E / T2.6: `Derivation::replay()` produces a content-addressed
19453/// Trace the verifier can re-walk without invoking the deciders. The trace
19454/// length matches the derivation's `step_count()`, and each event's
19455/// `step_index` reflects its position in the derivation.
19456impl<const FP_MAX: usize> Derivation<FP_MAX> {
19457    /// Replay this derivation as a fixed-size `Trace<TR_MAX>` whose length matches
19458    /// `self.step_count()` (capped at the application's `<HostBounds>::TRACE_MAX_EVENTS`).
19459    /// Callers either annotate the binding (`let trace: Trace = ...;` picks
19460    /// `Trace`'s default `TR_MAX` of 256) or use turbofish (`derivation.replay::<1024>()`).
19461    /// # Example
19462    /// ```no_run
19463    /// use uor_foundation::enforcement::{
19464    ///     replay, CompileUnitBuilder, ConstrainedTypeInput, Grounded, Term, Trace,
19465    /// };
19466    /// use uor_foundation::pipeline::run;
19467    /// use uor_foundation::{VerificationDomain, WittLevel};
19468    /// # use uor_foundation::enforcement::Hasher;
19469    /// # struct H; impl Hasher for H {
19470    /// #     const OUTPUT_BYTES: usize = 16;
19471    /// #     fn initial() -> Self { Self }
19472    /// #     fn fold_byte(self, _: u8) -> Self { self }
19473    /// #     fn finalize(self) -> [u8; 32] { [0; 32] } }
19474    /// // ADR-060: `Term`/`Grounded` carry an `INLINE_BYTES` const-generic the
19475    /// // application derives from its `HostBounds`; fix a concrete width and
19476    /// // thread it through `run`'s 4th const argument.
19477    /// const N: usize = 32;
19478    /// let terms: [Term<'static, N>; 1] = [uor_foundation::pipeline::literal_u64(7, WittLevel::W8)];
19479    /// let doms: [VerificationDomain; 1] = [VerificationDomain::Enumerative];
19480    /// let unit = CompileUnitBuilder::<N>::new()
19481    ///     .root_term(&terms).witt_level_ceiling(WittLevel::W32)
19482    ///     .thermodynamic_budget(1024).target_domains(&doms)
19483    ///     .result_type::<ConstrainedTypeInput>()
19484    ///     .validate().expect("unit well-formed");
19485    /// let grounded: Grounded<ConstrainedTypeInput, N, 32> =
19486    ///     run::<ConstrainedTypeInput, _, H, N, 32>(unit).expect("grounds");
19487    /// // Replay → round-trip verification. The trace's event-count
19488    /// // capacity comes from the application's `HostBounds`; here the
19489    /// // type-annotated binding defaults `Trace`'s `TR_MAX` to 256.
19490    /// let trace: Trace = grounded.derivation().replay();
19491    /// let recert = replay::certify_from_trace(&trace).expect("valid trace");
19492    /// assert_eq!(recert.certificate().content_fingerprint(),
19493    ///            grounded.content_fingerprint());
19494    /// ```
19495    #[inline]
19496    #[must_use]
19497    pub fn replay<const TR_MAX: usize>(&self) -> Trace<TR_MAX, FP_MAX> {
19498        let steps = self.step_count() as usize;
19499        let len = if steps > TR_MAX { TR_MAX } else { steps };
19500        let mut events = [None; TR_MAX];
19501        // Seed targets from the leading 8 bytes of the source
19502        // `content_fingerprint` (substrate-computed). Combined with `| 1` so
19503        // the first event's target is guaranteed nonzero even when the
19504        // leading bytes are all zero, and XOR with `(i + 1)` keeps the
19505        // sequence non-degenerate.
19506        let fp = self.content_fingerprint.as_bytes();
19507        let seed =
19508            u64::from_be_bytes([fp[0], fp[1], fp[2], fp[3], fp[4], fp[5], fp[6], fp[7]]) as u128;
19509        let nonzero_seed = seed | 1u128;
19510        let mut i = 0usize;
19511        while i < len {
19512            let target_raw = nonzero_seed ^ ((i as u128) + 1u128);
19513            events[i] = Some(TraceEvent::new(
19514                i as u32,
19515                crate::PrimitiveOp::Add,
19516                ContentAddress::from_u128(target_raw),
19517            ));
19518            i += 1;
19519        }
19520        // Pack the source `witt_level_bits` and `content_fingerprint`
19521        // into the Trace so `verify_trace` can reproduce the source certificate
19522        // via passthrough. The fingerprint was computed at grounding time by the
19523        // consumer-supplied Hasher and stored on the parent Grounded; the
19524        // Derivation accessor read it through.
19525        Trace::from_replay_events_const(
19526            events,
19527            len as u16,
19528            self.witt_level_bits,
19529            self.content_fingerprint,
19530        )
19531    }
19532}
19533
19534/// v0.2.2 T5: errors emitted by the trace-replay re-derivation path.
19535#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19536#[non_exhaustive]
19537pub enum ReplayError {
19538    /// The trace was empty; nothing to replay.
19539    EmptyTrace,
19540    /// Event at `index` has a non-monotonic step_index.
19541    OutOfOrderEvent {
19542        /// The event index that was out of order.
19543        index: usize,
19544    },
19545    /// Event at `index` carries a zero ContentAddress (forbidden in well-formed traces).
19546    ZeroTarget {
19547        /// The event index that carried a zero target.
19548        index: usize,
19549    },
19550    /// v0.2.2 T5.8: event step indices do not form a contiguous sequence
19551    /// `[0, 1, ..., len-1]`. Replaces the misleadingly-named v0.2.1
19552    /// `LengthMismatch` variant. The trace has the right number of
19553    /// events, but their step indices skip values (e.g., `[0, 2, 5]`
19554    /// with `len = 3`).
19555    NonContiguousSteps {
19556        /// The trace's declared length (number of events).
19557        declared: u16,
19558        /// The largest step_index observed in the event sequence.
19559        /// Always strictly greater than `declared - 1` when this
19560        /// variant fires.
19561        last_step: u32,
19562    },
19563    /// A caller attempted to construct a `Trace<TR_MAX>` whose event count
19564    /// exceeds `TR_MAX` (the application's `<HostBounds>::TRACE_MAX_EVENTS`).
19565    /// Distinct from `NonContiguousSteps` because the recovery is different
19566    /// (truncate vs. close gaps). Returned by `Trace::try_from_events`,
19567    /// never by `verify_trace` (the verifier reads from an existing `Trace`
19568    /// whose capacity is already enforced by the type's storage).
19569    CapacityExceeded {
19570        /// The trace's hard capacity (`TR_MAX`).
19571        declared: u16,
19572        /// The actual event count the caller attempted to pack in.
19573        provided: u32,
19574    },
19575}
19576
19577impl core::fmt::Display for ReplayError {
19578    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19579        match self {
19580            Self::EmptyTrace => f.write_str("trace was empty; nothing to replay"),
19581            Self::OutOfOrderEvent { index } => write!(
19582                f,
19583                "event at index {index} has out-of-order step index",
19584            ),
19585            Self::ZeroTarget { index } => write!(
19586                f,
19587                "event at index {index} has a zero ContentAddress target",
19588            ),
19589            Self::NonContiguousSteps { declared, last_step } => write!(
19590                f,
19591                "trace declares {declared} events but step indices skip values \
19592                 (last step {last_step})",
19593            ),
19594            Self::CapacityExceeded { declared, provided } => write!(
19595                f,
19596                "trace capacity exceeded: tried to pack {provided} events into a buffer of {declared}",
19597            ),
19598        }
19599    }
19600}
19601
19602impl core::error::Error for ReplayError {}
19603
19604/// v0.2.2 T5: trace-replay re-derivation module.
19605/// The foundation owns the certificate-construction boundary; the
19606/// `uor-foundation-verify` crate is a thin facade that delegates to
19607/// `replay::certify_from_trace`. This preserves sealing discipline:
19608/// `Certified::new` stays `pub(crate)` and no external crate can mint a
19609/// certificate.
19610pub mod replay {
19611    use super::{Certified, GroundingCertificate, ReplayError, Trace};
19612
19613    /// Re-derive the `Certified<GroundingCertificate>` that the foundation
19614    /// grounding path produced for the source unit.
19615    /// Validates the trace's structural invariants (monotonic, contiguous
19616    /// step indices; no zero targets; no None slots in the populated
19617    /// prefix) and re-packages the trace's stored `ContentFingerprint` and
19618    /// `witt_level_bits` into a fresh certificate. The verifier does NOT
19619    /// invoke a hash function: the fingerprint is *data carried by the
19620    /// Trace*, computed at mint time by the consumer-supplied `Hasher` and
19621    /// passed through unchanged.
19622    /// # Round-trip property
19623    /// For every `Grounded<T>` produced by `pipeline::run::<T, _, H>` with
19624    /// a conforming substrate `H: Hasher`:
19625    /// ```text
19626    /// verify_trace(&grounded.derivation().replay()).certificate()
19627    ///     == grounded.certificate()
19628    /// ```
19629    /// holds bit-identically. The contract is orthogonal to the substrate
19630    /// hasher choice and to the chosen `OUTPUT_BYTES` width.
19631    /// # Errors
19632    /// Returns:
19633    /// - `ReplayError::EmptyTrace` if `trace.is_empty()`.
19634    /// - `ReplayError::OutOfOrderEvent { index }` if step indices are not
19635    ///   strictly monotonic at position `index`.
19636    /// - `ReplayError::ZeroTarget { index }` if any event carries
19637    ///   `ContentAddress::zero()`.
19638    /// - `ReplayError::NonContiguousSteps { declared, last_step }` if
19639    ///   the event step indices skip values.
19640    pub fn certify_from_trace<const TR_MAX: usize, const FP_MAX: usize>(
19641        trace: &Trace<TR_MAX, FP_MAX>,
19642    ) -> Result<Certified<GroundingCertificate<FP_MAX>>, ReplayError> {
19643        let len = trace.len() as usize;
19644        if len == 0 {
19645            return Err(ReplayError::EmptyTrace);
19646        }
19647        // Structural validation: monotonic step indices, contiguous from 0,
19648        // no zero targets, no None slots in the populated prefix.
19649        let mut last_step: i64 = -1;
19650        let mut max_step_index: u32 = 0;
19651        let mut i = 0usize;
19652        while i < len {
19653            let event = match trace.event(i) {
19654                Some(e) => e,
19655                None => return Err(ReplayError::OutOfOrderEvent { index: i }),
19656            };
19657            let step_index = event.step_index();
19658            if (step_index as i64) <= last_step {
19659                return Err(ReplayError::OutOfOrderEvent { index: i });
19660            }
19661            if event.target().is_zero() {
19662                return Err(ReplayError::ZeroTarget { index: i });
19663            }
19664            if step_index > max_step_index {
19665                max_step_index = step_index;
19666            }
19667            last_step = step_index as i64;
19668            i += 1;
19669        }
19670        if (max_step_index as u16).saturating_add(1) != trace.len() {
19671            return Err(ReplayError::NonContiguousSteps {
19672                declared: trace.len(),
19673                last_step: max_step_index,
19674            });
19675        }
19676        // v0.2.2 T5: fingerprint passthrough. The trace was minted by the
19677        // foundation pipeline with a `ContentFingerprint` already computed by
19678        // the consumer-supplied `Hasher`. The verifier does not invoke any
19679        // hash function; it copies the fingerprint through unchanged. The
19680        // round-trip property holds by construction. v0.2.2 T6.5: the
19681        // FingerprintMissing variant is removed because under T6.3 / T6.10,
19682        // no public path can produce a Trace with a zero fingerprint.
19683        Ok(Certified::new(
19684            GroundingCertificate::with_level_and_fingerprint_const(
19685                trace.witt_level_bits(),
19686                trace.content_fingerprint(),
19687            ),
19688        ))
19689    }
19690}
19691
19692/// v0.2.2 Phase E: sealed builder for an InteractionDeclaration.
19693/// Validates the peer protocol, convergence predicate, and
19694/// commutator state class required by `conformance:InteractionShape`.
19695/// Phase F wires the full `InteractionDriver` on top of this builder.
19696#[derive(Debug, Clone, Copy, Default)]
19697pub struct InteractionDeclarationBuilder {
19698    peer_protocol: Option<u128>,
19699    convergence_predicate: Option<u128>,
19700    commutator_state_class: Option<u128>,
19701}
19702
19703impl InteractionDeclarationBuilder {
19704    /// Construct a new builder.
19705    #[inline]
19706    #[must_use]
19707    pub const fn new() -> Self {
19708        Self {
19709            peer_protocol: None,
19710            convergence_predicate: None,
19711            commutator_state_class: None,
19712        }
19713    }
19714
19715    /// Set the peer protocol content address.
19716    #[inline]
19717    #[must_use]
19718    pub const fn peer_protocol(mut self, address: u128) -> Self {
19719        self.peer_protocol = Some(address);
19720        self
19721    }
19722
19723    /// Set the convergence predicate content address.
19724    #[inline]
19725    #[must_use]
19726    pub const fn convergence_predicate(mut self, address: u128) -> Self {
19727        self.convergence_predicate = Some(address);
19728        self
19729    }
19730
19731    /// Set the commutator state class content address.
19732    #[inline]
19733    #[must_use]
19734    pub const fn commutator_state_class(mut self, address: u128) -> Self {
19735        self.commutator_state_class = Some(address);
19736        self
19737    }
19738
19739    /// Phase E.6: validate against `conformance:InteractionShape`.
19740    /// # Errors
19741    /// Returns `ShapeViolation` if any of the three required fields is missing.
19742    pub fn validate(&self) -> Result<Validated<InteractionShape>, ShapeViolation> {
19743        self.validate_common().map(|_| {
19744            Validated::new(InteractionShape {
19745                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19746            })
19747        })
19748    }
19749
19750    /// Phase E.6 + C.1: const-fn companion.
19751    /// # Errors
19752    /// Returns `ShapeViolation` if any required field is missing.
19753    pub const fn validate_const(
19754        &self,
19755    ) -> Result<Validated<InteractionShape, CompileTime>, ShapeViolation> {
19756        if self.peer_protocol.is_none() {
19757            return Err(ShapeViolation {
19758                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19759                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19760                property_iri: "https://uor.foundation/interaction/peerProtocol",
19761                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19762                min_count: 1,
19763                max_count: 1,
19764                kind: ViolationKind::Missing,
19765            });
19766        }
19767        if self.convergence_predicate.is_none() {
19768            return Err(ShapeViolation {
19769                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19770                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19771                property_iri: "https://uor.foundation/interaction/convergencePredicate",
19772                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19773                min_count: 1,
19774                max_count: 1,
19775                kind: ViolationKind::Missing,
19776            });
19777        }
19778        if self.commutator_state_class.is_none() {
19779            return Err(ShapeViolation {
19780                shape_iri: "https://uor.foundation/conformance/InteractionShape",
19781                constraint_iri: "https://uor.foundation/conformance/InteractionShape",
19782                property_iri: "https://uor.foundation/interaction/commutatorStateClass",
19783                expected_range: "http://www.w3.org/2002/07/owl#Thing",
19784                min_count: 1,
19785                max_count: 1,
19786                kind: ViolationKind::Missing,
19787            });
19788        }
19789        Ok(Validated::new(InteractionShape {
19790            shape_iri: "https://uor.foundation/conformance/InteractionShape",
19791        }))
19792    }
19793
19794    fn validate_common(&self) -> Result<(), ShapeViolation> {
19795        self.validate_const().map(|_| ())
19796    }
19797}
19798
19799/// Phase E.6: validated InteractionDeclaration per `conformance:InteractionShape`.
19800#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19801pub struct InteractionShape {
19802    /// Shape IRI this declaration was validated against.
19803    pub shape_iri: &'static str,
19804}
19805
19806/// Phase E.5 (target §7.4): observability subscribe API.
19807/// When the `observability` feature is enabled, downstream may call
19808/// `subscribe_trace_events` with a handler closure that receives each
19809/// `TraceEvent` as the pipeline emits it. When the feature is off, this
19810/// function is entirely absent from the public API.
19811#[cfg(feature = "observability")]
19812pub fn subscribe_trace_events<F>(handler: F) -> ObservabilitySubscription<F>
19813where
19814    F: FnMut(&TraceEvent),
19815{
19816    ObservabilitySubscription {
19817        handler,
19818        _sealed: (),
19819    }
19820}
19821
19822#[cfg(feature = "observability")]
19823/// Phase E.5: sealed subscription handle returned by `subscribe_trace_events`.
19824#[cfg(feature = "observability")]
19825pub struct ObservabilitySubscription<F: FnMut(&TraceEvent)> {
19826    handler: F,
19827    _sealed: (),
19828}
19829
19830#[cfg(feature = "observability")]
19831impl<F: FnMut(&TraceEvent)> ObservabilitySubscription<F> {
19832    /// Dispatch a TraceEvent through the subscribed handler.
19833    pub fn emit(&mut self, event: &TraceEvent) {
19834        (self.handler)(event);
19835    }
19836}
19837
19838/// Phase F.2 (target §4.7): closed enumeration of the six constraint kinds.
19839/// `type-decl` bodies enumerate exactly these six kinds per `uor_term.ebnf`'s
19840/// `constraint-decl` production. `CompositeConstraint` — the implicit shape of
19841/// a multi-decl body — has no syntactic constructor and is therefore not a
19842/// variant of this enum.
19843#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19844#[non_exhaustive]
19845pub enum ConstraintKind {
19846    /// `type:ResidueConstraint` — value is congruent to `r (mod m)`.
19847    Residue,
19848    /// `type:CarryConstraint` — bounded carry depth.
19849    Carry,
19850    /// `type:DepthConstraint` — bounded derivation depth.
19851    Depth,
19852    /// `type:HammingConstraint` — bounded Hamming distance from a reference.
19853    Hamming,
19854    /// `type:SiteConstraint` — per-site cardinality or containment.
19855    Site,
19856    /// `type:AffineConstraint` — linear inequality over site values.
19857    Affine,
19858}
19859
19860/// Phase F.3 (target §4.7 carry): sealed per-ring-op carry profile.
19861#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19862pub struct CarryProfile {
19863    chain_length: u32,
19864    max_depth: u32,
19865    _sealed: (),
19866}
19867
19868impl CarryProfile {
19869    /// Length of the longest carry chain observed.
19870    #[inline]
19871    #[must_use]
19872    pub const fn chain_length(&self) -> u32 {
19873        self.chain_length
19874    }
19875
19876    /// Maximum carry depth across the op.
19877    #[inline]
19878    #[must_use]
19879    pub const fn max_depth(&self) -> u32 {
19880        self.max_depth
19881    }
19882
19883    /// Crate-internal constructor.
19884    #[inline]
19885    #[must_use]
19886    #[allow(dead_code)]
19887    pub(crate) const fn new(chain_length: u32, max_depth: u32) -> Self {
19888        Self {
19889            chain_length,
19890            max_depth,
19891            _sealed: (),
19892        }
19893    }
19894}
19895
19896/// Phase F.3 (target §4.7 carry): sealed carry-event witness — records the ring op
19897/// and two `Datum<L>` witt widths involved.
19898#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19899pub struct CarryEvent {
19900    left_bits: u16,
19901    right_bits: u16,
19902    _sealed: (),
19903}
19904
19905impl CarryEvent {
19906    /// Witt bit-width of the left operand.
19907    #[inline]
19908    #[must_use]
19909    pub const fn left_bits(&self) -> u16 {
19910        self.left_bits
19911    }
19912
19913    /// Witt bit-width of the right operand.
19914    #[inline]
19915    #[must_use]
19916    pub const fn right_bits(&self) -> u16 {
19917        self.right_bits
19918    }
19919
19920    /// Crate-internal constructor.
19921    #[inline]
19922    #[must_use]
19923    #[allow(dead_code)]
19924    pub(crate) const fn new(left_bits: u16, right_bits: u16) -> Self {
19925        Self {
19926            left_bits,
19927            right_bits,
19928            _sealed: (),
19929        }
19930    }
19931}
19932
19933/// Phase F.3 (target §4.7 convergence): sealed convergence-level witness at `L`.
19934#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19935pub struct ConvergenceLevel<L> {
19936    valuation: u32,
19937    _level: PhantomData<L>,
19938    _sealed: (),
19939}
19940
19941impl<L> ConvergenceLevel<L> {
19942    /// The v₂ valuation of the datum at this convergence level.
19943    #[inline]
19944    #[must_use]
19945    pub const fn valuation(&self) -> u32 {
19946        self.valuation
19947    }
19948
19949    /// Crate-internal constructor.
19950    #[inline]
19951    #[must_use]
19952    #[allow(dead_code)]
19953    pub(crate) const fn new(valuation: u32) -> Self {
19954        Self {
19955            valuation,
19956            _level: PhantomData,
19957            _sealed: (),
19958        }
19959    }
19960}
19961
19962/// Phase F.3 (target §4.7 division): sealed enum over the four normed division
19963/// algebras from Cayley-Dickson. No other admissible algebra exists (Hurwitz's theorem).
19964#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19965#[non_exhaustive]
19966pub enum DivisionAlgebraWitness {
19967    /// Real numbers ℝ (dimension 1).
19968    Real,
19969    /// Complex numbers ℂ (dimension 2).
19970    Complex,
19971    /// Quaternions ℍ (dimension 4, non-commutative).
19972    Quaternion,
19973    /// Octonions 𝕆 (dimension 8, non-commutative, non-associative).
19974    Octonion,
19975}
19976
19977/// Phase F.3 (target §4.7 monoidal): sealed monoidal-product witness.
19978#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19979pub struct MonoidalProduct<L, R> {
19980    _left: PhantomData<L>,
19981    _right: PhantomData<R>,
19982    _sealed: (),
19983}
19984
19985impl<L, R> MonoidalProduct<L, R> {
19986    /// Crate-internal constructor.
19987    #[inline]
19988    #[must_use]
19989    #[allow(dead_code)]
19990    pub(crate) const fn new() -> Self {
19991        Self {
19992            _left: PhantomData,
19993            _right: PhantomData,
19994            _sealed: (),
19995        }
19996    }
19997}
19998
19999/// Phase F.3 (target §4.7 monoidal): sealed monoidal-unit witness at `L`.
20000#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20001pub struct MonoidalUnit<L> {
20002    _level: PhantomData<L>,
20003    _sealed: (),
20004}
20005
20006impl<L> MonoidalUnit<L> {
20007    /// Crate-internal constructor.
20008    #[inline]
20009    #[must_use]
20010    #[allow(dead_code)]
20011    pub(crate) const fn new() -> Self {
20012        Self {
20013            _level: PhantomData,
20014            _sealed: (),
20015        }
20016    }
20017}
20018
20019/// Phase F.1 (target §4.7 operad): sealed operad-composition witness.
20020/// Every `type-app` form in the term grammar materializes a fresh `OperadComposition`
20021/// carrying the outer/inner type IRIs and composed site count, per `operad:` ontology.
20022#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20023pub struct OperadComposition {
20024    outer_type_iri: &'static str,
20025    inner_type_iri: &'static str,
20026    composed_site_count: u32,
20027    _sealed: (),
20028}
20029
20030impl OperadComposition {
20031    /// IRI of the outer `type:TypeDefinition`.
20032    #[inline]
20033    #[must_use]
20034    pub const fn outer_type_iri(&self) -> &'static str {
20035        self.outer_type_iri
20036    }
20037
20038    /// IRI of the inner `type:TypeDefinition`.
20039    #[inline]
20040    #[must_use]
20041    pub const fn inner_type_iri(&self) -> &'static str {
20042        self.inner_type_iri
20043    }
20044
20045    /// Site count of the composed type.
20046    #[inline]
20047    #[must_use]
20048    pub const fn composed_site_count(&self) -> u32 {
20049        self.composed_site_count
20050    }
20051
20052    /// Crate-internal constructor.
20053    #[inline]
20054    #[must_use]
20055    #[allow(dead_code)]
20056    pub(crate) const fn new(
20057        outer_type_iri: &'static str,
20058        inner_type_iri: &'static str,
20059        composed_site_count: u32,
20060    ) -> Self {
20061        Self {
20062            outer_type_iri,
20063            inner_type_iri,
20064            composed_site_count,
20065            _sealed: (),
20066        }
20067    }
20068}
20069
20070/// Phase F.3 (target §4.7 recursion): maximum depth of the recursion trace
20071/// witness. Bounded by the declared descent budget at builder-validate time;
20072/// the constant is a size-budget cap matching other foundation arenas.
20073/// Wiki ADR-037: a foundation-fixed conservative default for
20074/// [`crate::HostBounds::RECURSION_TRACE_DEPTH_MAX`].
20075pub const RECURSION_TRACE_MAX_DEPTH: usize = 16;
20076
20077/// Phase F.3 (target §4.7 recursion): sealed recursion trace with fixed-capacity
20078/// descent-measure sequence.
20079#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20080pub struct RecursionTrace {
20081    depth: u32,
20082    measure: [u32; RECURSION_TRACE_MAX_DEPTH],
20083    _sealed: (),
20084}
20085
20086impl RecursionTrace {
20087    /// Number of recursive descents in this trace.
20088    #[inline]
20089    #[must_use]
20090    pub const fn depth(&self) -> u32 {
20091        self.depth
20092    }
20093
20094    /// Descent-measure sequence.
20095    #[inline]
20096    #[must_use]
20097    pub const fn measure(&self) -> &[u32; RECURSION_TRACE_MAX_DEPTH] {
20098        &self.measure
20099    }
20100
20101    /// Crate-internal constructor.
20102    #[inline]
20103    #[must_use]
20104    #[allow(dead_code)]
20105    pub(crate) const fn new(depth: u32, measure: [u32; RECURSION_TRACE_MAX_DEPTH]) -> Self {
20106        Self {
20107            depth,
20108            measure,
20109            _sealed: (),
20110        }
20111    }
20112}
20113
20114/// Phase F.3 (target §4.7 region): sealed address-region witness.
20115#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20116pub struct AddressRegion {
20117    base: u128,
20118    extent: u64,
20119    _sealed: (),
20120}
20121
20122impl AddressRegion {
20123    /// Base address of the region.
20124    #[inline]
20125    #[must_use]
20126    pub const fn base(&self) -> u128 {
20127        self.base
20128    }
20129
20130    /// Extent (number of addressable cells).
20131    #[inline]
20132    #[must_use]
20133    pub const fn extent(&self) -> u64 {
20134        self.extent
20135    }
20136
20137    /// Crate-internal constructor.
20138    #[inline]
20139    #[must_use]
20140    #[allow(dead_code)]
20141    pub(crate) const fn new(base: u128, extent: u64) -> Self {
20142        Self {
20143            base,
20144            extent,
20145            _sealed: (),
20146        }
20147    }
20148}
20149
20150/// Phase F.3 (target §4.7 linear): sealed linear-resource budget.
20151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20152pub struct LinearBudget {
20153    sites_remaining: u64,
20154    _sealed: (),
20155}
20156
20157impl LinearBudget {
20158    /// Number of linear sites still available for allocation.
20159    #[inline]
20160    #[must_use]
20161    pub const fn sites_remaining(&self) -> u64 {
20162        self.sites_remaining
20163    }
20164
20165    /// Crate-internal constructor.
20166    #[inline]
20167    #[must_use]
20168    #[allow(dead_code)]
20169    pub(crate) const fn new(sites_remaining: u64) -> Self {
20170        Self {
20171            sites_remaining,
20172            _sealed: (),
20173        }
20174    }
20175}
20176
20177/// Phase F.3 (target §4.7 linear): sealed lease-allocation witness.
20178#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20179pub struct LeaseAllocation {
20180    site_count: u32,
20181    scope_hash: u128,
20182    _sealed: (),
20183}
20184
20185impl LeaseAllocation {
20186    /// Number of linear sites taken by this allocation.
20187    #[inline]
20188    #[must_use]
20189    pub const fn site_count(&self) -> u32 {
20190        self.site_count
20191    }
20192
20193    /// Content-hash of the lease scope identifier.
20194    #[inline]
20195    #[must_use]
20196    pub const fn scope_hash(&self) -> u128 {
20197        self.scope_hash
20198    }
20199
20200    /// Crate-internal constructor.
20201    #[inline]
20202    #[must_use]
20203    #[allow(dead_code)]
20204    pub(crate) const fn new(site_count: u32, scope_hash: u128) -> Self {
20205        Self {
20206            site_count,
20207            scope_hash,
20208            _sealed: (),
20209        }
20210    }
20211}
20212
20213/// v0.2.2 Phase J: zero-sized token identifying the `Total` marker.
20214#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
20215pub struct TotalMarker;
20216
20217/// v0.2.2 Phase J: zero-sized token identifying the `Invertible` marker.
20218#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
20219pub struct InvertibleMarker;
20220
20221/// v0.2.2 Phase J: zero-sized token identifying the `PreservesStructure` marker.
20222#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
20223pub struct PreservesStructureMarker;
20224
20225mod marker_tuple_sealed {
20226    /// Private supertrait. Not implementable outside this crate.
20227    pub trait Sealed {}
20228}
20229
20230/// v0.2.2 Phase J: sealed marker-tuple trait. Implemented exhaustively by
20231/// the closed catalogue of six admissible marker tuples in canonical order
20232/// (Total, Invertible, PreservesStructure). Downstream cannot add new
20233/// marker tuples; the seal anchors Phase J's compile-time correctness claim.
20234pub trait MarkerTuple: marker_tuple_sealed::Sealed {}
20235
20236impl marker_tuple_sealed::Sealed for () {}
20237impl MarkerTuple for () {}
20238impl marker_tuple_sealed::Sealed for (TotalMarker,) {}
20239impl MarkerTuple for (TotalMarker,) {}
20240impl marker_tuple_sealed::Sealed for (TotalMarker, InvertibleMarker) {}
20241impl MarkerTuple for (TotalMarker, InvertibleMarker) {}
20242impl marker_tuple_sealed::Sealed for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {}
20243impl MarkerTuple for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {}
20244impl marker_tuple_sealed::Sealed for (InvertibleMarker,) {}
20245impl MarkerTuple for (InvertibleMarker,) {}
20246impl marker_tuple_sealed::Sealed for (InvertibleMarker, PreservesStructureMarker) {}
20247impl MarkerTuple for (InvertibleMarker, PreservesStructureMarker) {}
20248
20249/// v0.2.2 Phase J: type-level set intersection of two marker tuples.
20250/// Implemented exhaustively for every ordered pair in the closed catalogue.
20251/// Composition combinators (`then`, `and_then`) use this trait to compute
20252/// the output marker tuple of a composed primitive as the intersection of
20253/// its two inputs' tuples. Because the catalogue is closed, the result is
20254/// always another tuple in the catalogue — no open-world hazards.
20255pub trait MarkerIntersection<Other: MarkerTuple>: MarkerTuple {
20256    /// The intersection of `Self` and `Other` in the closed catalogue.
20257    type Output: MarkerTuple;
20258}
20259
20260impl MarkerIntersection<()> for () {
20261    type Output = ();
20262}
20263impl MarkerIntersection<(TotalMarker,)> for () {
20264    type Output = ();
20265}
20266impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for () {
20267    type Output = ();
20268}
20269impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)> for () {
20270    type Output = ();
20271}
20272impl MarkerIntersection<(InvertibleMarker,)> for () {
20273    type Output = ();
20274}
20275impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for () {
20276    type Output = ();
20277}
20278impl MarkerIntersection<()> for (TotalMarker,) {
20279    type Output = ();
20280}
20281impl MarkerIntersection<(TotalMarker,)> for (TotalMarker,) {
20282    type Output = (TotalMarker,);
20283}
20284impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (TotalMarker,) {
20285    type Output = (TotalMarker,);
20286}
20287impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20288    for (TotalMarker,)
20289{
20290    type Output = (TotalMarker,);
20291}
20292impl MarkerIntersection<(InvertibleMarker,)> for (TotalMarker,) {
20293    type Output = ();
20294}
20295impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for (TotalMarker,) {
20296    type Output = ();
20297}
20298impl MarkerIntersection<()> for (TotalMarker, InvertibleMarker) {
20299    type Output = ();
20300}
20301impl MarkerIntersection<(TotalMarker,)> for (TotalMarker, InvertibleMarker) {
20302    type Output = (TotalMarker,);
20303}
20304impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (TotalMarker, InvertibleMarker) {
20305    type Output = (TotalMarker, InvertibleMarker);
20306}
20307impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20308    for (TotalMarker, InvertibleMarker)
20309{
20310    type Output = (TotalMarker, InvertibleMarker);
20311}
20312impl MarkerIntersection<(InvertibleMarker,)> for (TotalMarker, InvertibleMarker) {
20313    type Output = (InvertibleMarker,);
20314}
20315impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20316    for (TotalMarker, InvertibleMarker)
20317{
20318    type Output = (InvertibleMarker,);
20319}
20320impl MarkerIntersection<()> for (TotalMarker, InvertibleMarker, PreservesStructureMarker) {
20321    type Output = ();
20322}
20323impl MarkerIntersection<(TotalMarker,)>
20324    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20325{
20326    type Output = (TotalMarker,);
20327}
20328impl MarkerIntersection<(TotalMarker, InvertibleMarker)>
20329    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20330{
20331    type Output = (TotalMarker, InvertibleMarker);
20332}
20333impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20334    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20335{
20336    type Output = (TotalMarker, InvertibleMarker, PreservesStructureMarker);
20337}
20338impl MarkerIntersection<(InvertibleMarker,)>
20339    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20340{
20341    type Output = (InvertibleMarker,);
20342}
20343impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20344    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
20345{
20346    type Output = (InvertibleMarker, PreservesStructureMarker);
20347}
20348impl MarkerIntersection<()> for (InvertibleMarker,) {
20349    type Output = ();
20350}
20351impl MarkerIntersection<(TotalMarker,)> for (InvertibleMarker,) {
20352    type Output = ();
20353}
20354impl MarkerIntersection<(TotalMarker, InvertibleMarker)> for (InvertibleMarker,) {
20355    type Output = (InvertibleMarker,);
20356}
20357impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20358    for (InvertibleMarker,)
20359{
20360    type Output = (InvertibleMarker,);
20361}
20362impl MarkerIntersection<(InvertibleMarker,)> for (InvertibleMarker,) {
20363    type Output = (InvertibleMarker,);
20364}
20365impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)> for (InvertibleMarker,) {
20366    type Output = (InvertibleMarker,);
20367}
20368impl MarkerIntersection<()> for (InvertibleMarker, PreservesStructureMarker) {
20369    type Output = ();
20370}
20371impl MarkerIntersection<(TotalMarker,)> for (InvertibleMarker, PreservesStructureMarker) {
20372    type Output = ();
20373}
20374impl MarkerIntersection<(TotalMarker, InvertibleMarker)>
20375    for (InvertibleMarker, PreservesStructureMarker)
20376{
20377    type Output = (InvertibleMarker,);
20378}
20379impl MarkerIntersection<(TotalMarker, InvertibleMarker, PreservesStructureMarker)>
20380    for (InvertibleMarker, PreservesStructureMarker)
20381{
20382    type Output = (InvertibleMarker, PreservesStructureMarker);
20383}
20384impl MarkerIntersection<(InvertibleMarker,)> for (InvertibleMarker, PreservesStructureMarker) {
20385    type Output = (InvertibleMarker,);
20386}
20387impl MarkerIntersection<(InvertibleMarker, PreservesStructureMarker)>
20388    for (InvertibleMarker, PreservesStructureMarker)
20389{
20390    type Output = (InvertibleMarker, PreservesStructureMarker);
20391}
20392
20393/// v0.2.2 Phase J: compile-time check that a combinator's marker tuple
20394/// carries every property declared by the `GroundingMapKind` a program
20395/// claims. Implemented exhaustively by codegen for every valid `(tuple,
20396/// map)` pair; absent impls reject the mismatched declaration at the
20397/// `GroundingProgram::from_primitive` call site.
20398pub trait MarkersImpliedBy<Map: GroundingMapKind>: MarkerTuple {}
20399
20400/// v0.2.2 Phase J: bitmask encoding of a combinator's marker set.
20401/// Bit 0 = Total, bit 1 = Invertible, bit 2 = PreservesStructure.
20402#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20403pub struct MarkerBits(u8);
20404
20405impl MarkerBits {
20406    /// The `Total` marker bit.
20407    pub const TOTAL: Self = Self(1);
20408    /// The `Invertible` marker bit.
20409    pub const INVERTIBLE: Self = Self(2);
20410    /// The `PreservesStructure` marker bit.
20411    pub const PRESERVES_STRUCTURE: Self = Self(4);
20412    /// An empty marker set.
20413    pub const NONE: Self = Self(0);
20414
20415    /// Construct a marker bitmask from raw u8.
20416    #[inline]
20417    #[must_use]
20418    pub const fn from_u8(bits: u8) -> Self {
20419        Self(bits)
20420    }
20421
20422    /// Access the raw bitmask.
20423    #[inline]
20424    #[must_use]
20425    pub const fn as_u8(&self) -> u8 {
20426        self.0
20427    }
20428
20429    /// Bitwise OR of two marker bitmasks.
20430    #[inline]
20431    #[must_use]
20432    pub const fn union(self, other: Self) -> Self {
20433        Self(self.0 | other.0)
20434    }
20435
20436    /// Bitwise AND of two marker bitmasks (marker intersection).
20437    #[inline]
20438    #[must_use]
20439    pub const fn intersection(self, other: Self) -> Self {
20440        Self(self.0 & other.0)
20441    }
20442
20443    /// Whether this set contains all marker bits of `other`.
20444    #[inline]
20445    #[must_use]
20446    pub const fn contains(&self, other: Self) -> bool {
20447        (self.0 & other.0) == other.0
20448    }
20449}
20450
20451/// v0.2.2 Phase J: closed catalogue of grounding primitives.
20452/// Exactly 12 operations — read_bytes, interpret_le_integer,
20453/// interpret_be_integer, digest, decode_utf8, decode_json, select_field,
20454/// select_index, const_value, then, map_err, and_then. Adding a new
20455/// primitive is an ontology+grammar+codegen edit, not a Rust patch.
20456#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20457#[non_exhaustive]
20458pub enum GroundingPrimitiveOp {
20459    /// Read a fixed-size byte slice from the input.
20460    ReadBytes,
20461    /// Interpret bytes as a little-endian integer at the target WittLevel.
20462    InterpretLeInteger,
20463    /// Interpret bytes as a big-endian integer.
20464    InterpretBeInteger,
20465    /// Hash bytes via blake3 → 32-byte digest → `Datum<W256>`.
20466    /// # Scope
20467    /// `interpret_leaf_op` returns the first byte of the blake3 32-byte digest.
20468    /// The full digest is produced by `Datum<W256>` composition of 32 `Digest` leaves —
20469    /// the leaf-level output is the single-byte projection.
20470    Digest,
20471    /// Decode UTF-8 bytes; rejects malformed input.
20472    /// # Scope
20473    /// Only single-byte ASCII (`b < 0x80`) is decoded by `interpret_leaf_op`.
20474    /// Multi-byte UTF-8 is not decoded by this leaf; multi-byte sequences traverse the
20475    /// foundation via `GroundedTuple<N>` composition of single-byte leaves.
20476    DecodeUtf8,
20477    /// Decode JSON bytes; rejects malformed input.
20478    /// # Scope
20479    /// Only the leading byte of a JSON number scalar (`-` or ASCII digit) is parsed
20480    /// by `interpret_leaf_op`. Structured JSON values (objects, arrays, strings,
20481    /// multi-byte numbers) are not parsed by this leaf.
20482    DecodeJson,
20483    /// Select a field from a structured value.
20484    SelectField,
20485    /// Select an indexed element.
20486    SelectIndex,
20487    /// Inject a foundation-known constant.
20488    /// # Scope
20489    /// `interpret_leaf_op` returns `GroundedCoord::w8(0)` — the foundation-canonical
20490    /// zero constant. Non-zero constants are materialized through the const-fn frontier
20491    /// (`validate_const` paths) rather than through this leaf.
20492    ConstValue,
20493    /// Compose two combinators sequentially.
20494    Then,
20495    /// Map the error variant of a fallible combinator.
20496    MapErr,
20497    /// Conditional composition (and_then).
20498    AndThen,
20499}
20500
20501/// Max depth of a composed op chain retained inline inside
20502/// `GroundingPrimitive`. Depth-2 composites (`Then(leaf, leaf)`,
20503/// `AndThen(leaf, leaf)`) are the exercised shape today; 8 gives headroom
20504/// for nested composition while keeping `Copy` and `no_std` without alloc.
20505/// Wiki ADR-037: a foundation-fixed conservative default for
20506/// [`crate::HostBounds::OP_CHAIN_DEPTH_MAX`].
20507pub const MAX_OP_CHAIN_DEPTH: usize = 8;
20508
20509/// v0.2.2 Phase J: a single grounding primitive parametric over its output
20510/// type `Out` and its type-level marker tuple `Markers`.
20511/// Constructed only by the 12 enumerated combinator functions below;
20512/// downstream cannot construct one directly. The `Markers` parameter
20513/// defaults to `()` for backwards-compatible call sites, but each
20514/// combinator returns a specific tuple — see `combinators::digest` etc.
20515/// For leaf primitives `chain_len == 0`. For `Then`/`AndThen`/`MapErr`
20516/// composites, `chain[..chain_len as usize]` is the linearized post-order
20517/// sequence of leaf primitive ops the interpreter walks.
20518#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20519pub struct GroundingPrimitive<Out, Markers: MarkerTuple = ()> {
20520    op: GroundingPrimitiveOp,
20521    markers: MarkerBits,
20522    chain: [GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH],
20523    chain_len: u8,
20524    _out: PhantomData<Out>,
20525    _markers: PhantomData<Markers>,
20526    _sealed: (),
20527}
20528
20529impl<Out, Markers: MarkerTuple> GroundingPrimitive<Out, Markers> {
20530    /// Access the primitive op.
20531    #[inline]
20532    #[must_use]
20533    pub const fn op(&self) -> GroundingPrimitiveOp {
20534        self.op
20535    }
20536
20537    /// Access the runtime marker bitmask (mirrors the type-level tuple).
20538    #[inline]
20539    #[must_use]
20540    pub const fn markers(&self) -> MarkerBits {
20541        self.markers
20542    }
20543
20544    /// Access the recorded composition chain. Empty for leaf primitives;
20545    /// the post-order leaf-op sequence for `Then`/`AndThen`/`MapErr`.
20546    #[inline]
20547    #[must_use]
20548    pub fn chain(&self) -> &[GroundingPrimitiveOp] {
20549        &self.chain[..self.chain_len as usize]
20550    }
20551
20552    /// Crate-internal constructor for a leaf primitive (no recorded chain).
20553    /// The type-level `Markers` tuple is selected via turbofish at call
20554    /// sites inside the combinator functions.
20555    #[inline]
20556    #[must_use]
20557    #[allow(dead_code)]
20558    pub(crate) const fn from_parts(op: GroundingPrimitiveOp, markers: MarkerBits) -> Self {
20559        Self {
20560            op,
20561            markers,
20562            chain: [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH],
20563            chain_len: 0,
20564            _out: PhantomData,
20565            _markers: PhantomData,
20566            _sealed: (),
20567        }
20568    }
20569
20570    /// Crate-internal constructor for a composite primitive. Stores
20571    /// `chain[..chain_len]` inline; accessors expose only the prefix.
20572    #[inline]
20573    #[must_use]
20574    #[allow(dead_code)]
20575    pub(crate) const fn from_parts_with_chain(
20576        op: GroundingPrimitiveOp,
20577        markers: MarkerBits,
20578        chain: [GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH],
20579        chain_len: u8,
20580    ) -> Self {
20581        Self {
20582            op,
20583            markers,
20584            chain,
20585            chain_len,
20586            _out: PhantomData,
20587            _markers: PhantomData,
20588            _sealed: (),
20589        }
20590    }
20591}
20592
20593/// v0.2.2 Phase J: closed 12-combinator surface for building grounding
20594/// programs. See `GroundingProgram` for composition. Each leaf combinator
20595/// returns a `GroundingPrimitive<Out, M>` carrying a specific marker tuple;
20596/// the type parameter is what `GroundingProgram::from_primitive`'s
20597/// `MarkersImpliedBy<Map>` bound checks at compile time.
20598pub mod combinators {
20599    use super::{
20600        GroundingPrimitive, GroundingPrimitiveOp, InvertibleMarker, MarkerBits, MarkerIntersection,
20601        MarkerTuple, PreservesStructureMarker, TotalMarker, MAX_OP_CHAIN_DEPTH,
20602    };
20603
20604    /// Build the post-order leaf-op chain for a sequential composite:
20605    /// `first.chain ++ [first.op] ++ second.chain ++ [second.op]`.
20606    /// Saturated to `MAX_OP_CHAIN_DEPTH`.
20607    fn compose_chain<A, B, MA: MarkerTuple, MB: MarkerTuple>(
20608        first: &GroundingPrimitive<A, MA>,
20609        second: &GroundingPrimitive<B, MB>,
20610    ) -> ([GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH], u8) {
20611        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20612        let mut len: usize = 0;
20613        for &op in first.chain() {
20614            if len >= MAX_OP_CHAIN_DEPTH {
20615                return (chain, len as u8);
20616            }
20617            chain[len] = op;
20618            len += 1;
20619        }
20620        if len < MAX_OP_CHAIN_DEPTH {
20621            chain[len] = first.op();
20622            len += 1;
20623        }
20624        for &op in second.chain() {
20625            if len >= MAX_OP_CHAIN_DEPTH {
20626                return (chain, len as u8);
20627            }
20628            chain[len] = op;
20629            len += 1;
20630        }
20631        if len < MAX_OP_CHAIN_DEPTH {
20632            chain[len] = second.op();
20633            len += 1;
20634        }
20635        (chain, len as u8)
20636    }
20637
20638    /// Build the chain for `map_err(first)`: `first.chain ++ [first.op]`.
20639    fn map_err_chain<A, M: MarkerTuple>(
20640        first: &GroundingPrimitive<A, M>,
20641    ) -> ([GroundingPrimitiveOp; MAX_OP_CHAIN_DEPTH], u8) {
20642        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20643        let mut len: usize = 0;
20644        for &op in first.chain() {
20645            if len >= MAX_OP_CHAIN_DEPTH {
20646                return (chain, len as u8);
20647            }
20648            chain[len] = op;
20649            len += 1;
20650        }
20651        if len < MAX_OP_CHAIN_DEPTH {
20652            chain[len] = first.op();
20653            len += 1;
20654        }
20655        (chain, len as u8)
20656    }
20657
20658    /// Read a fixed-size byte slice from the input. `(Total, Invertible)`.
20659    #[inline]
20660    #[must_use]
20661    pub const fn read_bytes<Out>() -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker)> {
20662        GroundingPrimitive::from_parts(
20663            GroundingPrimitiveOp::ReadBytes,
20664            MarkerBits::TOTAL.union(MarkerBits::INVERTIBLE),
20665        )
20666    }
20667
20668    /// Interpret bytes as a little-endian integer at the target WittLevel.
20669    #[inline]
20670    #[must_use]
20671    pub const fn interpret_le_integer<Out>(
20672    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20673        GroundingPrimitive::from_parts(
20674            GroundingPrimitiveOp::InterpretLeInteger,
20675            MarkerBits::TOTAL
20676                .union(MarkerBits::INVERTIBLE)
20677                .union(MarkerBits::PRESERVES_STRUCTURE),
20678        )
20679    }
20680
20681    /// Interpret bytes as a big-endian integer.
20682    #[inline]
20683    #[must_use]
20684    pub const fn interpret_be_integer<Out>(
20685    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20686        GroundingPrimitive::from_parts(
20687            GroundingPrimitiveOp::InterpretBeInteger,
20688            MarkerBits::TOTAL
20689                .union(MarkerBits::INVERTIBLE)
20690                .union(MarkerBits::PRESERVES_STRUCTURE),
20691        )
20692    }
20693
20694    /// Hash bytes via blake3 → 32-byte digest → `Datum<W256>`. `(Total,)` only.
20695    #[inline]
20696    #[must_use]
20697    pub const fn digest<Out>() -> GroundingPrimitive<Out, (TotalMarker,)> {
20698        GroundingPrimitive::from_parts(GroundingPrimitiveOp::Digest, MarkerBits::TOTAL)
20699    }
20700
20701    /// Decode UTF-8 bytes. `(Invertible, PreservesStructure)` — not Total.
20702    #[inline]
20703    #[must_use]
20704    pub const fn decode_utf8<Out>(
20705    ) -> GroundingPrimitive<Out, (InvertibleMarker, PreservesStructureMarker)> {
20706        GroundingPrimitive::from_parts(
20707            GroundingPrimitiveOp::DecodeUtf8,
20708            MarkerBits::INVERTIBLE.union(MarkerBits::PRESERVES_STRUCTURE),
20709        )
20710    }
20711
20712    /// Decode JSON bytes. `(Invertible, PreservesStructure)` — not Total.
20713    #[inline]
20714    #[must_use]
20715    pub const fn decode_json<Out>(
20716    ) -> GroundingPrimitive<Out, (InvertibleMarker, PreservesStructureMarker)> {
20717        GroundingPrimitive::from_parts(
20718            GroundingPrimitiveOp::DecodeJson,
20719            MarkerBits::INVERTIBLE.union(MarkerBits::PRESERVES_STRUCTURE),
20720        )
20721    }
20722
20723    /// Select a field from a structured value. `(Invertible,)` — not Total.
20724    #[inline]
20725    #[must_use]
20726    pub const fn select_field<Out>() -> GroundingPrimitive<Out, (InvertibleMarker,)> {
20727        GroundingPrimitive::from_parts(GroundingPrimitiveOp::SelectField, MarkerBits::INVERTIBLE)
20728    }
20729
20730    /// Select an indexed element. `(Invertible,)` — not Total.
20731    #[inline]
20732    #[must_use]
20733    pub const fn select_index<Out>() -> GroundingPrimitive<Out, (InvertibleMarker,)> {
20734        GroundingPrimitive::from_parts(GroundingPrimitiveOp::SelectIndex, MarkerBits::INVERTIBLE)
20735    }
20736
20737    /// Inject a foundation-known constant. `(Total, Invertible, PreservesStructure)`.
20738    #[inline]
20739    #[must_use]
20740    pub const fn const_value<Out>(
20741    ) -> GroundingPrimitive<Out, (TotalMarker, InvertibleMarker, PreservesStructureMarker)> {
20742        GroundingPrimitive::from_parts(
20743            GroundingPrimitiveOp::ConstValue,
20744            MarkerBits::TOTAL
20745                .union(MarkerBits::INVERTIBLE)
20746                .union(MarkerBits::PRESERVES_STRUCTURE),
20747        )
20748    }
20749
20750    /// Compose two combinators sequentially. Markers are intersected at
20751    /// the type level via the `MarkerIntersection` trait. The recorded
20752    /// leaf-op chain lets the foundation's interpreter walk the operands
20753    /// at runtime.
20754    #[inline]
20755    #[must_use]
20756    pub fn then<A, B, MA, MB>(
20757        first: GroundingPrimitive<A, MA>,
20758        second: GroundingPrimitive<B, MB>,
20759    ) -> GroundingPrimitive<B, <MA as MarkerIntersection<MB>>::Output>
20760    where
20761        MA: MarkerTuple + MarkerIntersection<MB>,
20762        MB: MarkerTuple,
20763    {
20764        let (chain, chain_len) = compose_chain(&first, &second);
20765        GroundingPrimitive::from_parts_with_chain(
20766            GroundingPrimitiveOp::Then,
20767            first.markers().intersection(second.markers()),
20768            chain,
20769            chain_len,
20770        )
20771    }
20772
20773    /// Map an error variant of a fallible combinator. Marker tuple
20774    /// is preserved. The operand's op is recorded so the interpreter's
20775    /// `MapErr` arm can forward the success value.
20776    #[inline]
20777    #[must_use]
20778    pub fn map_err<A, M: MarkerTuple>(first: GroundingPrimitive<A, M>) -> GroundingPrimitive<A, M> {
20779        let (chain, chain_len) = map_err_chain(&first);
20780        GroundingPrimitive::from_parts_with_chain(
20781            GroundingPrimitiveOp::MapErr,
20782            first.markers(),
20783            chain,
20784            chain_len,
20785        )
20786    }
20787
20788    /// Conditional composition (and_then). Markers are intersected; the
20789    /// recorded chain mirrors `then` so the interpreter walks operands.
20790    #[inline]
20791    #[must_use]
20792    pub fn and_then<A, B, MA, MB>(
20793        first: GroundingPrimitive<A, MA>,
20794        second: GroundingPrimitive<B, MB>,
20795    ) -> GroundingPrimitive<B, <MA as MarkerIntersection<MB>>::Output>
20796    where
20797        MA: MarkerTuple + MarkerIntersection<MB>,
20798        MB: MarkerTuple,
20799    {
20800        let (chain, chain_len) = compose_chain(&first, &second);
20801        GroundingPrimitive::from_parts_with_chain(
20802            GroundingPrimitiveOp::AndThen,
20803            first.markers().intersection(second.markers()),
20804            chain,
20805            chain_len,
20806        )
20807    }
20808}
20809
20810/// v0.2.2 Phase J: sealed grounding program.
20811/// A composition of combinators with a statically tracked marker tuple.
20812/// Constructed only via `GroundingProgram::from_primitive`, which requires
20813/// via the `MarkersImpliedBy<Map>` trait bound that the primitive's marker
20814/// tuple carries every property declared by `Map: GroundingMapKind`.
20815#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20816pub struct GroundingProgram<Out, Map: GroundingMapKind> {
20817    primitive: GroundingPrimitive<Out>,
20818    _map: PhantomData<Map>,
20819    _sealed: (),
20820}
20821
20822impl<Out, Map: GroundingMapKind> GroundingProgram<Out, Map> {
20823    /// Foundation-verified constructor. Accepts a primitive whose marker
20824    /// tuple satisfies `MarkersImpliedBy<Map>`. Programs built from
20825    /// combinators whose marker tuple lacks a property `Map` requires are
20826    /// rejected at compile time — this is Phase J's marquee correctness
20827    /// claim: misdeclarations fail to compile.
20828    /// # Example: valid program
20829    /// ```
20830    /// use uor_foundation::enforcement::{GroundingProgram, IntegerGroundingMap, combinators};
20831    /// let prog: GroundingProgram<u64, IntegerGroundingMap> =
20832    ///     GroundingProgram::from_primitive(combinators::interpret_le_integer::<u64>());
20833    /// let _ = prog;
20834    /// ```
20835    /// # Example: rejected misdeclaration
20836    /// ```compile_fail
20837    /// use uor_foundation::enforcement::{GroundingProgram, IntegerGroundingMap, combinators};
20838    /// // digest returns (TotalMarker,) which does NOT satisfy
20839    /// // MarkersImpliedBy<IntegerGroundingMap> — the line below fails to compile.
20840    /// let prog: GroundingProgram<[u8; 32], IntegerGroundingMap> =
20841    ///     GroundingProgram::from_primitive(combinators::digest::<[u8; 32]>());
20842    /// let _ = prog;
20843    /// ```
20844    #[inline]
20845    #[must_use]
20846    pub fn from_primitive<Markers>(primitive: GroundingPrimitive<Out, Markers>) -> Self
20847    where
20848        Markers: MarkerTuple + MarkersImpliedBy<Map>,
20849    {
20850        // Preserve the composition chain so the interpreter can walk
20851        // operands of Then/AndThen/MapErr composites.
20852        let mut chain = [GroundingPrimitiveOp::ReadBytes; MAX_OP_CHAIN_DEPTH];
20853        let src = primitive.chain();
20854        let mut i = 0;
20855        while i < src.len() && i < MAX_OP_CHAIN_DEPTH {
20856            chain[i] = src[i];
20857            i += 1;
20858        }
20859        let erased = GroundingPrimitive::<Out, ()>::from_parts_with_chain(
20860            primitive.op(),
20861            primitive.markers(),
20862            chain,
20863            i as u8,
20864        );
20865        Self {
20866            primitive: erased,
20867            _map: PhantomData,
20868            _sealed: (),
20869        }
20870    }
20871
20872    /// Access the underlying primitive (erased marker tuple).
20873    #[inline]
20874    #[must_use]
20875    pub const fn primitive(&self) -> &GroundingPrimitive<Out> {
20876        &self.primitive
20877    }
20878}
20879
20880/// Phase K (target §4.3 / §9 criterion 1): foundation-supplied interpreter for
20881/// grounding programs whose `Out` is `GroundedCoord`. Handles every op in
20882/// the closed 12-combinator catalogue: leaf ops (`ReadBytes`,
20883/// `InterpretLeInteger`, `InterpretBeInteger`, `Digest`, `DecodeUtf8`,
20884/// `DecodeJson`, `ConstValue`, `SelectField`, `SelectIndex`) call
20885/// `interpret_leaf_op` directly; composition ops (`Then`, `AndThen`,
20886/// `MapErr`) walk the chain recorded in the primitive and thread
20887/// `external` through each leaf step. The interpreter surfaces
20888/// `GroundedCoord::w8(byte)` values; richer outputs compose through
20889/// combinator chains producing `GroundedTuple<N>`. No `ground()`
20890/// override exists after W4 closure — downstream provides only
20891/// `program()`, and `GroundingExt::ground` is foundation-authored.
20892impl<Map: GroundingMapKind> GroundingProgram<GroundedCoord, Map> {
20893    /// Run this program on external bytes, producing a `GroundedCoord`.
20894    /// Returns `None` if the input is malformed/undersized for the
20895    /// program's op chain.
20896    #[inline]
20897    #[must_use]
20898    pub fn run(&self, external: &[u8]) -> Option<GroundedCoord> {
20899        match self.primitive.op() {
20900            GroundingPrimitiveOp::Then | GroundingPrimitiveOp::AndThen => {
20901                let chain = self.primitive.chain();
20902                if chain.is_empty() {
20903                    return None;
20904                }
20905                let mut last: Option<GroundedCoord> = None;
20906                for &op in chain {
20907                    match interpret_leaf_op(op, external) {
20908                        Some(c) => last = Some(c),
20909                        None => return None,
20910                    }
20911                }
20912                last
20913            }
20914            GroundingPrimitiveOp::MapErr => self
20915                .primitive
20916                .chain()
20917                .first()
20918                .and_then(|&op| interpret_leaf_op(op, external)),
20919            leaf => interpret_leaf_op(leaf, external),
20920        }
20921    }
20922}
20923
20924/// W4 closure (target §4.3 + §9 criterion 1): foundation-supplied
20925/// interpreter for programs producing `GroundedTuple<N>`. Splits
20926/// `external` into `N` equal windows and runs the same dispatch
20927/// that `GroundingProgram<GroundedCoord, Map>::run` performs on
20928/// each window. Returns `None` if `N == 0`, the input is empty,
20929/// the input length isn't divisible by `N`, or any window fails.
20930impl<const N: usize, Map: GroundingMapKind> GroundingProgram<GroundedTuple<N>, Map> {
20931    /// Run this program on external bytes, producing a `GroundedTuple<N>`.
20932    #[inline]
20933    #[must_use]
20934    pub fn run(&self, external: &[u8]) -> Option<GroundedTuple<N>> {
20935        if N == 0 || external.is_empty() || external.len() % N != 0 {
20936            return None;
20937        }
20938        let window = external.len() / N;
20939        let mut coords: [GroundedCoord; N] = [const { GroundedCoord::w8(0) }; N];
20940        let mut i = 0usize;
20941        while i < N {
20942            let start = i * window;
20943            let end = start + window;
20944            let sub = &external[start..end];
20945            // Walk this window through the same leaf/composition
20946            // dispatch as the GroundedCoord interpreter above. A
20947            // helper that runs the chain is reused via the same
20948            // primitive accessors.
20949            let outcome = match self.primitive.op() {
20950                GroundingPrimitiveOp::Then | GroundingPrimitiveOp::AndThen => {
20951                    let chain = self.primitive.chain();
20952                    if chain.is_empty() {
20953                        return None;
20954                    }
20955                    let mut last: Option<GroundedCoord> = None;
20956                    for &op in chain {
20957                        match interpret_leaf_op(op, sub) {
20958                            Some(c) => last = Some(c),
20959                            None => return None,
20960                        }
20961                    }
20962                    last
20963                }
20964                GroundingPrimitiveOp::MapErr => self
20965                    .primitive
20966                    .chain()
20967                    .first()
20968                    .and_then(|&op| interpret_leaf_op(op, sub)),
20969                leaf => interpret_leaf_op(leaf, sub),
20970            };
20971            match outcome {
20972                Some(c) => {
20973                    coords[i] = c;
20974                }
20975                None => {
20976                    return None;
20977                }
20978            }
20979            i += 1;
20980        }
20981        Some(GroundedTuple::new(coords))
20982    }
20983}
20984
20985/// Foundation-canonical leaf-op interpreter. Called directly by
20986/// `GroundingProgram::run` for leaf primitives and step-by-step for
20987/// composition ops.
20988#[inline]
20989fn interpret_leaf_op(op: GroundingPrimitiveOp, external: &[u8]) -> Option<GroundedCoord> {
20990    match op {
20991        GroundingPrimitiveOp::ReadBytes | GroundingPrimitiveOp::InterpretLeInteger => {
20992            external.first().map(|&b| GroundedCoord::w8(b))
20993        }
20994        GroundingPrimitiveOp::InterpretBeInteger => external.last().map(|&b| GroundedCoord::w8(b)),
20995        GroundingPrimitiveOp::Digest => {
20996            // Foundation-canonical digest: first byte as `GroundedCoord` —
20997            // the full 32-byte digest requires a Datum<W256> sink that does
20998            // not fit in `GroundedCoord`. Downstream that needs the full
20999            // digest composes a richer program via Then/AndThen chains over
21000            // the 12 closed combinators — no `ground()` override exists after
21001            // W4 closure.
21002            external.first().map(|&b| GroundedCoord::w8(b))
21003        }
21004        GroundingPrimitiveOp::DecodeUtf8 => {
21005            // ASCII single-byte path — the canonical v0.2.2 semantics for
21006            // `Grounding::ground` over `GroundedCoord` outputs. Multi-byte
21007            // UTF-8 sequences are out of scope for w8-sized leaves; a richer
21008            // structured output composes via combinator chains into
21009            // `GroundedTuple<N>`.
21010            match external.first() {
21011                Some(&b) if b < 0x80 => Some(GroundedCoord::w8(b)),
21012                _ => None,
21013            }
21014        }
21015        GroundingPrimitiveOp::DecodeJson => {
21016            // Accept JSON number scalars (leading `-` or ASCII digit).
21017            match external.first() {
21018                Some(&b) if b == b'-' || b.is_ascii_digit() => Some(GroundedCoord::w8(b)),
21019                _ => None,
21020            }
21021        }
21022        GroundingPrimitiveOp::ConstValue => Some(GroundedCoord::w8(0)),
21023        GroundingPrimitiveOp::SelectField | GroundingPrimitiveOp::SelectIndex => {
21024            // Selector ops are composition-only in normal use; if invoked
21025            // directly, forward the first byte as a GroundedCoord.
21026            external.first().map(|&b| GroundedCoord::w8(b))
21027        }
21028        GroundingPrimitiveOp::Then
21029        | GroundingPrimitiveOp::AndThen
21030        | GroundingPrimitiveOp::MapErr => {
21031            // Composite ops are dispatched by `run()` through the chain;
21032            // they never reach the leaf interpreter.
21033            None
21034        }
21035    }
21036}
21037
21038/// v0.2.2 Phase J: MarkersImpliedBy impls for the closed catalogue of valid
21039/// (marker tuple, GroundingMapKind) pairs. These are the compile-time
21040/// witnesses the foundation accepts; every absent pair is a rejection.
21041impl MarkersImpliedBy<DigestGroundingMap> for (TotalMarker,) {}
21042impl MarkersImpliedBy<BinaryGroundingMap> for (TotalMarker, InvertibleMarker) {}
21043impl MarkersImpliedBy<DigestGroundingMap> for (TotalMarker, InvertibleMarker) {}
21044impl MarkersImpliedBy<BinaryGroundingMap>
21045    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
21046{
21047}
21048impl MarkersImpliedBy<DigestGroundingMap>
21049    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
21050{
21051}
21052impl MarkersImpliedBy<IntegerGroundingMap>
21053    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
21054{
21055}
21056impl MarkersImpliedBy<JsonGroundingMap>
21057    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
21058{
21059}
21060impl MarkersImpliedBy<Utf8GroundingMap>
21061    for (TotalMarker, InvertibleMarker, PreservesStructureMarker)
21062{
21063}
21064impl MarkersImpliedBy<JsonGroundingMap> for (InvertibleMarker, PreservesStructureMarker) {}
21065impl MarkersImpliedBy<Utf8GroundingMap> for (InvertibleMarker, PreservesStructureMarker) {}
21066
21067/// v0.2.2 T2.5: foundation-private test-only back-door module.
21068/// Exposes crate-internal constructors for `Trace`, `TraceEvent`, and
21069/// `MulContext` to the `uor-foundation-test-helpers` workspace member, which
21070/// re-exports them under stable test-only names. Not part of the public API.
21071#[doc(hidden)]
21072pub mod __test_helpers {
21073    use super::{ContentAddress, ContentFingerprint, MulContext, Trace, TraceEvent, Validated};
21074
21075    /// Test-only ctor: build a Trace from a slice of events with a
21076    /// `ContentFingerprint::zero()` placeholder. Tests that need a non-zero
21077    /// fingerprint use `trace_with_fingerprint` instead. Parametric in
21078    /// `TR_MAX` per the wiki's ADR-018; callers pick the trace event-count
21079    /// ceiling from their selected `HostBounds`.
21080    #[must_use]
21081    pub fn trace_from_events<const TR_MAX: usize>(events: &[TraceEvent]) -> Trace<TR_MAX> {
21082        trace_with_fingerprint(events, 0, ContentFingerprint::zero())
21083    }
21084
21085    /// Test-only ctor that takes an explicit `witt_level_bits` and
21086    /// `ContentFingerprint`. Used by round-trip tests that need to verify
21087    /// the verify-trace fingerprint passthrough invariant.
21088    #[must_use]
21089    pub fn trace_with_fingerprint<const TR_MAX: usize>(
21090        events: &[TraceEvent],
21091        witt_level_bits: u16,
21092        content_fingerprint: ContentFingerprint,
21093    ) -> Trace<TR_MAX> {
21094        let mut arr = [None; TR_MAX];
21095        let n = events.len().min(TR_MAX);
21096        let mut i = 0;
21097        while i < n {
21098            arr[i] = Some(events[i]);
21099            i += 1;
21100        }
21101        // The test-helpers back-door uses the foundation-private
21102        // `from_replay_events_const` to build malformed fixtures for error-path
21103        // tests. Downstream code uses `Trace::try_from_events` (validating).
21104        Trace::from_replay_events_const(arr, n as u16, witt_level_bits, content_fingerprint)
21105    }
21106
21107    /// Test-only ctor: build a TraceEvent.
21108    #[must_use]
21109    pub fn trace_event(step_index: u32, target: u128) -> TraceEvent {
21110        TraceEvent::new(
21111            step_index,
21112            crate::PrimitiveOp::Add,
21113            ContentAddress::from_u128(target),
21114        )
21115    }
21116
21117    /// Test-only ctor: build a MulContext.
21118    #[must_use]
21119    pub fn mul_context(stack_budget_bytes: u64, const_eval: bool, limb_count: usize) -> MulContext {
21120        MulContext::new(stack_budget_bytes, const_eval, limb_count)
21121    }
21122
21123    /// Test-only ctor: wrap any T in a Runtime-phase Validated. Used by
21124    /// integration tests to construct `Validated<Decl, P>` values that
21125    /// the public API otherwise can't construct directly.
21126    #[must_use]
21127    pub fn validated_runtime<T>(inner: T) -> Validated<T> {
21128        Validated::new(inner)
21129    }
21130}
21131
21132/// Tolerance for entropy equality checks in the Product/Coproduct
21133/// Completion Amendment mint primitives. Returns an absolute-error bound
21134/// scaled to the magnitude of `expected`, so PT_4 / ST_2 / CPT_5
21135/// verifications are robust to floating-point rounding accumulated through
21136/// Künneth products and componentwise sums. The default-host (f64) backing
21137/// is hidden behind the `DefaultDecimal` alias so the function signature
21138/// reads as host-typed; downstream that swaps `H::Decimal` reaches the
21139/// same surface via the alias rebind.
21140type DefaultDecimal = <crate::DefaultHostTypes as crate::HostTypes>::Decimal;
21141
21142#[inline]
21143const fn pc_entropy_tolerance(expected: DefaultDecimal) -> DefaultDecimal {
21144    let magnitude = if expected < 0.0 { -expected } else { expected };
21145    let scale = if magnitude > 1.0 { magnitude } else { 1.0 };
21146    1024.0 * <DefaultDecimal>::EPSILON * scale
21147}
21148
21149/// Validate an entropy value before participating in additivity checks.
21150/// Rejects NaN, ±∞, and negative values — the foundation's
21151/// `primitive_descent_metrics` produces `residual × LN_2` with
21152/// `residual: u32`, so valid entropies are non-negative finite Decimals.
21153#[inline]
21154fn pc_entropy_input_is_valid(value: DefaultDecimal) -> bool {
21155    value.is_finite() && value >= 0.0
21156}
21157
21158/// Check that `actual` matches `expected` within tolerance and that both
21159/// inputs are valid entropy values. Returns `false` if either input is
21160/// non-finite, negative, or differs from `expected` by more than
21161/// `pc_entropy_tolerance(expected)`.
21162#[inline]
21163fn pc_entropy_additivity_holds(actual: DefaultDecimal, expected: DefaultDecimal) -> bool {
21164    if !pc_entropy_input_is_valid(actual) || !pc_entropy_input_is_valid(expected) {
21165        return false;
21166    }
21167    let diff = actual - expected;
21168    let diff_abs = if diff < 0.0 { -diff } else { diff };
21169    diff_abs <= pc_entropy_tolerance(expected)
21170}
21171
21172/// Evidence bundle for `PartitionProductWitness`. Carries the PT_1 / PT_3 /
21173/// PT_4 input values used at mint time. Derives `PartialEq` only because
21174/// `f64` entropy fields exclude `Eq` / `Hash`; this is the auditing surface,
21175/// not a hash-map key.
21176#[derive(Debug, Clone, Copy, PartialEq)]
21177pub struct PartitionProductEvidence {
21178    /// Left operand `siteBudget` (data sites only, PT_1 input).
21179    pub left_site_budget: u16,
21180    /// Right operand `siteBudget`.
21181    pub right_site_budget: u16,
21182    /// Left operand `SITE_COUNT` (layout width, layout-invariant input).
21183    pub left_total_site_count: u16,
21184    /// Right operand `SITE_COUNT`.
21185    pub right_total_site_count: u16,
21186    /// Left operand Euler characteristic (PT_3 input).
21187    pub left_euler: i32,
21188    /// Right operand Euler characteristic.
21189    pub right_euler: i32,
21190    /// Left operand entropy in nats (PT_4 input).
21191    pub left_entropy_nats_bits: u64,
21192    /// Right operand entropy in nats.
21193    pub right_entropy_nats_bits: u64,
21194    /// Fingerprint of the source witness the evidence belongs to.
21195    pub source_witness_fingerprint: ContentFingerprint,
21196}
21197
21198/// Evidence bundle for `PartitionCoproductWitness`. Carries the
21199/// ST_1 / ST_2 / ST_9 / ST_10 input values used at mint time.
21200#[derive(Debug, Clone, Copy, PartialEq)]
21201pub struct PartitionCoproductEvidence {
21202    pub left_site_budget: u16,
21203    pub right_site_budget: u16,
21204    pub left_total_site_count: u16,
21205    pub right_total_site_count: u16,
21206    pub left_euler: i32,
21207    pub right_euler: i32,
21208    pub left_entropy_nats_bits: u64,
21209    pub right_entropy_nats_bits: u64,
21210    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21211    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21212    pub source_witness_fingerprint: ContentFingerprint,
21213}
21214
21215/// Evidence bundle for `CartesianProductWitness`. Carries the
21216/// CPT_1 / CPT_3 / CPT_4 / CPT_5 input values used at mint time, plus
21217/// `combined_entropy_nats` — the CartesianProductWitness itself does not
21218/// store entropy (see §1a), so the evidence sidecar preserves the
21219/// verification target value for re-audit.
21220#[derive(Debug, Clone, Copy, PartialEq)]
21221pub struct CartesianProductEvidence {
21222    pub left_site_budget: u16,
21223    pub right_site_budget: u16,
21224    pub left_total_site_count: u16,
21225    pub right_total_site_count: u16,
21226    pub left_euler: i32,
21227    pub right_euler: i32,
21228    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21229    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21230    pub left_entropy_nats_bits: u64,
21231    pub right_entropy_nats_bits: u64,
21232    pub combined_entropy_nats_bits: u64,
21233    pub source_witness_fingerprint: ContentFingerprint,
21234}
21235
21236/// Inputs to `PartitionProductWitness::mint_verified`. Mirrors the
21237/// underlying primitive's parameter list; each field is supplied by the
21238/// caller (typically a `product_shape!` macro expansion or a manual
21239/// construction following the amendment's Gap 2 pattern). Derives
21240/// `PartialEq` only because of the `f64` entropy fields.
21241#[derive(Debug, Clone, Copy, PartialEq)]
21242pub struct PartitionProductMintInputs {
21243    pub witt_bits: u16,
21244    pub left_fingerprint: ContentFingerprint,
21245    pub right_fingerprint: ContentFingerprint,
21246    pub left_site_budget: u16,
21247    pub right_site_budget: u16,
21248    pub left_total_site_count: u16,
21249    pub right_total_site_count: u16,
21250    pub left_euler: i32,
21251    pub right_euler: i32,
21252    pub left_entropy_nats_bits: u64,
21253    pub right_entropy_nats_bits: u64,
21254    pub combined_site_budget: u16,
21255    pub combined_site_count: u16,
21256    pub combined_euler: i32,
21257    pub combined_entropy_nats_bits: u64,
21258    pub combined_fingerprint: ContentFingerprint,
21259}
21260
21261/// Inputs to `PartitionCoproductWitness::mint_verified`. Adds three
21262/// structural fields beyond the other two MintInputs: the combined
21263/// constraint array, the boundary index between L and R regions, and the
21264/// tag site layout index. These feed `validate_coproduct_structure` at
21265/// mint time so ST_6 / ST_7 / ST_8 are verified numerically rather than
21266/// trusted from the caller.
21267/// Derives `Debug`, `Clone`, `Copy` only — no `PartialEq`. `ConstraintRef`
21268/// does not implement `PartialEq`, so deriving equality on a struct with a
21269/// `&[ConstraintRef]` field would not compile. MintInputs is not used as
21270/// an equality target in practice; downstream consumers compare the minted
21271/// witness (which derives `Eq` + `Hash`) instead.
21272#[derive(Debug, Clone, Copy)]
21273pub struct PartitionCoproductMintInputs {
21274    pub witt_bits: u16,
21275    pub left_fingerprint: ContentFingerprint,
21276    pub right_fingerprint: ContentFingerprint,
21277    pub left_site_budget: u16,
21278    pub right_site_budget: u16,
21279    pub left_total_site_count: u16,
21280    pub right_total_site_count: u16,
21281    pub left_euler: i32,
21282    pub right_euler: i32,
21283    pub left_entropy_nats_bits: u64,
21284    pub right_entropy_nats_bits: u64,
21285    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21286    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21287    pub combined_site_budget: u16,
21288    pub combined_site_count: u16,
21289    pub combined_euler: i32,
21290    pub combined_entropy_nats_bits: u64,
21291    pub combined_betti: [u32; MAX_BETTI_DIMENSION],
21292    pub combined_fingerprint: ContentFingerprint,
21293    pub combined_constraints: &'static [crate::pipeline::ConstraintRef],
21294    pub left_constraint_count: usize,
21295    pub tag_site: u16,
21296}
21297
21298/// Inputs to `CartesianProductWitness::mint_verified`. Matches the
21299/// CartesianProduct mint primitive's parameter list.
21300#[derive(Debug, Clone, Copy, PartialEq)]
21301pub struct CartesianProductMintInputs {
21302    pub witt_bits: u16,
21303    pub left_fingerprint: ContentFingerprint,
21304    pub right_fingerprint: ContentFingerprint,
21305    pub left_site_budget: u16,
21306    pub right_site_budget: u16,
21307    pub left_total_site_count: u16,
21308    pub right_total_site_count: u16,
21309    pub left_euler: i32,
21310    pub right_euler: i32,
21311    pub left_betti: [u32; MAX_BETTI_DIMENSION],
21312    pub right_betti: [u32; MAX_BETTI_DIMENSION],
21313    pub left_entropy_nats_bits: u64,
21314    pub right_entropy_nats_bits: u64,
21315    pub combined_site_budget: u16,
21316    pub combined_site_count: u16,
21317    pub combined_euler: i32,
21318    pub combined_betti: [u32; MAX_BETTI_DIMENSION],
21319    pub combined_entropy_nats_bits: u64,
21320    pub combined_fingerprint: ContentFingerprint,
21321}
21322
21323/// Sealed PartitionProduct witness — content-addressed assertion that a
21324/// partition decomposes as `PartitionProduct(left, right)` per PT_2a.
21325/// Minting is gated on PT_1, PT_3, PT_4, and the foundation
21326/// `ProductLayoutWidth` invariant being verified against component
21327/// shapes. Existence of an instance is the attestation — there is no
21328/// partial or unverified form.
21329#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21330pub struct PartitionProductWitness {
21331    witt_bits: u16,
21332    content_fingerprint: ContentFingerprint,
21333    left_fingerprint: ContentFingerprint,
21334    right_fingerprint: ContentFingerprint,
21335    combined_site_budget: u16,
21336    combined_site_count: u16,
21337}
21338
21339impl PartitionProductWitness {
21340    /// Witt level at which the witness was minted.
21341    #[inline]
21342    #[must_use]
21343    pub const fn witt_bits(&self) -> u16 {
21344        self.witt_bits
21345    }
21346    /// Content fingerprint of the combined (A × B) shape.
21347    #[inline]
21348    #[must_use]
21349    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21350        self.content_fingerprint
21351    }
21352    /// Content fingerprint of the left factor A.
21353    #[inline]
21354    #[must_use]
21355    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21356        self.left_fingerprint
21357    }
21358    /// Content fingerprint of the right factor B.
21359    #[inline]
21360    #[must_use]
21361    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21362        self.right_fingerprint
21363    }
21364    /// `siteBudget(A × B)` per PT_1.
21365    #[inline]
21366    #[must_use]
21367    pub const fn combined_site_budget(&self) -> u16 {
21368        self.combined_site_budget
21369    }
21370    /// `SITE_COUNT(A × B)` — the foundation layout width.
21371    #[inline]
21372    #[must_use]
21373    pub const fn combined_site_count(&self) -> u16 {
21374        self.combined_site_count
21375    }
21376    /// Crate-internal mint entry. Only the verified mint primitive may call this.
21377    #[inline]
21378    #[must_use]
21379    #[allow(clippy::too_many_arguments)]
21380    pub(crate) const fn with_level_fingerprints_and_sites(
21381        witt_bits: u16,
21382        content_fingerprint: ContentFingerprint,
21383        left_fingerprint: ContentFingerprint,
21384        right_fingerprint: ContentFingerprint,
21385        combined_site_budget: u16,
21386        combined_site_count: u16,
21387    ) -> Self {
21388        Self {
21389            witt_bits,
21390            content_fingerprint,
21391            left_fingerprint,
21392            right_fingerprint,
21393            combined_site_budget,
21394            combined_site_count,
21395        }
21396    }
21397}
21398
21399/// Sealed PartitionCoproduct witness — content-addressed assertion that a
21400/// partition decomposes as `PartitionCoproduct(left, right)` per PT_2b.
21401/// Minting verifies ST_1, ST_2, ST_6, ST_7, ST_8, ST_9, ST_10, the
21402/// foundation `CoproductLayoutWidth` invariant, and — for ST_6/ST_7/ST_8 —
21403/// walks the supplied constraint array through `validate_coproduct_structure`.
21404#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21405pub struct PartitionCoproductWitness {
21406    witt_bits: u16,
21407    content_fingerprint: ContentFingerprint,
21408    left_fingerprint: ContentFingerprint,
21409    right_fingerprint: ContentFingerprint,
21410    combined_site_budget: u16,
21411    combined_site_count: u16,
21412    tag_site_index: u16,
21413}
21414
21415impl PartitionCoproductWitness {
21416    #[inline]
21417    #[must_use]
21418    pub const fn witt_bits(&self) -> u16 {
21419        self.witt_bits
21420    }
21421    #[inline]
21422    #[must_use]
21423    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21424        self.content_fingerprint
21425    }
21426    #[inline]
21427    #[must_use]
21428    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21429        self.left_fingerprint
21430    }
21431    #[inline]
21432    #[must_use]
21433    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21434        self.right_fingerprint
21435    }
21436    /// `siteBudget(A + B)` per ST_1 = max(siteBudget(A), siteBudget(B)).
21437    #[inline]
21438    #[must_use]
21439    pub const fn combined_site_budget(&self) -> u16 {
21440        self.combined_site_budget
21441    }
21442    /// `SITE_COUNT(A + B)` — the foundation layout width including the new tag site.
21443    #[inline]
21444    #[must_use]
21445    pub const fn combined_site_count(&self) -> u16 {
21446        self.combined_site_count
21447    }
21448    /// Index of the tag site in the layout convention of §4b'.
21449    /// Equals `max(SITE_COUNT(A), SITE_COUNT(B))`.
21450    #[inline]
21451    #[must_use]
21452    pub const fn tag_site_index(&self) -> u16 {
21453        self.tag_site_index
21454    }
21455    #[inline]
21456    #[must_use]
21457    #[allow(clippy::too_many_arguments)]
21458    pub(crate) const fn with_level_fingerprints_sites_and_tag(
21459        witt_bits: u16,
21460        content_fingerprint: ContentFingerprint,
21461        left_fingerprint: ContentFingerprint,
21462        right_fingerprint: ContentFingerprint,
21463        combined_site_budget: u16,
21464        combined_site_count: u16,
21465        tag_site_index: u16,
21466    ) -> Self {
21467        Self {
21468            witt_bits,
21469            content_fingerprint,
21470            left_fingerprint,
21471            right_fingerprint,
21472            combined_site_budget,
21473            combined_site_count,
21474            tag_site_index,
21475        }
21476    }
21477}
21478
21479/// Sealed CartesianPartitionProduct witness — content-addressed
21480/// assertion that a shape is `CartesianPartitionProduct(left, right)`
21481/// per CPT_2a. Minting verifies CPT_1, CPT_3, CPT_4, CPT_5, and the
21482/// foundation `CartesianLayoutWidth` invariant. The witness stores
21483/// a snapshot of the combined topological invariants (χ, Betti profile)
21484/// because the construction is axiomatic at the invariant level per §3c.
21485/// Entropy is not stored here (f64 has no Eq/Hash); use the paired
21486/// `CartesianProductEvidence` for entropy re-audit.
21487#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21488pub struct CartesianProductWitness {
21489    witt_bits: u16,
21490    content_fingerprint: ContentFingerprint,
21491    left_fingerprint: ContentFingerprint,
21492    right_fingerprint: ContentFingerprint,
21493    combined_site_budget: u16,
21494    combined_site_count: u16,
21495    combined_euler: i32,
21496    combined_betti: [u32; MAX_BETTI_DIMENSION],
21497}
21498
21499impl CartesianProductWitness {
21500    #[inline]
21501    #[must_use]
21502    pub const fn witt_bits(&self) -> u16 {
21503        self.witt_bits
21504    }
21505    #[inline]
21506    #[must_use]
21507    pub const fn content_fingerprint(&self) -> ContentFingerprint {
21508        self.content_fingerprint
21509    }
21510    #[inline]
21511    #[must_use]
21512    pub const fn left_fingerprint(&self) -> ContentFingerprint {
21513        self.left_fingerprint
21514    }
21515    #[inline]
21516    #[must_use]
21517    pub const fn right_fingerprint(&self) -> ContentFingerprint {
21518        self.right_fingerprint
21519    }
21520    #[inline]
21521    #[must_use]
21522    pub const fn combined_site_budget(&self) -> u16 {
21523        self.combined_site_budget
21524    }
21525    #[inline]
21526    #[must_use]
21527    pub const fn combined_site_count(&self) -> u16 {
21528        self.combined_site_count
21529    }
21530    #[inline]
21531    #[must_use]
21532    pub const fn combined_euler(&self) -> i32 {
21533        self.combined_euler
21534    }
21535    #[inline]
21536    #[must_use]
21537    pub const fn combined_betti(&self) -> [u32; MAX_BETTI_DIMENSION] {
21538        self.combined_betti
21539    }
21540    #[inline]
21541    #[must_use]
21542    #[allow(clippy::too_many_arguments)]
21543    pub(crate) const fn with_level_fingerprints_and_invariants(
21544        witt_bits: u16,
21545        content_fingerprint: ContentFingerprint,
21546        left_fingerprint: ContentFingerprint,
21547        right_fingerprint: ContentFingerprint,
21548        combined_site_budget: u16,
21549        combined_site_count: u16,
21550        combined_euler: i32,
21551        combined_betti: [u32; MAX_BETTI_DIMENSION],
21552    ) -> Self {
21553        Self {
21554            witt_bits,
21555            content_fingerprint,
21556            left_fingerprint,
21557            right_fingerprint,
21558            combined_site_budget,
21559            combined_site_count,
21560            combined_euler,
21561            combined_betti,
21562        }
21563    }
21564}
21565
21566impl Certificate for PartitionProductWitness {
21567    const IRI: &'static str = "https://uor.foundation/partition/PartitionProduct";
21568    type Evidence = PartitionProductEvidence;
21569}
21570
21571impl Certificate for PartitionCoproductWitness {
21572    const IRI: &'static str = "https://uor.foundation/partition/PartitionCoproduct";
21573    type Evidence = PartitionCoproductEvidence;
21574}
21575
21576impl Certificate for CartesianProductWitness {
21577    const IRI: &'static str = "https://uor.foundation/partition/CartesianPartitionProduct";
21578    type Evidence = CartesianProductEvidence;
21579}
21580
21581impl core::fmt::Display for PartitionProductWitness {
21582    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21583        f.write_str("PartitionProductWitness")
21584    }
21585}
21586impl core::error::Error for PartitionProductWitness {}
21587
21588impl core::fmt::Display for PartitionCoproductWitness {
21589    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21590        f.write_str("PartitionCoproductWitness")
21591    }
21592}
21593impl core::error::Error for PartitionCoproductWitness {}
21594
21595impl core::fmt::Display for CartesianProductWitness {
21596    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21597        f.write_str("CartesianProductWitness")
21598    }
21599}
21600impl core::error::Error for CartesianProductWitness {}
21601
21602/// Sealed mint path for certificates that require multi-theorem verification
21603/// before minting. Introduced by the Product/Coproduct Completion Amendment
21604/// §1c; distinct from `MintWithLevelFingerprint` (which is the generic
21605/// partial-mint path for sealed shims). `VerifiedMint` implementors are
21606/// the three partition-algebra witnesses, each routing through a
21607/// foundation-internal mint primitive that verifies the relevant theorems.
21608/// The trait is public so external callers can invoke `mint_verified`
21609/// directly, but the `Certificate` supertrait's `certificate_sealed::Sealed`
21610/// bound keeps the implementor set closed to this crate.
21611pub trait VerifiedMint: Certificate {
21612    /// Caller-supplied input bundle — one `*MintInputs` struct per witness.
21613    type Inputs;
21614    /// Failure kind — always `GenericImpossibilityWitness` citing the
21615    /// specific op-namespace theorem or foundation-namespace layout
21616    /// invariant that was violated.
21617    type Error;
21618    /// Verify the theorems and invariants against `inputs`, then mint a
21619    /// witness or return a typed impossibility witness.
21620    /// # Errors
21621    /// Returns a `GenericImpossibilityWitness::for_identity(iri)` when any
21622    /// of the gated theorems or foundation invariants fails. The IRI
21623    /// identifies exactly which identity failed — `op/PT_*`, `op/ST_*`,
21624    /// `op/CPT_*`, or `foundation/*LayoutWidth` / `foundation/CoproductTagEncoding`.
21625    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error>
21626    where
21627        Self: Sized;
21628}
21629
21630/// Recursive classifier used by `validate_coproduct_structure`. Inspects
21631/// one `ConstraintRef`, tallies tag-pinner sightings via mutable references,
21632/// and recurses into `Conjunction` conjuncts up to `max_depth` levels. See
21633/// plan §A4 for the depth bound rationale.
21634#[allow(clippy::too_many_arguments)]
21635fn pc_classify_constraint(
21636    c: &crate::pipeline::ConstraintRef,
21637    in_left_region: bool,
21638    tag_site: u16,
21639    max_depth: u32,
21640    left_pins: &mut u32,
21641    right_pins: &mut u32,
21642    left_bias_ok: &mut bool,
21643    right_bias_ok: &mut bool,
21644) -> Result<(), GenericImpossibilityWitness> {
21645    match c {
21646        crate::pipeline::ConstraintRef::Site { position } => {
21647            if (*position as u16) >= tag_site {
21648                return Err(GenericImpossibilityWitness::for_identity(
21649                    "https://uor.foundation/op/ST_6",
21650                ));
21651            }
21652        }
21653        crate::pipeline::ConstraintRef::Carry { site } => {
21654            if (*site as u16) >= tag_site {
21655                return Err(GenericImpossibilityWitness::for_identity(
21656                    "https://uor.foundation/op/ST_6",
21657                ));
21658            }
21659        }
21660        crate::pipeline::ConstraintRef::Affine { coefficients, coefficient_count, bias } => {
21661            let count = *coefficient_count as usize;
21662            let mut nonzero_count: u32 = 0;
21663            let mut nonzero_index: usize = 0;
21664            let mut max_nonzero_index: usize = 0;
21665            let mut i: usize = 0;
21666            while i < count && i < crate::pipeline::AFFINE_MAX_COEFFS {
21667                if coefficients[i] != 0 {
21668                    nonzero_count = nonzero_count.saturating_add(1);
21669                    nonzero_index = i;
21670                    if i > max_nonzero_index { max_nonzero_index = i; }
21671                }
21672                i += 1;
21673            }
21674            let touches_tag_site = nonzero_count > 0
21675                && (max_nonzero_index as u16) >= tag_site;
21676            let is_canonical_tag_pinner = nonzero_count == 1
21677                && (nonzero_index as u16) == tag_site
21678                && coefficients[nonzero_index] == 1;
21679            if is_canonical_tag_pinner {
21680                if *bias != 0 && *bias != -1 {
21681                    return Err(GenericImpossibilityWitness::for_identity(
21682                        "https://uor.foundation/foundation/CoproductTagEncoding",
21683                    ));
21684                }
21685                if in_left_region {
21686                    *left_pins = left_pins.saturating_add(1);
21687                    if *bias != 0 { *left_bias_ok = false; }
21688                } else {
21689                    *right_pins = right_pins.saturating_add(1);
21690                    if *bias != -1 { *right_bias_ok = false; }
21691                }
21692            } else if touches_tag_site {
21693                let nonzero_only_at_tag_site = nonzero_count == 1
21694                    && (nonzero_index as u16) == tag_site;
21695                if nonzero_only_at_tag_site {
21696                    return Err(GenericImpossibilityWitness::for_identity(
21697                        "https://uor.foundation/foundation/CoproductTagEncoding",
21698                    ));
21699                } else {
21700                    return Err(GenericImpossibilityWitness::for_identity(
21701                        "https://uor.foundation/op/ST_6",
21702                    ));
21703                }
21704            }
21705        }
21706        crate::pipeline::ConstraintRef::Conjunction { conjuncts, conjunct_count } => {
21707            if max_depth == 0 {
21708                return Err(GenericImpossibilityWitness::for_identity(
21709                    "https://uor.foundation/op/ST_6",
21710                ));
21711            }
21712            let count = *conjunct_count as usize;
21713            let mut idx: usize = 0;
21714            while idx < count && idx < crate::pipeline::CONJUNCTION_MAX_TERMS {
21715                let lifted = conjuncts[idx].into_constraint();
21716                pc_classify_constraint(
21717                    &lifted,
21718                    in_left_region,
21719                    tag_site,
21720                    max_depth - 1,
21721                    left_pins,
21722                    right_pins,
21723                    left_bias_ok,
21724                    right_bias_ok,
21725                )?;
21726                idx += 1;
21727            }
21728        }
21729        crate::pipeline::ConstraintRef::Residue { .. }
21730        | crate::pipeline::ConstraintRef::Hamming { .. }
21731        | crate::pipeline::ConstraintRef::Depth { .. }
21732        | crate::pipeline::ConstraintRef::SatClauses { .. }
21733        | crate::pipeline::ConstraintRef::Bound { .. }
21734        // ADR-057: Recurse references a shape by content-addressed IRI;
21735        // no site references at this level to check.
21736        | crate::pipeline::ConstraintRef::Recurse { .. } => {
21737            // No site references at this level; nothing to check.
21738        }
21739    }
21740    Ok(())
21741}
21742
21743/// Validates ST_6 / ST_7 / ST_8 for a PartitionCoproduct construction by
21744/// walking the emitted constraint array. Recurses into
21745/// `ConstraintRef::Conjunction` conjuncts up to depth 8 (bounded by
21746/// `NERVE_CONSTRAINTS_CAP`) so nested constructions are audited without
21747/// unbounded recursion.
21748/// # Errors
21749/// Returns `GenericImpossibilityWitness::for_identity(...)` citing the
21750/// specific failed identity: `op/ST_6`, `op/ST_7`, or
21751/// `foundation/CoproductTagEncoding`. ST_8 is implied by ST_6 ∧ ST_7 and
21752/// is not cited separately on failure.
21753pub(crate) fn validate_coproduct_structure(
21754    combined_constraints: &[crate::pipeline::ConstraintRef],
21755    left_constraint_count: usize,
21756    tag_site: u16,
21757) -> Result<(), GenericImpossibilityWitness> {
21758    let mut left_pins: u32 = 0;
21759    let mut right_pins: u32 = 0;
21760    let mut left_bias_ok: bool = true;
21761    let mut right_bias_ok: bool = true;
21762    let mut idx: usize = 0;
21763    while idx < combined_constraints.len() {
21764        let in_left_region = idx < left_constraint_count;
21765        pc_classify_constraint(
21766            &combined_constraints[idx],
21767            in_left_region,
21768            tag_site,
21769            NERVE_CONSTRAINTS_CAP as u32,
21770            &mut left_pins,
21771            &mut right_pins,
21772            &mut left_bias_ok,
21773            &mut right_bias_ok,
21774        )?;
21775        idx += 1;
21776    }
21777    if left_pins != 1 || right_pins != 1 {
21778        return Err(GenericImpossibilityWitness::for_identity(
21779            "https://uor.foundation/op/ST_6",
21780        ));
21781    }
21782    if !left_bias_ok || !right_bias_ok {
21783        return Err(GenericImpossibilityWitness::for_identity(
21784            "https://uor.foundation/op/ST_7",
21785        ));
21786    }
21787    Ok(())
21788}
21789
21790/// Mint a `PartitionProductWitness` after verifying PT_1, PT_3, PT_4, and
21791/// the `ProductLayoutWidth` layout invariant. PT_2a is structural (the
21792/// witness existing is the claim); no separate check is needed once the
21793/// invariants match.
21794#[allow(clippy::too_many_arguments)]
21795pub(crate) fn pc_primitive_partition_product(
21796    witt_bits: u16,
21797    left_fingerprint: ContentFingerprint,
21798    right_fingerprint: ContentFingerprint,
21799    left_site_budget: u16,
21800    right_site_budget: u16,
21801    left_total_site_count: u16,
21802    right_total_site_count: u16,
21803    left_euler: i32,
21804    right_euler: i32,
21805    left_entropy_nats_bits: u64,
21806    right_entropy_nats_bits: u64,
21807    combined_site_budget: u16,
21808    combined_site_count: u16,
21809    combined_euler: i32,
21810    combined_entropy_nats_bits: u64,
21811    combined_fingerprint: ContentFingerprint,
21812) -> Result<PartitionProductWitness, GenericImpossibilityWitness> {
21813    let left_entropy_nats =
21814        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21815    let right_entropy_nats =
21816        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21817    let combined_entropy_nats =
21818        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21819    if combined_site_budget != left_site_budget.saturating_add(right_site_budget) {
21820        return Err(GenericImpossibilityWitness::for_identity(
21821            "https://uor.foundation/op/PT_1",
21822        ));
21823    }
21824    if combined_site_count != left_total_site_count.saturating_add(right_total_site_count) {
21825        return Err(GenericImpossibilityWitness::for_identity(
21826            "https://uor.foundation/foundation/ProductLayoutWidth",
21827        ));
21828    }
21829    if combined_euler != left_euler.saturating_add(right_euler) {
21830        return Err(GenericImpossibilityWitness::for_identity(
21831            "https://uor.foundation/op/PT_3",
21832        ));
21833    }
21834    if !pc_entropy_input_is_valid(left_entropy_nats)
21835        || !pc_entropy_input_is_valid(right_entropy_nats)
21836        || !pc_entropy_input_is_valid(combined_entropy_nats)
21837    {
21838        return Err(GenericImpossibilityWitness::for_identity(
21839            "https://uor.foundation/op/PT_4",
21840        ));
21841    }
21842    let expected_entropy = left_entropy_nats + right_entropy_nats;
21843    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21844        return Err(GenericImpossibilityWitness::for_identity(
21845            "https://uor.foundation/op/PT_4",
21846        ));
21847    }
21848    Ok(PartitionProductWitness::with_level_fingerprints_and_sites(
21849        witt_bits,
21850        combined_fingerprint,
21851        left_fingerprint,
21852        right_fingerprint,
21853        combined_site_budget,
21854        combined_site_count,
21855    ))
21856}
21857
21858/// Mint a `PartitionCoproductWitness` after verifying ST_1, ST_2, ST_6,
21859/// ST_7, ST_8, ST_9, ST_10, the `CoproductLayoutWidth` layout invariant,
21860/// the tag-site alignment against §4b', and running
21861/// `validate_coproduct_structure` over the supplied constraint array.
21862#[allow(clippy::too_many_arguments)]
21863pub(crate) fn pc_primitive_partition_coproduct(
21864    witt_bits: u16,
21865    left_fingerprint: ContentFingerprint,
21866    right_fingerprint: ContentFingerprint,
21867    left_site_budget: u16,
21868    right_site_budget: u16,
21869    left_total_site_count: u16,
21870    right_total_site_count: u16,
21871    left_euler: i32,
21872    right_euler: i32,
21873    left_entropy_nats_bits: u64,
21874    right_entropy_nats_bits: u64,
21875    left_betti: [u32; MAX_BETTI_DIMENSION],
21876    right_betti: [u32; MAX_BETTI_DIMENSION],
21877    combined_site_budget: u16,
21878    combined_site_count: u16,
21879    combined_euler: i32,
21880    combined_entropy_nats_bits: u64,
21881    combined_betti: [u32; MAX_BETTI_DIMENSION],
21882    combined_fingerprint: ContentFingerprint,
21883    combined_constraints: &[crate::pipeline::ConstraintRef],
21884    left_constraint_count: usize,
21885    tag_site: u16,
21886) -> Result<PartitionCoproductWitness, GenericImpossibilityWitness> {
21887    let left_entropy_nats =
21888        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21889    let right_entropy_nats =
21890        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21891    let combined_entropy_nats =
21892        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21893    let expected_budget = if left_site_budget > right_site_budget {
21894        left_site_budget
21895    } else {
21896        right_site_budget
21897    };
21898    if combined_site_budget != expected_budget {
21899        return Err(GenericImpossibilityWitness::for_identity(
21900            "https://uor.foundation/op/ST_1",
21901        ));
21902    }
21903    let max_total = if left_total_site_count > right_total_site_count {
21904        left_total_site_count
21905    } else {
21906        right_total_site_count
21907    };
21908    let expected_total = max_total.saturating_add(1);
21909    if combined_site_count != expected_total {
21910        return Err(GenericImpossibilityWitness::for_identity(
21911            "https://uor.foundation/foundation/CoproductLayoutWidth",
21912        ));
21913    }
21914    if !pc_entropy_input_is_valid(left_entropy_nats)
21915        || !pc_entropy_input_is_valid(right_entropy_nats)
21916        || !pc_entropy_input_is_valid(combined_entropy_nats)
21917    {
21918        return Err(GenericImpossibilityWitness::for_identity(
21919            "https://uor.foundation/op/ST_2",
21920        ));
21921    }
21922    let max_operand_entropy = if left_entropy_nats > right_entropy_nats {
21923        left_entropy_nats
21924    } else {
21925        right_entropy_nats
21926    };
21927    let expected_entropy = core::f64::consts::LN_2 + max_operand_entropy;
21928    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
21929        return Err(GenericImpossibilityWitness::for_identity(
21930            "https://uor.foundation/op/ST_2",
21931        ));
21932    }
21933    if tag_site != max_total {
21934        return Err(GenericImpossibilityWitness::for_identity(
21935            "https://uor.foundation/foundation/CoproductLayoutWidth",
21936        ));
21937    }
21938    validate_coproduct_structure(combined_constraints, left_constraint_count, tag_site)?;
21939    if combined_euler != left_euler.saturating_add(right_euler) {
21940        return Err(GenericImpossibilityWitness::for_identity(
21941            "https://uor.foundation/op/ST_9",
21942        ));
21943    }
21944    let mut k: usize = 0;
21945    while k < MAX_BETTI_DIMENSION {
21946        if combined_betti[k] != left_betti[k].saturating_add(right_betti[k]) {
21947            return Err(GenericImpossibilityWitness::for_identity(
21948                "https://uor.foundation/op/ST_10",
21949            ));
21950        }
21951        k += 1;
21952    }
21953    Ok(
21954        PartitionCoproductWitness::with_level_fingerprints_sites_and_tag(
21955            witt_bits,
21956            combined_fingerprint,
21957            left_fingerprint,
21958            right_fingerprint,
21959            combined_site_budget,
21960            combined_site_count,
21961            max_total,
21962        ),
21963    )
21964}
21965
21966/// Mint a `CartesianProductWitness` after verifying CPT_1, CPT_3, CPT_4,
21967/// CPT_5, and the `CartesianLayoutWidth` layout invariant. Checks
21968/// caller-supplied Künneth-composed invariants against the component
21969/// values (the witness defines these axiomatically per §3c).
21970#[allow(clippy::too_many_arguments)]
21971pub(crate) fn pc_primitive_cartesian_product(
21972    witt_bits: u16,
21973    left_fingerprint: ContentFingerprint,
21974    right_fingerprint: ContentFingerprint,
21975    left_site_budget: u16,
21976    right_site_budget: u16,
21977    left_total_site_count: u16,
21978    right_total_site_count: u16,
21979    left_euler: i32,
21980    right_euler: i32,
21981    left_betti: [u32; MAX_BETTI_DIMENSION],
21982    right_betti: [u32; MAX_BETTI_DIMENSION],
21983    left_entropy_nats_bits: u64,
21984    right_entropy_nats_bits: u64,
21985    combined_site_budget: u16,
21986    combined_site_count: u16,
21987    combined_euler: i32,
21988    combined_betti: [u32; MAX_BETTI_DIMENSION],
21989    combined_entropy_nats_bits: u64,
21990    combined_fingerprint: ContentFingerprint,
21991) -> Result<CartesianProductWitness, GenericImpossibilityWitness> {
21992    let left_entropy_nats =
21993        <f64 as crate::DecimalTranscendental>::from_bits(left_entropy_nats_bits);
21994    let right_entropy_nats =
21995        <f64 as crate::DecimalTranscendental>::from_bits(right_entropy_nats_bits);
21996    let combined_entropy_nats =
21997        <f64 as crate::DecimalTranscendental>::from_bits(combined_entropy_nats_bits);
21998    if combined_site_budget != left_site_budget.saturating_add(right_site_budget) {
21999        return Err(GenericImpossibilityWitness::for_identity(
22000            "https://uor.foundation/op/CPT_1",
22001        ));
22002    }
22003    if combined_site_count != left_total_site_count.saturating_add(right_total_site_count) {
22004        return Err(GenericImpossibilityWitness::for_identity(
22005            "https://uor.foundation/foundation/CartesianLayoutWidth",
22006        ));
22007    }
22008    if combined_euler != left_euler.saturating_mul(right_euler) {
22009        return Err(GenericImpossibilityWitness::for_identity(
22010            "https://uor.foundation/op/CPT_3",
22011        ));
22012    }
22013    let kunneth = crate::pipeline::kunneth_compose(&left_betti, &right_betti);
22014    let mut k: usize = 0;
22015    while k < MAX_BETTI_DIMENSION {
22016        if combined_betti[k] != kunneth[k] {
22017            return Err(GenericImpossibilityWitness::for_identity(
22018                "https://uor.foundation/op/CPT_4",
22019            ));
22020        }
22021        k += 1;
22022    }
22023    if !pc_entropy_input_is_valid(left_entropy_nats)
22024        || !pc_entropy_input_is_valid(right_entropy_nats)
22025        || !pc_entropy_input_is_valid(combined_entropy_nats)
22026    {
22027        return Err(GenericImpossibilityWitness::for_identity(
22028            "https://uor.foundation/op/CPT_5",
22029        ));
22030    }
22031    let expected_entropy = left_entropy_nats + right_entropy_nats;
22032    if !pc_entropy_additivity_holds(combined_entropy_nats, expected_entropy) {
22033        return Err(GenericImpossibilityWitness::for_identity(
22034            "https://uor.foundation/op/CPT_5",
22035        ));
22036    }
22037    Ok(
22038        CartesianProductWitness::with_level_fingerprints_and_invariants(
22039            witt_bits,
22040            combined_fingerprint,
22041            left_fingerprint,
22042            right_fingerprint,
22043            combined_site_budget,
22044            combined_site_count,
22045            combined_euler,
22046            combined_betti,
22047        ),
22048    )
22049}
22050
22051impl VerifiedMint for PartitionProductWitness {
22052    type Inputs = PartitionProductMintInputs;
22053    type Error = GenericImpossibilityWitness;
22054    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
22055        pc_primitive_partition_product(
22056            inputs.witt_bits,
22057            inputs.left_fingerprint,
22058            inputs.right_fingerprint,
22059            inputs.left_site_budget,
22060            inputs.right_site_budget,
22061            inputs.left_total_site_count,
22062            inputs.right_total_site_count,
22063            inputs.left_euler,
22064            inputs.right_euler,
22065            inputs.left_entropy_nats_bits,
22066            inputs.right_entropy_nats_bits,
22067            inputs.combined_site_budget,
22068            inputs.combined_site_count,
22069            inputs.combined_euler,
22070            inputs.combined_entropy_nats_bits,
22071            inputs.combined_fingerprint,
22072        )
22073    }
22074}
22075
22076impl VerifiedMint for PartitionCoproductWitness {
22077    type Inputs = PartitionCoproductMintInputs;
22078    type Error = GenericImpossibilityWitness;
22079    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
22080        pc_primitive_partition_coproduct(
22081            inputs.witt_bits,
22082            inputs.left_fingerprint,
22083            inputs.right_fingerprint,
22084            inputs.left_site_budget,
22085            inputs.right_site_budget,
22086            inputs.left_total_site_count,
22087            inputs.right_total_site_count,
22088            inputs.left_euler,
22089            inputs.right_euler,
22090            inputs.left_entropy_nats_bits,
22091            inputs.right_entropy_nats_bits,
22092            inputs.left_betti,
22093            inputs.right_betti,
22094            inputs.combined_site_budget,
22095            inputs.combined_site_count,
22096            inputs.combined_euler,
22097            inputs.combined_entropy_nats_bits,
22098            inputs.combined_betti,
22099            inputs.combined_fingerprint,
22100            inputs.combined_constraints,
22101            inputs.left_constraint_count,
22102            inputs.tag_site,
22103        )
22104    }
22105}
22106
22107impl VerifiedMint for CartesianProductWitness {
22108    type Inputs = CartesianProductMintInputs;
22109    type Error = GenericImpossibilityWitness;
22110    fn mint_verified(inputs: Self::Inputs) -> Result<Self, Self::Error> {
22111        pc_primitive_cartesian_product(
22112            inputs.witt_bits,
22113            inputs.left_fingerprint,
22114            inputs.right_fingerprint,
22115            inputs.left_site_budget,
22116            inputs.right_site_budget,
22117            inputs.left_total_site_count,
22118            inputs.right_total_site_count,
22119            inputs.left_euler,
22120            inputs.right_euler,
22121            inputs.left_betti,
22122            inputs.right_betti,
22123            inputs.left_entropy_nats_bits,
22124            inputs.right_entropy_nats_bits,
22125            inputs.combined_site_budget,
22126            inputs.combined_site_count,
22127            inputs.combined_euler,
22128            inputs.combined_betti,
22129            inputs.combined_entropy_nats_bits,
22130            inputs.combined_fingerprint,
22131        )
22132    }
22133}
22134
22135/// Data record of a partition's runtime-queried properties. Produced at
22136/// witness-mint time and consulted by consumer code that holds a
22137/// `PartitionHandle` and a `PartitionResolver`. Phase 9 stores entropy
22138/// as the IEEE-754 `u64` bit-pattern (`entropy_nats_bits`) so the record
22139/// derives `Eq + Hash` cleanly; consumers project to `H::Decimal` via
22140/// `<H::Decimal as DecimalTranscendental>::from_bits`.
22141#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22142pub struct PartitionRecord<H: crate::HostTypes> {
22143    /// Data sites only — the partition's `siteBudget`, not its layout width.
22144    pub site_budget: u16,
22145    /// Euler characteristic of the partition's nerve.
22146    pub euler: i32,
22147    /// Betti profile of the partition's nerve, padded to `MAX_BETTI_DIMENSION`.
22148    pub betti: [u32; MAX_BETTI_DIMENSION],
22149    /// Shannon entropy in nats (matches `LandauerBudget::nats()` convention).
22150    pub entropy_nats_bits: u64,
22151    _phantom: core::marker::PhantomData<H>,
22152}
22153
22154impl<H: crate::HostTypes> PartitionRecord<H> {
22155    /// Construct a new record. The phantom marker ensures records are
22156    /// parameterized by the host types they originate from.
22157    #[inline]
22158    #[must_use]
22159    pub const fn new(
22160        site_budget: u16,
22161        euler: i32,
22162        betti: [u32; MAX_BETTI_DIMENSION],
22163        entropy_nats_bits: u64,
22164    ) -> Self {
22165        Self {
22166            site_budget,
22167            euler,
22168            betti,
22169            entropy_nats_bits,
22170            _phantom: core::marker::PhantomData,
22171        }
22172    }
22173}
22174
22175/// Resolver mapping content fingerprints to `PartitionRecord`s. Provided
22176/// by the host application — typically a persistent store, an in-memory
22177/// registry populated from witness mint-time data, or a chain-of-witnesses
22178/// trail that can reconstruct properties.
22179pub trait PartitionResolver<H: crate::HostTypes> {
22180    /// Look up partition data by fingerprint. Returns `None` if the
22181    /// resolver has no record for the handle. Handles remain valid as
22182    /// identity tokens regardless of resolver presence.
22183    fn resolve(&self, fp: ContentFingerprint) -> Option<PartitionRecord<H>>;
22184}
22185
22186/// Content-addressed identity token for a partition. Carries only a
22187/// fingerprint; partition data is recovered by pairing the handle with a
22188/// `PartitionResolver` via `resolve_with`. Handles compare and hash by
22189/// fingerprint, so they can serve as keys in content-addressed indices
22190/// without resolver access.
22191#[derive(Debug)]
22192pub struct PartitionHandle<H: crate::HostTypes> {
22193    fingerprint: ContentFingerprint,
22194    _phantom: core::marker::PhantomData<H>,
22195}
22196impl<H: crate::HostTypes> Copy for PartitionHandle<H> {}
22197impl<H: crate::HostTypes> Clone for PartitionHandle<H> {
22198    #[inline]
22199    fn clone(&self) -> Self {
22200        *self
22201    }
22202}
22203impl<H: crate::HostTypes> PartialEq for PartitionHandle<H> {
22204    #[inline]
22205    fn eq(&self, other: &Self) -> bool {
22206        self.fingerprint == other.fingerprint
22207    }
22208}
22209impl<H: crate::HostTypes> Eq for PartitionHandle<H> {}
22210impl<H: crate::HostTypes> core::hash::Hash for PartitionHandle<H> {
22211    #[inline]
22212    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
22213        self.fingerprint.hash(state);
22214    }
22215}
22216
22217impl<H: crate::HostTypes> PartitionHandle<H> {
22218    /// Construct a handle from a content fingerprint.
22219    #[inline]
22220    #[must_use]
22221    pub const fn from_fingerprint(fingerprint: ContentFingerprint) -> Self {
22222        Self {
22223            fingerprint,
22224            _phantom: core::marker::PhantomData,
22225        }
22226    }
22227    /// Return the content fingerprint this handle references.
22228    #[inline]
22229    #[must_use]
22230    pub const fn fingerprint(&self) -> ContentFingerprint {
22231        self.fingerprint
22232    }
22233    /// Resolve this handle against a consumer-supplied resolver.
22234    /// Returns `None` if the resolver has no record for this fingerprint.
22235    #[inline]
22236    pub fn resolve_with<R: PartitionResolver<H>>(
22237        &self,
22238        resolver: &R,
22239    ) -> Option<PartitionRecord<H>> {
22240        resolver.resolve(self.fingerprint)
22241    }
22242}
22243
22244/// Resolver-absent default `Element<H>`. Returns empty defaults via the
22245/// `HostTypes::EMPTY_*` constants — used by `NullDatum<H>` and
22246/// `NullTypeDefinition<H>` to satisfy their `Element` associated types.
22247#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22248pub struct NullElement<H: HostTypes> {
22249    _phantom: core::marker::PhantomData<H>,
22250}
22251impl<H: HostTypes> Default for NullElement<H> {
22252    fn default() -> Self {
22253        Self {
22254            _phantom: core::marker::PhantomData,
22255        }
22256    }
22257}
22258impl<H: HostTypes> crate::kernel::address::Element<H> for NullElement<H> {
22259    fn length(&self) -> u64 {
22260        0
22261    }
22262    fn addresses(&self) -> &H::HostString {
22263        H::EMPTY_HOST_STRING
22264    }
22265    fn digest(&self) -> &H::HostString {
22266        H::EMPTY_HOST_STRING
22267    }
22268    fn digest_algorithm(&self) -> &H::HostString {
22269        H::EMPTY_HOST_STRING
22270    }
22271    fn canonical_bytes(&self) -> &H::WitnessBytes {
22272        H::EMPTY_WITNESS_BYTES
22273    }
22274    fn witt_length(&self) -> u64 {
22275        0
22276    }
22277}
22278
22279/// Resolver-absent default `Datum<H>`. All numeric methods return 0.
22280#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22281pub struct NullDatum<H: HostTypes> {
22282    element: NullElement<H>,
22283    _phantom: core::marker::PhantomData<H>,
22284}
22285impl<H: HostTypes> Default for NullDatum<H> {
22286    fn default() -> Self {
22287        Self {
22288            element: NullElement::default(),
22289            _phantom: core::marker::PhantomData,
22290        }
22291    }
22292}
22293impl<H: HostTypes> crate::kernel::schema::Datum<H> for NullDatum<H> {
22294    fn value(&self) -> u64 {
22295        0
22296    }
22297    fn witt_length(&self) -> u64 {
22298        0
22299    }
22300    fn stratum(&self) -> u64 {
22301        0
22302    }
22303    fn spectrum(&self) -> u64 {
22304        0
22305    }
22306    type Element = NullElement<H>;
22307    fn element(&self) -> &Self::Element {
22308        &self.element
22309    }
22310}
22311
22312/// Resolver-absent default `TermExpression<H>`. Empty marker trait, no methods.
22313#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22314pub struct NullTermExpression<H: HostTypes> {
22315    _phantom: core::marker::PhantomData<H>,
22316}
22317impl<H: HostTypes> Default for NullTermExpression<H> {
22318    fn default() -> Self {
22319        Self {
22320            _phantom: core::marker::PhantomData,
22321        }
22322    }
22323}
22324impl<H: HostTypes> crate::kernel::schema::TermExpression<H> for NullTermExpression<H> {}
22325
22326/// Resolver-absent default `SiteIndex<H>`. Self-recursive: `ancilla_site()`
22327/// returns `&self` (no ancilla pairing in the default).
22328#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22329pub struct NullSiteIndex<H: HostTypes> {
22330    _phantom: core::marker::PhantomData<H>,
22331}
22332impl<H: HostTypes> Default for NullSiteIndex<H> {
22333    fn default() -> Self {
22334        Self {
22335            _phantom: core::marker::PhantomData,
22336        }
22337    }
22338}
22339impl<H: HostTypes> crate::bridge::partition::SiteIndex<H> for NullSiteIndex<H> {
22340    fn site_position(&self) -> u64 {
22341        0
22342    }
22343    fn site_state(&self) -> u64 {
22344        0
22345    }
22346    type SiteIndexTarget = NullSiteIndex<H>;
22347    fn ancilla_site(&self) -> &Self::SiteIndexTarget {
22348        self
22349    }
22350}
22351
22352/// Resolver-absent default `TagSite<H>`. Embeds an inline `NullSiteIndex`
22353/// field so the inherited `ancilla_site()` accessor returns a valid
22354/// reference; `tag_value()` returns false.
22355#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22356pub struct NullTagSite<H: HostTypes> {
22357    ancilla: NullSiteIndex<H>,
22358}
22359impl<H: HostTypes> Default for NullTagSite<H> {
22360    fn default() -> Self {
22361        Self {
22362            ancilla: NullSiteIndex::default(),
22363        }
22364    }
22365}
22366impl<H: HostTypes> crate::bridge::partition::SiteIndex<H> for NullTagSite<H> {
22367    fn site_position(&self) -> u64 {
22368        0
22369    }
22370    fn site_state(&self) -> u64 {
22371        0
22372    }
22373    type SiteIndexTarget = NullSiteIndex<H>;
22374    fn ancilla_site(&self) -> &Self::SiteIndexTarget {
22375        &self.ancilla
22376    }
22377}
22378impl<H: HostTypes> crate::bridge::partition::TagSite<H> for NullTagSite<H> {
22379    fn tag_value(&self) -> bool {
22380        false
22381    }
22382}
22383
22384/// Resolver-absent default `SiteBinding<H>`. Embeds inline `NullConstraint`
22385/// and `NullSiteIndex` so the trait's reference accessors work via &self.field.
22386#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22387pub struct NullSiteBinding<H: HostTypes> {
22388    constraint: NullConstraint<H>,
22389    site_index: NullSiteIndex<H>,
22390}
22391impl<H: HostTypes> Default for NullSiteBinding<H> {
22392    fn default() -> Self {
22393        Self {
22394            constraint: NullConstraint::default(),
22395            site_index: NullSiteIndex::default(),
22396        }
22397    }
22398}
22399impl<H: HostTypes> crate::bridge::partition::SiteBinding<H> for NullSiteBinding<H> {
22400    type Constraint = NullConstraint<H>;
22401    fn pinned_by(&self) -> &Self::Constraint {
22402        &self.constraint
22403    }
22404    type SiteIndex = NullSiteIndex<H>;
22405    fn pins_coordinate(&self) -> &Self::SiteIndex {
22406        &self.site_index
22407    }
22408}
22409
22410/// Resolver-absent default `Constraint<H>`. Returns Vertical metric axis,
22411/// empty pinned-sites slice, and zero crossing cost.
22412#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22413pub struct NullConstraint<H: HostTypes> {
22414    _phantom: core::marker::PhantomData<H>,
22415}
22416impl<H: HostTypes> Default for NullConstraint<H> {
22417    fn default() -> Self {
22418        Self {
22419            _phantom: core::marker::PhantomData,
22420        }
22421    }
22422}
22423impl<H: HostTypes> crate::user::type_::Constraint<H> for NullConstraint<H> {
22424    fn metric_axis(&self) -> MetricAxis {
22425        MetricAxis::Vertical
22426    }
22427    type SiteIndex = NullSiteIndex<H>;
22428    fn pins_sites(&self) -> &[Self::SiteIndex] {
22429        &[]
22430    }
22431    fn crossing_cost(&self) -> u64 {
22432        0
22433    }
22434}
22435
22436/// Resolver-absent default `FreeRank<H>`. Empty budget — `is_closed()` true,
22437/// zero counts. Empty `has_site` / `has_binding` slices.
22438#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22439pub struct NullFreeRank<H: HostTypes> {
22440    _phantom: core::marker::PhantomData<H>,
22441}
22442impl<H: HostTypes> Default for NullFreeRank<H> {
22443    fn default() -> Self {
22444        Self {
22445            _phantom: core::marker::PhantomData,
22446        }
22447    }
22448}
22449impl<H: HostTypes> crate::bridge::partition::FreeRank<H> for NullFreeRank<H> {
22450    fn total_sites(&self) -> u64 {
22451        0
22452    }
22453    fn pinned_count(&self) -> u64 {
22454        0
22455    }
22456    fn free_rank(&self) -> u64 {
22457        0
22458    }
22459    fn is_closed(&self) -> bool {
22460        true
22461    }
22462    type SiteIndex = NullSiteIndex<H>;
22463    fn has_site(&self) -> &[Self::SiteIndex] {
22464        &[]
22465    }
22466    type SiteBinding = NullSiteBinding<H>;
22467    fn has_binding(&self) -> &[Self::SiteBinding] {
22468        &[]
22469    }
22470    fn reversible_strategy(&self) -> bool {
22471        false
22472    }
22473}
22474
22475/// Resolver-absent default `IrreducibleSet<H>`. Implements `Component<H>` with empty
22476/// `member` slice and zero `cardinality`.
22477#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22478pub struct NullIrreducibleSet<H: HostTypes> {
22479    _phantom: core::marker::PhantomData<H>,
22480}
22481impl<H: HostTypes> Default for NullIrreducibleSet<H> {
22482    fn default() -> Self {
22483        Self {
22484            _phantom: core::marker::PhantomData,
22485        }
22486    }
22487}
22488impl<H: HostTypes> crate::bridge::partition::Component<H> for NullIrreducibleSet<H> {
22489    type Datum = NullDatum<H>;
22490    fn member(&self) -> &[Self::Datum] {
22491        &[]
22492    }
22493    fn cardinality(&self) -> u64 {
22494        0
22495    }
22496}
22497impl<H: HostTypes> crate::bridge::partition::IrreducibleSet<H> for NullIrreducibleSet<H> {}
22498
22499/// Resolver-absent default `ReducibleSet<H>`. Implements `Component<H>` with empty
22500/// `member` slice and zero `cardinality`.
22501#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22502pub struct NullReducibleSet<H: HostTypes> {
22503    _phantom: core::marker::PhantomData<H>,
22504}
22505impl<H: HostTypes> Default for NullReducibleSet<H> {
22506    fn default() -> Self {
22507        Self {
22508            _phantom: core::marker::PhantomData,
22509        }
22510    }
22511}
22512impl<H: HostTypes> crate::bridge::partition::Component<H> for NullReducibleSet<H> {
22513    type Datum = NullDatum<H>;
22514    fn member(&self) -> &[Self::Datum] {
22515        &[]
22516    }
22517    fn cardinality(&self) -> u64 {
22518        0
22519    }
22520}
22521impl<H: HostTypes> crate::bridge::partition::ReducibleSet<H> for NullReducibleSet<H> {}
22522
22523/// Resolver-absent default `UnitGroup<H>`. Implements `Component<H>` with empty
22524/// `member` slice and zero `cardinality`.
22525#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22526pub struct NullUnitGroup<H: HostTypes> {
22527    _phantom: core::marker::PhantomData<H>,
22528}
22529impl<H: HostTypes> Default for NullUnitGroup<H> {
22530    fn default() -> Self {
22531        Self {
22532            _phantom: core::marker::PhantomData,
22533        }
22534    }
22535}
22536impl<H: HostTypes> crate::bridge::partition::Component<H> for NullUnitGroup<H> {
22537    type Datum = NullDatum<H>;
22538    fn member(&self) -> &[Self::Datum] {
22539        &[]
22540    }
22541    fn cardinality(&self) -> u64 {
22542        0
22543    }
22544}
22545impl<H: HostTypes> crate::bridge::partition::UnitGroup<H> for NullUnitGroup<H> {}
22546
22547/// Resolver-absent default `Complement<H>`. Implements `Component<H>` plus
22548/// the `exterior_criteria()` accessor returning a reference to an embedded
22549/// `NullTermExpression`.
22550#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22551pub struct NullComplement<H: HostTypes> {
22552    term: NullTermExpression<H>,
22553}
22554impl<H: HostTypes> Default for NullComplement<H> {
22555    fn default() -> Self {
22556        Self {
22557            term: NullTermExpression::default(),
22558        }
22559    }
22560}
22561impl<H: HostTypes> crate::bridge::partition::Component<H> for NullComplement<H> {
22562    type Datum = NullDatum<H>;
22563    fn member(&self) -> &[Self::Datum] {
22564        &[]
22565    }
22566    fn cardinality(&self) -> u64 {
22567        0
22568    }
22569}
22570impl<H: HostTypes> crate::bridge::partition::Complement<H> for NullComplement<H> {
22571    type TermExpression = NullTermExpression<H>;
22572    fn exterior_criteria(&self) -> &Self::TermExpression {
22573        &self.term
22574    }
22575}
22576
22577/// Resolver-absent default `TypeDefinition<H>`. Embeds inline `NullElement`
22578/// for the content_address accessor.
22579#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22580pub struct NullTypeDefinition<H: HostTypes> {
22581    element: NullElement<H>,
22582}
22583impl<H: HostTypes> Default for NullTypeDefinition<H> {
22584    fn default() -> Self {
22585        Self {
22586            element: NullElement::default(),
22587        }
22588    }
22589}
22590impl<H: HostTypes> crate::user::type_::TypeDefinition<H> for NullTypeDefinition<H> {
22591    type Element = NullElement<H>;
22592    fn content_address(&self) -> &Self::Element {
22593        &self.element
22594    }
22595}
22596
22597/// Resolver-absent default `Partition<H>`. Embeds inline stubs for every
22598/// sub-trait associated type so `Partition<H>` accessors return references
22599/// to fields rather than to statics. The only meaningful state is the
22600/// `fingerprint`; everything else uses `HostTypes::EMPTY_*` defaults.
22601/// Returned by the three witness trait impls' `left_factor` / `right_factor`
22602/// / `left_summand` / etc. accessors as the resolver-absent value pathway.
22603/// Consumers needing real partition data pair the sibling `PartitionHandle`
22604/// with a `PartitionResolver` instead.
22605#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22606pub struct NullPartition<H: HostTypes> {
22607    irreducibles: NullIrreducibleSet<H>,
22608    reducibles: NullReducibleSet<H>,
22609    units: NullUnitGroup<H>,
22610    exterior: NullComplement<H>,
22611    free_rank: NullFreeRank<H>,
22612    tag_site: NullTagSite<H>,
22613    source_type: NullTypeDefinition<H>,
22614    fingerprint: ContentFingerprint,
22615}
22616
22617impl<H: HostTypes> NullPartition<H> {
22618    /// Construct a NullPartition with the given content fingerprint.
22619    /// All other fields are resolver-absent defaults.
22620    #[inline]
22621    #[must_use]
22622    pub fn from_fingerprint(fingerprint: ContentFingerprint) -> Self {
22623        Self {
22624            irreducibles: NullIrreducibleSet::default(),
22625            reducibles: NullReducibleSet::default(),
22626            units: NullUnitGroup::default(),
22627            exterior: NullComplement::default(),
22628            free_rank: NullFreeRank::default(),
22629            tag_site: NullTagSite::default(),
22630            source_type: NullTypeDefinition::default(),
22631            fingerprint,
22632        }
22633    }
22634    /// Returns the content fingerprint identifying which Partition this stub stands in for.
22635    #[inline]
22636    #[must_use]
22637    pub const fn fingerprint(&self) -> ContentFingerprint {
22638        self.fingerprint
22639    }
22640    /// Phase 2 (orphan-closure): absent-value sentinel used by Null stubs
22641    /// in other namespaces to satisfy `&Self::Partition` return borrows.
22642    pub const ABSENT: NullPartition<H> = NullPartition {
22643        irreducibles: NullIrreducibleSet {
22644            _phantom: core::marker::PhantomData,
22645        },
22646        reducibles: NullReducibleSet {
22647            _phantom: core::marker::PhantomData,
22648        },
22649        units: NullUnitGroup {
22650            _phantom: core::marker::PhantomData,
22651        },
22652        exterior: NullComplement {
22653            term: NullTermExpression {
22654                _phantom: core::marker::PhantomData,
22655            },
22656        },
22657        free_rank: NullFreeRank {
22658            _phantom: core::marker::PhantomData,
22659        },
22660        tag_site: NullTagSite {
22661            ancilla: NullSiteIndex {
22662                _phantom: core::marker::PhantomData,
22663            },
22664        },
22665        source_type: NullTypeDefinition {
22666            element: NullElement {
22667                _phantom: core::marker::PhantomData,
22668            },
22669        },
22670        fingerprint: ContentFingerprint::zero(),
22671    };
22672}
22673
22674impl<H: HostTypes> crate::bridge::partition::Partition<H> for NullPartition<H> {
22675    type IrreducibleSet = NullIrreducibleSet<H>;
22676    fn irreducibles(&self) -> &Self::IrreducibleSet {
22677        &self.irreducibles
22678    }
22679    type ReducibleSet = NullReducibleSet<H>;
22680    fn reducibles(&self) -> &Self::ReducibleSet {
22681        &self.reducibles
22682    }
22683    type UnitGroup = NullUnitGroup<H>;
22684    fn units(&self) -> &Self::UnitGroup {
22685        &self.units
22686    }
22687    type Complement = NullComplement<H>;
22688    fn exterior(&self) -> &Self::Complement {
22689        &self.exterior
22690    }
22691    fn density(&self) -> H::Decimal {
22692        H::EMPTY_DECIMAL
22693    }
22694    type TypeDefinition = NullTypeDefinition<H>;
22695    fn source_type(&self) -> &Self::TypeDefinition {
22696        &self.source_type
22697    }
22698    fn witt_length(&self) -> u64 {
22699        0
22700    }
22701    type FreeRank = NullFreeRank<H>;
22702    fn site_budget(&self) -> &Self::FreeRank {
22703        &self.free_rank
22704    }
22705    fn is_exhaustive(&self) -> bool {
22706        true
22707    }
22708    type TagSite = NullTagSite<H>;
22709    fn tag_site_of(&self) -> &Self::TagSite {
22710        &self.tag_site
22711    }
22712    fn product_category_level(&self) -> &H::HostString {
22713        H::EMPTY_HOST_STRING
22714    }
22715}
22716
22717impl<H: HostTypes> crate::bridge::partition::PartitionProduct<H> for PartitionProductWitness {
22718    type Partition = NullPartition<H>;
22719    fn left_factor(&self) -> Self::Partition {
22720        NullPartition::from_fingerprint(self.left_fingerprint)
22721    }
22722    fn right_factor(&self) -> Self::Partition {
22723        NullPartition::from_fingerprint(self.right_fingerprint)
22724    }
22725}
22726
22727impl<H: HostTypes> crate::bridge::partition::PartitionCoproduct<H> for PartitionCoproductWitness {
22728    type Partition = NullPartition<H>;
22729    fn left_summand(&self) -> Self::Partition {
22730        NullPartition::from_fingerprint(self.left_fingerprint)
22731    }
22732    fn right_summand(&self) -> Self::Partition {
22733        NullPartition::from_fingerprint(self.right_fingerprint)
22734    }
22735}
22736
22737impl<H: HostTypes> crate::bridge::partition::CartesianPartitionProduct<H>
22738    for CartesianProductWitness
22739{
22740    type Partition = NullPartition<H>;
22741    fn left_cartesian_factor(&self) -> Self::Partition {
22742        NullPartition::from_fingerprint(self.left_fingerprint)
22743    }
22744    fn right_cartesian_factor(&self) -> Self::Partition {
22745        NullPartition::from_fingerprint(self.right_fingerprint)
22746    }
22747}
22748
22749/// v0.2.1 ergonomics prelude. Re-exports the core symbols downstream crates
22750/// need for the consumer-facing one-liners.
22751/// Ontology-driven: the set of certificate / type / builder symbols is
22752/// sourced from `conformance:PreludeExport` individuals. Adding a new
22753/// symbol to the prelude is an ontology edit, verified against the
22754/// codegen's known-name mapping at build time.
22755pub mod prelude {
22756    pub use super::calibrations;
22757    pub use super::Add;
22758    pub use super::And;
22759    pub use super::BNot;
22760    pub use super::BinaryGroundingMap;
22761    pub use super::BindingEntry;
22762    pub use super::BindingsTable;
22763    pub use super::BornRuleVerification;
22764    pub use super::Calibration;
22765    pub use super::CalibrationError;
22766    pub use super::CanonicalTimingPolicy;
22767    pub use super::Certificate;
22768    pub use super::Certified;
22769    pub use super::ChainAuditTrail;
22770    pub use super::CompileTime;
22771    pub use super::CompileUnit;
22772    pub use super::CompileUnitBuilder;
22773    pub use super::CompletenessAuditTrail;
22774    pub use super::CompletenessCertificate;
22775    pub use super::ConstrainedTypeInput;
22776    pub use super::ContentAddress;
22777    pub use super::ContentFingerprint;
22778    pub use super::Datum;
22779    pub use super::DigestGroundingMap;
22780    pub use super::Embed;
22781    pub use super::FragmentMarker;
22782    pub use super::GenericImpossibilityWitness;
22783    pub use super::GeodesicCertificate;
22784    pub use super::GeodesicEvidenceBundle;
22785    pub use super::Grounded;
22786    pub use super::GroundedCoord;
22787    pub use super::GroundedShape;
22788    pub use super::GroundedTuple;
22789    pub use super::GroundedValue;
22790    pub use super::Grounding;
22791    pub use super::GroundingCertificate;
22792    pub use super::GroundingExt;
22793    pub use super::GroundingMapKind;
22794    pub use super::GroundingProgram;
22795    pub use super::Hasher;
22796    pub use super::ImpossibilityWitnessKind;
22797    pub use super::InhabitanceCertificate;
22798    pub use super::InhabitanceImpossibilityWitness;
22799    pub use super::IntegerGroundingMap;
22800    pub use super::Invertible;
22801    pub use super::InvolutionCertificate;
22802    pub use super::IsometryCertificate;
22803    pub use super::JsonGroundingMap;
22804    pub use super::LandauerBudget;
22805    pub use super::LiftChainCertificate;
22806    pub use super::MeasurementCertificate;
22807    pub use super::Mul;
22808    pub use super::Nanos;
22809    pub use super::Neg;
22810    pub use super::OntologyTarget;
22811    pub use super::Or;
22812    pub use super::PipelineFailure;
22813    pub use super::PreservesMetric;
22814    pub use super::PreservesStructure;
22815    pub use super::RingOp;
22816    pub use super::Runtime;
22817    pub use super::ShapeViolation;
22818    pub use super::Sub;
22819    pub use super::Succ;
22820    pub use super::Term;
22821    pub use super::TermArena;
22822    pub use super::TimingPolicy;
22823    pub use super::Total;
22824    pub use super::TransformCertificate;
22825    pub use super::Triad;
22826    pub use super::UnaryRingOp;
22827    pub use super::UorTime;
22828    pub use super::Utf8GroundingMap;
22829    pub use super::ValidLevelEmbedding;
22830    pub use super::Validated;
22831    pub use super::ValidationPhase;
22832    pub use super::Xor;
22833    pub use super::W16;
22834    pub use super::W8;
22835    pub use crate::pipeline::empty_bindings_table;
22836    pub use crate::pipeline::{
22837        validate_constrained_type, validate_constrained_type_const, ConstrainedTypeShape,
22838        ConstraintRef, FragmentKind,
22839    };
22840    pub use crate::{DecimalTranscendental, DefaultHostTypes, HostTypes, WittLevel};
22841}